@praxisui/dynamic-form 10.0.0-rc.34 → 10.0.0-rc.35
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.
|
@@ -20,7 +20,7 @@ import * as i9 from '@angular/material/snack-bar';
|
|
|
20
20
|
import { MatSnackBarModule } from '@angular/material/snack-bar';
|
|
21
21
|
import * as i19 from '@angular/material/badge';
|
|
22
22
|
import { MatBadgeModule } from '@angular/material/badge';
|
|
23
|
-
import { map, Subscription, merge, of, timer, NEVER, EMPTY, defer, TimeoutError, Subject, firstValueFrom, BehaviorSubject, throwError, combineLatest, Observable, race, from, debounceTime as debounceTime$1, takeUntil as takeUntil$1, defaultIfEmpty, switchMap as switchMap$1, catchError as catchError$1, take as take$1, finalize as finalize$1 } from 'rxjs';
|
|
23
|
+
import { map, Subscription, merge, of, timer, NEVER, EMPTY, defer, TimeoutError, Subject, firstValueFrom, BehaviorSubject, throwError, combineLatest, forkJoin, Observable, race, from, debounceTime as debounceTime$1, takeUntil as takeUntil$1, defaultIfEmpty, switchMap as switchMap$1, catchError as catchError$1, take as take$1, finalize as finalize$1 } from 'rxjs';
|
|
24
24
|
import { filter, map as map$1, switchMap, take, timeout, throwIfEmpty, tap, catchError, ignoreElements, finalize, takeUntil, skip, debounceTime, startWith } from 'rxjs/operators';
|
|
25
25
|
import * as i1 from '@praxisui/core';
|
|
26
26
|
import { serializeEntityLookupValueForPayload, PraxisI18nService, PraxisIconButtonComponent, PraxisIconDirective, providePraxisI18nConfig, RULE_PROPERTY_SCHEMA, FIELD_METADATA_CAPABILITIES, migrateFormLayoutRule, PraxisJsonLogicService, normalizeFormLayoutItems, deepMerge, createDefaultFormConfig, normalizeFormConfig as normalizeFormConfig$1, ensureIds, createEmptyRichContentDocument, formIdentityIssues, resolveHidden, resolveOrder, resolveSpan, projectGroupedCommandPartialRows, isPraxisRuntimeGlobalActionEffect, ASYNC_CONFIG_STORAGE, withFormConfigSections, createFieldLayoutItem, getFormLayoutFieldNames, LoggerService, createCorporateLoggerConfig, ConsoleLoggerSink, ResourceDiscoveryService, GlobalActionService, SCHEMA_METADATA_CLIENT_OPTIONS, ResourceQuickConnectComponent, composeHeadersWithVersion, buildApiUrl, readStrongResourceEtag, ApiEndpoint, mapFieldDefinitionsToMetadata, reconcileFormConfig, applyLocalFormCustomizations, materializeFormLayoutFromMetadata, syncWithServerMetadata, PRAXIS_LOADING_CTX, evaluateFieldAccess, normalizeControlTypeKey, normalizePraxisEffectPolicy, buildPraxisEffectDistinctKey, getFormColumnFieldNames, resolveGroupedCommandPartialRowSpans, resolveOffset, buildSchemaIdStorageKeySegment, buildSchemaId, fetchWithETag, resolveControlTypeAlias, getTextTransformer, MemoryCacheAdapter, LocalStorageCacheAdapter, SchemaMetadataClient, DEFAULT_SCHEMA_REQUEST_TIMEOUT_MS, normalizeReactiveDeterminations, CONNECTION_STORAGE, API_URL, PRAXIS_LOADING_RENDERER, FORM_HOOKS_PRESETS, EmptyStateCardComponent, isValidFormConfig, ComponentMetadataRegistry, FieldControlType, isRequiredGlobalActionPayloadMissing, GLOBAL_ACTION_CATALOG, PRAXIS_GLOBAL_ACTION_CATALOG, getGlobalActionCatalog, SURFACE_OPEN_I18N_NAMESPACE, getGlobalActionUiSchema, getRequiredGlobalActionPayloadKeys, hasMeaningfulGlobalActionPayloadValue, SurfaceOpenActionEditorComponent, SURFACE_OPEN_I18N_CONFIG, IconPickerService, validateGlobalActionRefs, normalizeFormMetadata, GenericCrudService, DynamicFormService, projectComponentAuthoringManifest } from '@praxisui/core';
|
|
@@ -164,6 +164,11 @@ const PRAXIS_DYNAMIC_FORM_I18N_CONFIG = {
|
|
|
164
164
|
'config.general.inputMode.edit': 'Editar',
|
|
165
165
|
'config.general.inputMode.view': 'Visualizar',
|
|
166
166
|
'config.general.inputMode.tooltip': 'O mode controla o fluxo (create/edit/view). enableCustomization só libera edição do layout e não altera o mode.',
|
|
167
|
+
'config.general.layoutScope.label': 'Escopo de persistência do layout',
|
|
168
|
+
'config.general.layoutScope.shared': 'Todos os modos (Criar / Editar / Visualizar)',
|
|
169
|
+
'config.general.layoutScope.modeOnly': 'Somente este modo ({{mode}})',
|
|
170
|
+
'config.general.layoutScope.sharedHint': 'Ao salvar, replica seções e grade nos demais modos que ainda compartilham layout.',
|
|
171
|
+
'config.general.layoutScope.modeOnlyHint': 'Ao salvar, aplica este layout exclusivamente ao modo atual, sem alterar os demais modos.',
|
|
167
172
|
'config.general.bindings.label': 'Preferências iniciais',
|
|
168
173
|
'config.general.bindings.persisted': 'As escolhas explícitas serão salvas com o formulário.',
|
|
169
174
|
'config.general.bindings.implicit': 'O formulário usa os valores padrão. Edite uma opção para definir sua preferência.',
|
|
@@ -750,6 +755,11 @@ const PRAXIS_DYNAMIC_FORM_I18N_CONFIG = {
|
|
|
750
755
|
'config.general.inputMode.edit': 'Edit',
|
|
751
756
|
'config.general.inputMode.view': 'View',
|
|
752
757
|
'config.general.inputMode.tooltip': 'mode controls the flow (create/edit/view). enableCustomization only enables layout editing and does not change mode.',
|
|
758
|
+
'config.general.layoutScope.label': 'Layout persistence scope',
|
|
759
|
+
'config.general.layoutScope.shared': 'All modes (Create / Edit / View)',
|
|
760
|
+
'config.general.layoutScope.modeOnly': 'This mode only ({{mode}})',
|
|
761
|
+
'config.general.layoutScope.sharedHint': 'When saving, replicates sections and grid to sibling modes that still share layout.',
|
|
762
|
+
'config.general.layoutScope.modeOnlyHint': 'When saving, applies this layout exclusively to the active mode without altering other modes.',
|
|
753
763
|
'config.general.bindings.label': 'Initial preferences',
|
|
754
764
|
'config.general.bindings.persisted': 'Explicit choices will be saved with the form.',
|
|
755
765
|
'config.general.bindings.implicit': 'The form uses default values. Edit an option to set your preference.',
|
|
@@ -8873,6 +8883,7 @@ function applyDefaultSpans(config) {
|
|
|
8873
8883
|
const DOCUMENT_KIND = 'praxis.dynamic-form.editor';
|
|
8874
8884
|
const DOCUMENT_VERSION = 1;
|
|
8875
8885
|
const VALID_MODES = ['create', 'edit', 'view'];
|
|
8886
|
+
const VALID_LAYOUT_SCOPES = ['shared', 'mode-only'];
|
|
8876
8887
|
const VALID_NOTIFY_VALUES = ['inline', 'snackbar', 'both', 'none'];
|
|
8877
8888
|
const VALID_LABEL_POSITIONS = ['above', 'left'];
|
|
8878
8889
|
const VALID_DENSITIES = ['comfortable', 'cozy', 'compact'];
|
|
@@ -8903,6 +8914,7 @@ function parseLegacyOrDynamicFormDocument(raw) {
|
|
|
8903
8914
|
config: extractLegacyFormConfig(obj),
|
|
8904
8915
|
bindings: {
|
|
8905
8916
|
mode: normalizeMode(obj.inputsPatch?.mode),
|
|
8917
|
+
layoutScope: normalizeLayoutScope(obj.inputsPatch?.layoutScope),
|
|
8906
8918
|
presentationModeGlobal: obj.inputsPatch?.presentationModeGlobal,
|
|
8907
8919
|
emptyState: obj.inputsPatch?.emptyState,
|
|
8908
8920
|
},
|
|
@@ -8978,6 +8990,11 @@ function validateDynamicFormAuthoringInput(raw, context) {
|
|
|
8978
8990
|
!VALID_MODES.includes(rawBindings.mode)) {
|
|
8979
8991
|
diagnostics.push(errorDiagnostic('dynamicForm.bindings.mode.invalid', 'bindings.mode must be create, edit or view', 'bindings.mode'));
|
|
8980
8992
|
}
|
|
8993
|
+
if (Object.prototype.hasOwnProperty.call(rawBindings, 'layoutScope') &&
|
|
8994
|
+
rawBindings.layoutScope != null &&
|
|
8995
|
+
!VALID_LAYOUT_SCOPES.includes(rawBindings.layoutScope)) {
|
|
8996
|
+
diagnostics.push(errorDiagnostic('dynamicForm.bindings.layoutScope.invalid', 'bindings.layoutScope must be shared or mode-only', 'bindings.layoutScope'));
|
|
8997
|
+
}
|
|
8981
8998
|
if (rawBindings.presentationModeGlobal != null &&
|
|
8982
8999
|
typeof rawBindings.presentationModeGlobal !== 'boolean') {
|
|
8983
9000
|
diagnostics.push(errorDiagnostic('dynamicForm.bindings.presentationModeGlobal.invalid', 'bindings.presentationModeGlobal must be boolean or null', 'bindings.presentationModeGlobal'));
|
|
@@ -9120,6 +9137,8 @@ function buildDynamicFormApplyPlan(doc, runtime, options) {
|
|
|
9120
9137
|
const diff = {
|
|
9121
9138
|
modeChanged: normalizeMode(runtime?.currentBindings?.mode) !==
|
|
9122
9139
|
normalizeMode(bindingsPatch?.mode),
|
|
9140
|
+
layoutScopeChanged: normalizeLayoutScope(runtime?.currentBindings?.layoutScope) !==
|
|
9141
|
+
normalizeLayoutScope(bindingsPatch?.layoutScope),
|
|
9123
9142
|
presentationChanged: !deepEqual(runtime?.currentContextSnapshot?.presentation, contextSnapshot?.presentation),
|
|
9124
9143
|
schemaPrefsChanged: !deepEqual(runtime?.currentContextSnapshot?.schemaPrefs, contextSnapshot?.schemaPrefs),
|
|
9125
9144
|
backConfigChanged: !deepEqual(runtime?.currentContextSnapshot?.backConfig, contextSnapshot?.backConfig),
|
|
@@ -9260,6 +9279,7 @@ function normalizeBindings(bindings) {
|
|
|
9260
9279
|
return undefined;
|
|
9261
9280
|
return stripUndefinedShallow({
|
|
9262
9281
|
mode: normalizeMode(bindings.mode),
|
|
9282
|
+
layoutScope: normalizeLayoutScope(bindings.layoutScope),
|
|
9263
9283
|
emptyState: normalizeEmptyState(bindings.emptyState),
|
|
9264
9284
|
presentationModeGlobal: typeof bindings.presentationModeGlobal === 'boolean' || bindings.presentationModeGlobal === null
|
|
9265
9285
|
? bindings.presentationModeGlobal : undefined,
|
|
@@ -9343,6 +9363,9 @@ function normalizeMode(value) {
|
|
|
9343
9363
|
? value
|
|
9344
9364
|
: undefined;
|
|
9345
9365
|
}
|
|
9366
|
+
function normalizeLayoutScope(value) {
|
|
9367
|
+
return value === 'shared' || value === 'mode-only' ? value : undefined;
|
|
9368
|
+
}
|
|
9346
9369
|
function normalizeNullableNumber(value) {
|
|
9347
9370
|
if (value === null)
|
|
9348
9371
|
return null;
|
|
@@ -17511,9 +17534,17 @@ class PraxisDynamicForm {
|
|
|
17511
17534
|
}
|
|
17512
17535
|
async openConfigEditor() {
|
|
17513
17536
|
const initialConfig = normalizeFormConfig$1(this.config);
|
|
17537
|
+
const existingLayoutScope = this.config?.metadata?.layoutScope;
|
|
17514
17538
|
const initialDocument = createDynamicFormAuthoringDocument({
|
|
17515
17539
|
config: initialConfig,
|
|
17516
|
-
bindings: {
|
|
17540
|
+
bindings: {
|
|
17541
|
+
mode: this.mode,
|
|
17542
|
+
...(existingLayoutScope === 'shared' || existingLayoutScope === 'mode-only'
|
|
17543
|
+
? { layoutScope: existingLayoutScope }
|
|
17544
|
+
: {}),
|
|
17545
|
+
presentationModeGlobal: this.presentationModeGlobal,
|
|
17546
|
+
emptyState: this.emptyState,
|
|
17547
|
+
},
|
|
17517
17548
|
contextSnapshot: this.captureCurrentContextSnapshot(),
|
|
17518
17549
|
});
|
|
17519
17550
|
const { PraxisDynamicFormConfigEditor } = await Promise.resolve().then(function () { return index; });
|
|
@@ -17559,7 +17590,15 @@ class PraxisDynamicForm {
|
|
|
17559
17590
|
this.debugLog('[PDF] settingsPanel.reset$');
|
|
17560
17591
|
}
|
|
17561
17592
|
catch { }
|
|
17562
|
-
this.
|
|
17593
|
+
const currentScope = this.config?.metadata?.layoutScope;
|
|
17594
|
+
if (currentScope === 'mode-only') {
|
|
17595
|
+
this.clearDynamicFormEditorPersistence([
|
|
17596
|
+
this.resolveModeKey(this.mode),
|
|
17597
|
+
]);
|
|
17598
|
+
}
|
|
17599
|
+
else {
|
|
17600
|
+
this.clearDynamicFormEditorPersistence();
|
|
17601
|
+
}
|
|
17563
17602
|
});
|
|
17564
17603
|
ref.saved$?.pipe(takeUntil(this.destroy$)).subscribe((cfg) => {
|
|
17565
17604
|
try {
|
|
@@ -20132,6 +20171,10 @@ class PraxisDynamicForm {
|
|
|
20132
20171
|
}
|
|
20133
20172
|
catch { }
|
|
20134
20173
|
this.persistFormConfig(key, this.config);
|
|
20174
|
+
if ((this.config?.metadata?.layoutScope ?? 'shared') !== 'mode-only' &&
|
|
20175
|
+
(this.config?.sections?.length ?? 0) > 0) {
|
|
20176
|
+
void this.persistSharedFormConfigAcrossModes(this.resolveModeKey(this.mode), this.config);
|
|
20177
|
+
}
|
|
20135
20178
|
this.debugLog('[PDF] field-metadata:persisted', { key, fieldName });
|
|
20136
20179
|
}
|
|
20137
20180
|
catch (e) {
|
|
@@ -20844,11 +20887,19 @@ class PraxisDynamicForm {
|
|
|
20844
20887
|
Object.prototype.hasOwnProperty.call(raw, 'backConfig') ||
|
|
20845
20888
|
Object.prototype.hasOwnProperty.call(raw, 'presentation') ||
|
|
20846
20889
|
Object.prototype.hasOwnProperty.call(raw, 'schemaPrefs'));
|
|
20890
|
+
const existingLayoutScope = this.config?.metadata?.layoutScope;
|
|
20847
20891
|
const doc = isCanonicalDocument || isLegacyEditorPayload
|
|
20848
20892
|
? parseLegacyOrDynamicFormDocument(nextConfig)
|
|
20849
20893
|
: createDynamicFormAuthoringDocument({
|
|
20850
20894
|
config: nextConfig,
|
|
20851
|
-
bindings: {
|
|
20895
|
+
bindings: {
|
|
20896
|
+
mode: this.mode,
|
|
20897
|
+
...(existingLayoutScope === 'shared' || existingLayoutScope === 'mode-only'
|
|
20898
|
+
? { layoutScope: existingLayoutScope }
|
|
20899
|
+
: {}),
|
|
20900
|
+
presentationModeGlobal: this.presentationModeGlobal,
|
|
20901
|
+
emptyState: this.emptyState,
|
|
20902
|
+
},
|
|
20852
20903
|
contextSnapshot: this.captureCurrentContextSnapshot(),
|
|
20853
20904
|
});
|
|
20854
20905
|
const plan = buildDynamicFormApplyPlan(doc, this.buildDynamicFormEditorRuntimeContext(), {
|
|
@@ -20861,9 +20912,13 @@ class PraxisDynamicForm {
|
|
|
20861
20912
|
this.executeDynamicFormEditorApplyPlan(plan, 'adapter-apply');
|
|
20862
20913
|
}
|
|
20863
20914
|
buildDynamicFormEditorRuntimeContext() {
|
|
20915
|
+
const existingLayoutScope = this.config?.metadata?.layoutScope;
|
|
20864
20916
|
return {
|
|
20865
20917
|
currentBindings: {
|
|
20866
20918
|
mode: this.mode,
|
|
20919
|
+
...(existingLayoutScope === 'shared' || existingLayoutScope === 'mode-only'
|
|
20920
|
+
? { layoutScope: existingLayoutScope }
|
|
20921
|
+
: {}),
|
|
20867
20922
|
emptyState: this.emptyState,
|
|
20868
20923
|
presentationModeGlobal: this.presentationModeGlobal,
|
|
20869
20924
|
},
|
|
@@ -21062,10 +21117,63 @@ class PraxisDynamicForm {
|
|
|
21062
21117
|
}
|
|
21063
21118
|
}
|
|
21064
21119
|
const nextConfig = this.attachRuntimeMetadataToDynamicFormConfig(plan.canonicalConfig, plan.metadata?.attachSchemaSnapshot === true);
|
|
21120
|
+
const isResetExecution = trigger === 'settings-reset' || plan.runtime?.clearMode === true;
|
|
21121
|
+
const explicitLayoutScope = isResetExecution
|
|
21122
|
+
? undefined
|
|
21123
|
+
: (plan.bindingsPatch?.layoutScope ??
|
|
21124
|
+
plan.canonicalConfig.metadata?.layoutScope ??
|
|
21125
|
+
(trigger === 'adapter-apply'
|
|
21126
|
+
? this.config?.metadata?.layoutScope
|
|
21127
|
+
: undefined));
|
|
21065
21128
|
this.config = normalizeFormConfig$1(nextConfig);
|
|
21129
|
+
if (isResetExecution) {
|
|
21130
|
+
const { layoutScope: _removed, ...restMetadata } = this.config?.metadata || {};
|
|
21131
|
+
this.config = {
|
|
21132
|
+
...this.config,
|
|
21133
|
+
metadata: {
|
|
21134
|
+
...restMetadata,
|
|
21135
|
+
source: 'default',
|
|
21136
|
+
},
|
|
21137
|
+
};
|
|
21138
|
+
}
|
|
21139
|
+
else if (explicitLayoutScope === 'shared' ||
|
|
21140
|
+
explicitLayoutScope === 'mode-only') {
|
|
21141
|
+
this.config = {
|
|
21142
|
+
...this.config,
|
|
21143
|
+
metadata: {
|
|
21144
|
+
...(this.config.metadata || {}),
|
|
21145
|
+
...(plan.persistence?.saveConfig ? { source: 'local' } : {}),
|
|
21146
|
+
layoutScope: explicitLayoutScope,
|
|
21147
|
+
},
|
|
21148
|
+
};
|
|
21149
|
+
}
|
|
21150
|
+
else if (plan.persistence?.saveConfig) {
|
|
21151
|
+
this.config = {
|
|
21152
|
+
...this.config,
|
|
21153
|
+
metadata: {
|
|
21154
|
+
...(this.config.metadata || {}),
|
|
21155
|
+
source: 'local',
|
|
21156
|
+
layoutScope: 'shared',
|
|
21157
|
+
},
|
|
21158
|
+
};
|
|
21159
|
+
}
|
|
21160
|
+
else if (this.config?.metadata && 'layoutScope' in this.config.metadata) {
|
|
21161
|
+
const { layoutScope: _removed, ...restMetadata } = this.config.metadata;
|
|
21162
|
+
this.config = {
|
|
21163
|
+
...this.config,
|
|
21164
|
+
metadata: restMetadata,
|
|
21165
|
+
};
|
|
21166
|
+
}
|
|
21066
21167
|
if (plan.persistence?.saveConfig) {
|
|
21067
|
-
const
|
|
21168
|
+
const activeMode = this.resolveModeKey(targetMode || this.mode);
|
|
21169
|
+
const key = this.formConfigKey(activeMode);
|
|
21170
|
+
const effectiveLayoutScope = this.config?.metadata?.layoutScope === 'mode-only'
|
|
21171
|
+
? 'mode-only'
|
|
21172
|
+
: 'shared';
|
|
21068
21173
|
this.persistFormConfig(key, this.config);
|
|
21174
|
+
if (effectiveLayoutScope === 'shared' && (this.config?.sections?.length ?? 0) > 0) {
|
|
21175
|
+
void this.persistSharedFormConfigAcrossModes(activeMode, this.config);
|
|
21176
|
+
}
|
|
21069
21177
|
}
|
|
21070
21178
|
this.configChange.emit(this.config);
|
|
21071
21179
|
this.presentation = contextSnapshot?.presentation ?? null;
|
|
@@ -21093,6 +21201,100 @@ class PraxisDynamicForm {
|
|
|
21093
21201
|
}
|
|
21094
21202
|
catch { }
|
|
21095
21203
|
}
|
|
21204
|
+
buildCrossModeMetadataSeed(cfg) {
|
|
21205
|
+
const { schemaId: _schemaId, serverHash: _serverHash, schemaContext: _schemaContext, lastVerifiedAt: _lastVerifiedAt, ...restMetadata } = (cfg?.metadata || {});
|
|
21206
|
+
return {
|
|
21207
|
+
...restMetadata,
|
|
21208
|
+
source: 'local',
|
|
21209
|
+
layoutScope: 'shared',
|
|
21210
|
+
};
|
|
21211
|
+
}
|
|
21212
|
+
resolveSiblingModeComponentKeyIds(activeMode, siblingMode) {
|
|
21213
|
+
const primaryKeyId = this.componentKeyId();
|
|
21214
|
+
const rawFormId = String(this.formId || '').trim();
|
|
21215
|
+
const candidates = new Set();
|
|
21216
|
+
if (primaryKeyId) {
|
|
21217
|
+
candidates.add(primaryKeyId);
|
|
21218
|
+
}
|
|
21219
|
+
if (!rawFormId) {
|
|
21220
|
+
return Array.from(candidates);
|
|
21221
|
+
}
|
|
21222
|
+
const activeSuffixes = activeMode === 'view' || activeMode === 'presentation' || activeMode === 'dossier'
|
|
21223
|
+
? [activeMode, 'view', 'detail']
|
|
21224
|
+
: [activeMode];
|
|
21225
|
+
const targetSuffixes = siblingMode === 'view' ? ['view', 'detail'] : [siblingMode];
|
|
21226
|
+
for (const activeSuffix of activeSuffixes) {
|
|
21227
|
+
const pattern = new RegExp(`([-._])${activeSuffix}$`, 'i');
|
|
21228
|
+
const match = rawFormId.match(pattern);
|
|
21229
|
+
if (!match) {
|
|
21230
|
+
continue;
|
|
21231
|
+
}
|
|
21232
|
+
const sep = match[1];
|
|
21233
|
+
for (const targetSuffix of targetSuffixes) {
|
|
21234
|
+
const siblingFormId = rawFormId.replace(pattern, `${sep}${targetSuffix}`);
|
|
21235
|
+
if (!siblingFormId || siblingFormId === rawFormId) {
|
|
21236
|
+
continue;
|
|
21237
|
+
}
|
|
21238
|
+
const siblingKeyId = this.componentKeys.buildComponentId({
|
|
21239
|
+
componentType: 'praxis-dynamic-form',
|
|
21240
|
+
componentId: siblingFormId,
|
|
21241
|
+
instanceKey: this.componentInstanceId,
|
|
21242
|
+
componentRef: this,
|
|
21243
|
+
route: this.route,
|
|
21244
|
+
requireComponentId: true,
|
|
21245
|
+
});
|
|
21246
|
+
if (siblingKeyId) {
|
|
21247
|
+
candidates.add(siblingKeyId);
|
|
21248
|
+
}
|
|
21249
|
+
const unscopedKeyId = this.componentKeys.buildComponentId({
|
|
21250
|
+
componentType: 'praxis-dynamic-form',
|
|
21251
|
+
componentId: siblingFormId,
|
|
21252
|
+
requireComponentId: true,
|
|
21253
|
+
});
|
|
21254
|
+
if (unscopedKeyId) {
|
|
21255
|
+
candidates.add(unscopedKeyId);
|
|
21256
|
+
}
|
|
21257
|
+
candidates.add(siblingFormId);
|
|
21258
|
+
}
|
|
21259
|
+
}
|
|
21260
|
+
return Array.from(candidates);
|
|
21261
|
+
}
|
|
21262
|
+
resolveSiblingModeFormConfigKeys(activeMode, siblingMode) {
|
|
21263
|
+
return this.resolveSiblingModeComponentKeyIds(activeMode, siblingMode).map((keyId) => `praxis-form-config-${keyId}:${siblingMode}`);
|
|
21264
|
+
}
|
|
21265
|
+
resolveSiblingModePresentationKeys(activeMode, siblingMode) {
|
|
21266
|
+
return this.resolveSiblingModeComponentKeyIds(activeMode, siblingMode).map((keyId) => `form-pres:${keyId}:${siblingMode}`);
|
|
21267
|
+
}
|
|
21268
|
+
async persistSharedFormConfigAcrossModes(activeMode, cfg) {
|
|
21269
|
+
const sharedSeed = {
|
|
21270
|
+
...this.cloneFormConfigForPatch(cfg),
|
|
21271
|
+
metadata: this.buildCrossModeMetadataSeed(cfg),
|
|
21272
|
+
};
|
|
21273
|
+
const siblingModes = [
|
|
21274
|
+
'create',
|
|
21275
|
+
'edit',
|
|
21276
|
+
'view',
|
|
21277
|
+
];
|
|
21278
|
+
for (const siblingMode of siblingModes) {
|
|
21279
|
+
if (siblingMode === activeMode || this.isDestroyed) {
|
|
21280
|
+
continue;
|
|
21281
|
+
}
|
|
21282
|
+
const siblingKeys = this.resolveSiblingModeFormConfigKeys(activeMode, siblingMode);
|
|
21283
|
+
if (!siblingKeys.length) {
|
|
21284
|
+
continue;
|
|
21285
|
+
}
|
|
21286
|
+
const existingConfigs = await Promise.all(siblingKeys.map((key) => this.loadConfigFailOpen(key)));
|
|
21287
|
+
if (existingConfigs.some((existing) => existing?.metadata?.layoutScope === 'mode-only')) {
|
|
21288
|
+
continue;
|
|
21289
|
+
}
|
|
21290
|
+
for (const siblingKey of siblingKeys) {
|
|
21291
|
+
if (this.isDestroyed) {
|
|
21292
|
+
break;
|
|
21293
|
+
}
|
|
21294
|
+
await this.persistFormConfig(siblingKey, sharedSeed);
|
|
21295
|
+
}
|
|
21296
|
+
}
|
|
21297
|
+
}
|
|
21096
21298
|
attachRuntimeMetadataToDynamicFormConfig(cfg, attachSchemaSnapshot) {
|
|
21097
21299
|
if (!attachSchemaSnapshot) {
|
|
21098
21300
|
return cfg;
|
|
@@ -21159,13 +21361,46 @@ class PraxisDynamicForm {
|
|
|
21159
21361
|
if (backKey) {
|
|
21160
21362
|
this.asyncConfigStorage.clearConfig(backKey).subscribe();
|
|
21161
21363
|
}
|
|
21162
|
-
const
|
|
21163
|
-
|
|
21364
|
+
const activeMode = this.resolveModeKey(this.mode);
|
|
21365
|
+
const isExplicitModeSubset = Array.isArray(modes) && modes.length > 0;
|
|
21366
|
+
const scopedModes = Array.from(new Set((isExplicitModeSubset ? modes : ['create', 'edit', 'view']).map((mode) => this.resolveModeKey(mode))));
|
|
21367
|
+
if (isExplicitModeSubset) {
|
|
21368
|
+
this.clearStoredPresentationSnapshots(scopedModes);
|
|
21369
|
+
scopedModes.forEach((mode) => {
|
|
21370
|
+
const key = this.formConfigKey(mode);
|
|
21371
|
+
if (key) {
|
|
21372
|
+
this.asyncConfigStorage.clearConfig(key).subscribe();
|
|
21373
|
+
}
|
|
21374
|
+
});
|
|
21375
|
+
return;
|
|
21376
|
+
}
|
|
21377
|
+
this.clearStoredPresentationSnapshots([activeMode, 'presentation', 'dossier']);
|
|
21164
21378
|
scopedModes.forEach((mode) => {
|
|
21165
|
-
|
|
21166
|
-
|
|
21167
|
-
|
|
21379
|
+
if (mode === activeMode) {
|
|
21380
|
+
const key = this.formConfigKey(mode);
|
|
21381
|
+
if (key) {
|
|
21382
|
+
this.asyncConfigStorage.clearConfig(key).subscribe();
|
|
21383
|
+
}
|
|
21384
|
+
return;
|
|
21168
21385
|
}
|
|
21386
|
+
const siblingMode = mode;
|
|
21387
|
+
const siblingKeys = this.resolveSiblingModeFormConfigKeys(activeMode, siblingMode);
|
|
21388
|
+
if (!siblingKeys.length) {
|
|
21389
|
+
return;
|
|
21390
|
+
}
|
|
21391
|
+
forkJoin(siblingKeys.map((key) => this.asyncConfigStorage.loadConfig(key).pipe(take(1), catchError(() => of(null)))))
|
|
21392
|
+
.pipe(take(1))
|
|
21393
|
+
.subscribe((existingConfigs) => {
|
|
21394
|
+
if (existingConfigs.some((existing) => existing?.metadata?.layoutScope === 'mode-only')) {
|
|
21395
|
+
return;
|
|
21396
|
+
}
|
|
21397
|
+
for (const siblingPresKey of this.resolveSiblingModePresentationKeys(activeMode, siblingMode)) {
|
|
21398
|
+
this.asyncConfigStorage.clearConfig(siblingPresKey).subscribe();
|
|
21399
|
+
}
|
|
21400
|
+
for (const siblingKey of siblingKeys) {
|
|
21401
|
+
this.asyncConfigStorage.clearConfig(siblingKey).subscribe();
|
|
21402
|
+
}
|
|
21403
|
+
});
|
|
21169
21404
|
});
|
|
21170
21405
|
}
|
|
21171
21406
|
clearStoredPresentationSnapshots(modes = ['create', 'edit', 'view', 'presentation', 'dossier']) {
|
|
@@ -21740,7 +21975,7 @@ class PraxisDynamicForm {
|
|
|
21740
21975
|
}
|
|
21741
21976
|
}
|
|
21742
21977
|
static ɵfac = i0.ɵɵngDeclareFactory({ minVersion: "12.0.0", version: "21.2.14", ngImport: i0, type: PraxisDynamicForm, deps: [{ token: i1.GenericCrudService }, { token: i2.HttpClient }, { token: i1$3.FormBuilder }, { token: i0.ChangeDetectorRef }, { token: FormLayoutService }, { token: FormContextService }, { token: FormRulesService }, { token: i7.SettingsPanelService }, { token: i2$1.MatDialog }, { token: ASYNC_CONFIG_STORAGE }, { token: CONNECTION_STORAGE }, { token: i1.DynamicFormService }, { token: i9.MatSnackBar }, { token: CanvasStateService }, { token: DynamicFormLayoutService }, { token: ReactiveDeterminationRuntimeService }, { token: i1.ErrorMessageService }, { token: i1.SchemaNormalizerService }, { token: i1.ComponentMetadataRegistry }, { token: i1.GlobalConfigService }, { token: i1.ComponentKeyService }, { token: i1.LoadingOrchestrator }, { token: i0.NgZone }, { token: API_URL }, { token: PRAXIS_LOADING_RENDERER, optional: true }, { token: i13.Router, optional: true }, { token: i13.ActivatedRoute, optional: true }, { token: i1.FormHooksRegistry, optional: true }, { token: FORM_HOOKS_PRESETS, optional: true }, { token: i1.LoggerService, optional: true }, { token: i1.EnterpriseRuntimeContextService, optional: true }], target: i0.ɵɵFactoryTarget.Component });
|
|
21743
|
-
static ɵcmp = i0.ɵɵngDeclareComponent({ minVersion: "17.0.0", version: "21.2.14", type: PraxisDynamicForm, isStandalone: true, selector: "praxis-dynamic-form", inputs: { resourcePath: "resourcePath", resourceId: "resourceId", initialValue: "initialValue", emptyState: "emptyState", editorialContext: "editorialContext", mode: "mode", config: "config", actions: "actions", schemaSource: "schemaSource", schemaUrl: "schemaUrl", readUrl: "readUrl", submitUrl: "submitUrl", submitMethod: "submitMethod", submitIdempotencyKey: "submitIdempotencyKey", submitCorrelationId: "submitCorrelationId", submitResourceVersion: "submitResourceVersion", submitResourceVersionTargetResourceKey: "submitResourceVersionTargetResourceKey", submitResourceVersionTargetIdField: "submitResourceVersionTargetIdField", responseSchemaUrl: "responseSchemaUrl", apiEndpointKey: "apiEndpointKey", apiUrlEntry: "apiUrlEntry", enableCustomization: "enableCustomization", showAiAssistant: "showAiAssistant", formId: "formId", componentInstanceId: "componentInstanceId", configPersistenceStrategy: "configPersistenceStrategy", layout: "layout", layoutMode: "layoutMode", formLayout: "formLayout", generatedLayoutPreset: "generatedLayoutPreset", layoutPolicy: "layoutPolicy", backConfig: "backConfig", hooks: "hooks", removeEmptyContainersOnSave: "removeEmptyContainersOnSave", reactiveValidation: "reactiveValidation", reactiveValidationDebounceMs: "reactiveValidationDebounceMs", notifyIfOutdated: "notifyIfOutdated", snoozeMs: "snoozeMs", autoOpenSettingsOnOutdated: "autoOpenSettingsOnOutdated", readonlyModeGlobal: "readonlyModeGlobal", disabledModeGlobal: "disabledModeGlobal", presentationModeGlobal: "presentationModeGlobal", presentation: "presentation", presentationPreset: "presentationPreset", sectionDefaultAppearance: "sectionDefaultAppearance", sectionDivider: "sectionDivider", visibleGlobal: "visibleGlobal", fieldIconPolicy: "fieldIconPolicy", domainRules: "domainRules", customEndpoints: "customEndpoints" }, outputs: { formSubmit: "formSubmit", formCancel: "formCancel", formReset: "formReset", configChange: "configChange", configPatchChange: "configPatchChange", formReady: "formReady", valueChange: "valueChange", payloadPreviewChange: "payloadPreviewChange", syncCompleted: "syncCompleted", initializationError: "initializationError", loadingStateChange: "loadingStateChange", enableCustomizationChange: "enableCustomizationChange", customAction: "customAction", actionConfirmation: "actionConfirmation", schemaStatusChange: "schemaStatusChange", fieldRenderError: "fieldRenderError", ruleDiagnosticsChange: "ruleDiagnosticsChange", reactiveDeterminationExecuted: "reactiveDeterminationExecuted", reactiveDeterminationPendingChange: "reactiveDeterminationPendingChange", tabChange: "tabChange", tabSelected: "tabSelected" }, providers: [providePraxisI18nConfig(PRAXIS_DYNAMIC_FORM_I18N_CONFIG)], viewQueries: [{ propertyName: "formHost", first: true, predicate: ["formHost"], descendants: true }, { propertyName: "fieldLoaders", predicate: DynamicFieldLoaderDirective, descendants: true }], usesOnChanges: true, ngImport: i0, template: "@if (isLoading) {\n <!-- Loading State -->\n <div class=\"form-loading\" role=\"status\" aria-live=\"polite\" aria-label=\"Carregando formul\u00E1rio\">\n <div class=\"form-loading-header\">\n <mat-progress-spinner diameter=\"32\" aria-label=\"Carregando formul\u00E1rio\"></mat-progress-spinner>\n <div class=\"form-loading-copy\">\n <p class=\"form-loading-title\">Carregando formul\u00E1rio...</p>\n <p class=\"form-loading-subtitle\">Preparando campos e op\u00E7\u00F5es do cadastro.</p>\n </div>\n </div>\n <div class=\"form-loading-skeleton\" aria-hidden=\"true\">\n <span class=\"form-loading-line form-loading-line-title\"></span>\n <span class=\"form-loading-line\"></span>\n <span class=\"form-loading-line form-loading-line-short\"></span>\n <span class=\"form-loading-field\"></span>\n <span class=\"form-loading-field form-loading-field-wide\"></span>\n </div>\n </div>\n} @else if (initializationStatus === 'error') {\n <!-- Error State -->\n <div class=\"form-error\">\n <mat-icon color=\"warn\" [praxisIcon]=\"'error'\"></mat-icon>\n <h3>{{ getErrorTitle() }}</h3>\n <p>{{ currentErrorMessage }}</p>\n @if (isRecoverable) {\n <button mat-stroked-button (click)=\"retryInitialization()\">\n <mat-icon [praxisIcon]=\"'refresh'\"></mat-icon>\n Tentar Novamente\n </button>\n }\n <button mat-button (click)=\"showDetailedError()\" class=\"show-details\">\n Ver Detalhes T\u00E9cnicos\n </button>\n <!-- Permitir corre\u00E7\u00E3o do resourcePath diretamente do estado de erro -->\n <button mat-flat-button color=\"primary\" (click)=\"openQuickConnect()\" class=\"connect-action\">\n <mat-icon [praxisIcon]=\"'bolt'\"></mat-icon>\n Conectar a recurso\n </button>\n </div>\n} @else if (initializationStatus === 'success') {\n <!-- Inline banner for schema change (only when customization is enabled) -->\n @if (shouldShowOutdatedInline()) {\n <div class=\"pfx-form-info-banner\" role=\"status\" aria-live=\"polite\">\n <div class=\"text\">O schema do servidor mudou. Reconciliar agora?</div>\n <div class=\"actions\">\n <button mat-stroked-button color=\"primary\" (click)=\"openConfigEditor()\">\n <mat-icon [praxisIcon]=\"'sync'\"></mat-icon>\n Reconciliar\n </button>\n <button mat-button (click)=\"onSnoozeOutdated()\">Lembrar depois</button>\n <button mat-button (click)=\"onIgnoreOutdated()\">Ignorar</button>\n </div>\n </div>\n }\n\n <!-- Configuration Controls -->\n @if (shouldShowConfigControls && enableCustomization) {\n <div class=\"form-config-controls\">\n @if (showAiAssistant) {\n <button type=\"button\" praxisIconButton=\"auto_awesome\" size=\"dense\" (click)=\"openAiAssistant()\" [disabled]=\"isLoading\"\n [attr.data-testid]=\"aiAssistantTriggerTestId('config-controls')\"\n aria-label=\"Abrir copiloto semantico Praxis do formulario\"\n matTooltip=\"Abrir copiloto sem\u00E2ntico do formul\u00E1rio\">\n </button>\n }\n <button type=\"button\" praxisIconButton=\"settings\" size=\"dense\" (click)=\"openConfigEditor()\" [disabled]=\"isLoading\" class=\"config-button\"\n [matBadge]=\"schemaOutdated ? '!' : ''\" [matBadgeHidden]=\"!schemaOutdated\" matBadgeColor=\"warn\" matBadgeSize=\"small\"\n matBadgePosition=\"above after\"\n [attr.aria-label]=\"configControlLabel\" [matTooltip]=\"configControlLabel\">\n </button>\n <button type=\"button\" praxisIconButton=\"link_off\" size=\"dense\" (click)=\"disconnect()\"\n [attr.aria-label]=\"disconnectControlLabel\" [matTooltip]=\"disconnectControlLabel\"\n [disabled]=\"isLoading\">\n </button>\n </div>\n }\n\n <!-- Form Content -->\n @if (!resourcePath && !hasExplicitSchemaUrl() && !hasRenderableConfig()) {\n <praxis-empty-state-card icon=\"link\" [title]=\"'Conecte o formul\u00E1rio \u00E0 fonte de dados'\"\n [description]=\"'Informe a rota do recurso da API para gerar automaticamente os campos do formul\u00E1rio.'\"\n [primaryAction]=\"{ label: 'Conectar \u00E0 fonte de dados', icon: 'bolt', action: openQuickConnect.bind(this) }\"></praxis-empty-state-card>\n }\n @if (shouldShowContextEmptyState()) {\n <div class=\"form-context-empty-state\" role=\"status\" aria-live=\"polite\">\n <praxis-empty-state-card\n [icon]=\"emptyState?.icon || 'touch_app'\"\n [title]=\"emptyState!.title\"\n [description]=\"emptyState?.description\"\n [tone]=\"emptyState?.tone || 'primary'\"\n [variant]=\"emptyState?.variant || 'transparent'\"\n [alignment]=\"emptyState?.alignment || 'center'\"\n [density]=\"emptyState?.density || 'compact'\"\n [iconContainer]=\"emptyState?.iconContainer || 'circle'\"\n [inline]=\"true\"\n />\n </div>\n } @else {\n <div #entityReadRegion class=\"entity-read-region\" tabindex=\"-1\" role=\"region\" [attr.aria-label]=\"entityReadText('region')\">\n <span class=\"cdk-visually-hidden\" role=\"status\" aria-live=\"polite\" aria-atomic=\"true\">{{ entityReadStatusText() }}</span>\n @if (entityHydrationPending || entityReadFailed) {\n <div class=\"entity-read-feedback\" data-testid=\"form-entity-read-feedback\">\n @if (entityHydrationPending) {\n <mat-progress-spinner diameter=\"28\" mode=\"indeterminate\" aria-hidden=\"true\"></mat-progress-spinner>\n <p aria-hidden=\"true\">{{ entityReadText('loading') }}</p>\n } @else {\n <mat-icon [praxisIcon]=\"'error_outline'\" aria-hidden=\"true\"></mat-icon>\n <p aria-hidden=\"true\">{{ entityReadText('error') }}</p>\n <button mat-stroked-button type=\"button\" (click)=\"retryEntityRead(entityReadRegion)\">{{ entityReadText('retry') }}</button>\n }\n </div>\n }\n <form #formHost (ngSubmit)=\"onSubmit()\" [attr.aria-busy]=\"submitting || entityHydrationPending ? 'true' : null\"\n [style.opacity]=\"entityHydrationPending || entityReadFailed ? '0' : null\"\n [style.transition]=\"entityHydrationPending || entityReadFailed ? 'none' : null\"\n [attr.inert]=\"entityHydrationPending || entityReadFailed ? '' : null\"\n [attr.aria-hidden]=\"entityHydrationPending || entityReadFailed ? 'true' : null\"\n [attr.aria-label]=\"'Formul\u00E1rio ' + (config.metadata?.version || '')\" [class.canvas-mode-enabled]=\"enableCustomization\"\n [class.presentation-mode]=\"effectivePresentation\"\n [class.praxis-dynamic-form--presentation]=\"effectivePresentation\"\n [class.readonly-mode]=\"effectiveReadonly\"\n [attr.data-presentation-preset]=\"effectivePresentation ? effectivePresentationPreset : null\"\n [class.praxis-dynamic-form--corporate-dossier]=\"isCorporateDossierPreset()\"\n [class.praxis-dynamic-form--editorial-card]=\"isEditorialCardPreset()\"\n [class.praxis-dynamic-form--compact-presentation]=\"isCompactPresentationPreset()\"\n [class.editorial-visual-context]=\"hasEditorialVisualContext()\"\n [class.pfx-mounting]=\"isMounting\" [formGroup]=\"form\"\n [ngClass]=\"{\n 'pres-compact': presentationVars.compact,\n 'pres-label-left': presentationVars.labelPosition === 'left',\n 'pres-label-above': presentationVars.labelPosition === 'above'\n }\" [style.--pfx-pres-label-align]=\"presentationVars.labelAlign\"\n [style.--pfx-pres-label-size]=\"presentationVars.labelSize\"\n [style.--pfx-pres-label-width]=\"presentationVars.labelWidth\"\n [style.--pfx-pres-row-gap]=\"presentationVars.density === 'compact' ? '6px' : (presentationVars.density === 'cozy' ? '8px' : '10px')\"\n [style.--pfx-pres-row-padding]=\"presentationVars.density === 'compact' ? '2px 0' : (presentationVars.density === 'cozy' ? '6px 0' : '8px 0')\"\n [style.--pfx-pres-value-align]=\"presentationVars.valueAlign\"\n [style.--pfx-pres-value-size]=\"presentationVars.valueSize\"\n [style.--pdx-form-mount-duration]=\"getMountDurationVar()\"\n [style.--pdx-form-mount-offset]=\"getMountOffsetVar()\"\n [style.--pdx-form-mount-stagger]=\"getMountStaggerVar()\"\n class=\"praxis-dynamic-form\">\n @if (enableCustomization && selectedElement) {\n <praxis-canvas-toolbar (editMetadata)=\"openSelectedElementEditor()\" (selectPath)=\"onSelectPath($event)\"\n (moveUp)=\"onToolbarMove('up')\" (moveDown)=\"onToolbarMove('down')\" (toggleReadonly)=\"onToolbarToggleReadonly()\"\n (toggleRequired)=\"onToolbarToggleRequired()\" (toggleHidden)=\"onToolbarToggleHidden()\"\n (toggleDisabled)=\"onToolbarToggleDisabled()\" (requestClose)=\"onToolbarRequestClose()\"\n [selectedElement]=\"selectedElement\"\n [style.transform]=\"toolbarTransform\"></praxis-canvas-toolbar>\n }\n\n @if (formBlocksBefore?.nodes?.length) {\n <section class=\"form-editorial-blocks form-editorial-blocks-before\" data-editorial-placement=\"before\">\n <praxis-rich-content\n [document]=\"formBlocksBeforeDocument\"\n [context]=\"getEditorialRichContentContext()\"\n [hostCapabilities]=\"richContentHostCapabilities\"\n ></praxis-rich-content>\n </section>\n }\n\n @if (actionPlacement === 'top' && !(effectivePresentation || effectiveReadonly)) {\n <praxis-form-actions data-actions-placement=\"top\" [actions]=\"effectiveActions\" [isSubmitting]=\"submitting\"\n [formIsValid]=\"effectiveFormIsValid\" [submitError]=\"submitError\" [formId]=\"formId\" [actionOverrides]=\"actionRuleProps\"\n [invalidRequiredFieldLabels]=\"invalidRequiredFieldLabels\"\n [suppressInvalidSubmitHint]=\"entityHydrationPending\"\n [editorialVisualContext]=\"hasEditorialVisualContext()\"\n (action)=\"onFormAction($event)\"></praxis-form-actions>\n }\n\n <!-- Tab Layout Navigation Bar -->\n @if (effectiveLayoutMode === 'tabs' && effectiveTabs.length > 1) {\n <nav class=\"prx-form-tabs\" [attr.data-appearance]=\"effectiveTabsAppearance\" role=\"tablist\" aria-label=\"Navega\u00E7\u00E3o em abas do formul\u00E1rio\">\n <div class=\"prx-form-tabs__tablist prx-form-tabs__tablist--scrollable\">\n @for (tab of effectiveTabs; track tab.id) {\n <button\n type=\"button\"\n role=\"tab\"\n class=\"prx-form-tabs__tab\"\n [class.prx-form-tabs__tab--active]=\"activeTabId === tab.id\"\n [attr.aria-selected]=\"activeTabId === tab.id\"\n [attr.aria-controls]=\"getTabAriaControls(tab)\"\n [attr.id]=\"'tab-' + tab.id\"\n [disabled]=\"tab.disabled\"\n [matTooltip]=\"tab.tooltip || null\"\n [matTooltipDisabled]=\"!tab.tooltip\"\n (click)=\"selectTab(tab.id)\"\n >\n @if (tab.icon) {\n <mat-icon class=\"prx-form-tabs__tab-icon\" [praxisIcon]=\"tab.icon\" aria-hidden=\"true\"></mat-icon>\n }\n <span class=\"prx-form-tabs__tab-label\">{{ tab.label }}</span>\n @if (tab.badge != null) {\n <span class=\"prx-form-tabs__tab-badge\">{{ tab.badge }}</span>\n }\n @if (getTabErrorCount(tab) > 0) {\n <span class=\"prx-form-tabs__tab-error-badge\" [attr.aria-label]=\"getTabErrorCount(tab) + ' erros na aba'\">\n {{ getTabErrorCount(tab) }}\n </span>\n }\n </button>\n }\n </div>\n </nav>\n }\n\n @for (section of (config.sections || []); track (section.id ?? $index); let sectionIndex = $index) {\n <div class=\"section-drop-wrapper\" [attr.data-section-id]=\"section.id\" [hidden]=\"!isSectionInActiveTab(section)\"\n [attr.role]=\"effectiveLayoutMode === 'tabs' ? 'tabpanel' : null\"\n [attr.id]=\"effectiveLayoutMode === 'tabs' ? ('section-tabpanel-' + section.id) : null\"\n [attr.aria-labelledby]=\"effectiveLayoutMode === 'tabs' ? ('tab-' + (getTabIdForSection(section) || section.id)) : null\">\n @if (isSectionVisible(section)) {\n <div #sectionEl class=\"form-section canvas-element\" data-canvas-type=\"section\" [attr.data-section-id]=\"section.id\"\n [attr.data-section-index]=\"sectionIndex\" (mouseenter)=\"onElementMouseEnter($event, 'section', section, sectionEl)\"\n (mouseleave)=\"onElementMouseLeave($event)\" (click)=\"onElementClick($event, 'section', section, sectionEl)\"\n [class.selected]=\"selectedElement?.domElement === sectionEl\"\n [class.hovered]=\"hoveredElement?.domElement === sectionEl && selectedElement?.domElement !== sectionEl\"\n [attr.data-section-appearance]=\"getSectionAppearance(section) || null\"\n [attr.data-section-divider]=\"isSectionDividerEnabled(section) ? 'true' : null\"\n [attr.data-presentation-preset]=\"effectivePresentation ? getSectionPresentationPreset(section) : null\"\n [class.form-section--corporate-dossier]=\"isSectionCorporateDossier(section)\"\n [class.form-section--editorial-card]=\"isSectionEditorialCard(section)\"\n [class.form-section--compact-presentation]=\"isSectionCompactPresentation(section)\"\n [style.marginBottom.px]=\"!isLastVisibleSection(section) ? getSectionGapBottom(section) : null\" [ngClass]=\"getSectionClasses(section)\"\n [ngStyle]=\"getSectionStyles(section)\">\n @if (!shouldHideSectionHeader(section)) {\n <div\n class=\"section-heading\"\n [class.align-center]=\"getSectionHeaderAlign(section) === 'center'\"\n [class.step-appearance]=\"getSectionAppearance(section) === 'step'\"\n [class.title-only]=\"isSectionHeaderTitleOnly(section)\"\n >\n <div class=\"section-heading-text\" [matTooltip]=\"getSectionHeaderTooltip(section) || null\"\n [matTooltipDisabled]=\"!getSectionHeaderTooltip(section)\">\n @if (getSectionStepLabel(section)) {\n <div class=\"section-step-label\" [class.align-center]=\"getSectionHeaderAlign(section) === 'center'\">\n {{ getSectionStepLabel(section) }}\n </div>\n }\n @if (getSectionTitle(section)) {\n <h3 class=\"section-title\" [class.title-large]=\"getSectionTitleStyle(section) === 'titleLarge'\"\n [class.title-medium]=\"getSectionTitleStyle(section) === 'titleMedium'\"\n [class.title-small]=\"getSectionTitleStyle(section) === 'titleSmall'\"\n [class.headline-small]=\"getSectionTitleStyle(section) === 'headlineSmall'\"\n [style.marginBottom.px]=\"getEffectiveSectionTitleGapBottom(section)\" [style.color]=\"getSectionTitleColor(section) || null\"\n [class.align-center]=\"getSectionHeaderAlign(section) === 'center'\"\n [attr.id]=\"sectionPanelId(section, sectionIndex) + '-title'\">\n @let sectionHeaderVisual = getSectionHeaderVisual(section);\n @let sectionHeaderAvatarSize = getSectionHeaderAvatarSize(section);\n @if (sectionHeaderVisual.kind === 'icon') {\n <mat-icon class=\"section-title-icon\" aria-hidden=\"true\" [praxisIcon]=\"sectionHeaderVisual.icon\"></mat-icon>\n }\n @if (sectionHeaderVisual.kind === 'image') {\n <img class=\"section-title-avatar section-title-avatar-image\" [class.size-sm]=\"sectionHeaderAvatarSize === 'sm'\"\n [class.size-md]=\"sectionHeaderAvatarSize === 'md'\" [class.size-lg]=\"sectionHeaderAvatarSize === 'lg'\"\n [src]=\"sectionHeaderVisual.src\" [alt]=\"sectionHeaderVisual.alt\" />\n }\n @if (sectionHeaderVisual.kind === 'initials') {\n <span class=\"section-title-avatar section-title-avatar-text\" [class.size-sm]=\"sectionHeaderAvatarSize === 'sm'\"\n [class.size-md]=\"sectionHeaderAvatarSize === 'md'\" [class.size-lg]=\"sectionHeaderAvatarSize === 'lg'\" aria-hidden=\"true\">\n {{ sectionHeaderVisual.text }}\n </span>\n @if (sectionHeaderVisual.ariaLabel) {\n <span class=\"section-title-avatar-sr-only\">{{ sectionHeaderVisual.ariaLabel }}</span>\n }\n }\n @if (sectionHeaderVisual.kind === 'placeholder') {\n <span class=\"section-title-avatar section-title-avatar-placeholder\" [class.size-sm]=\"sectionHeaderAvatarSize === 'sm'\"\n [class.size-md]=\"sectionHeaderAvatarSize === 'md'\" [class.size-lg]=\"sectionHeaderAvatarSize === 'lg'\" aria-hidden=\"true\">\n @if (sectionHeaderVisual.icon) {\n <mat-icon aria-hidden=\"true\" [praxisIcon]=\"sectionHeaderVisual.icon\"></mat-icon>\n }\n @if (sectionHeaderVisual.text) {\n <span>{{ sectionHeaderVisual.text }}</span>\n }\n </span>\n @if (sectionHeaderVisual.ariaLabel) {\n <span class=\"section-title-avatar-sr-only\">{{ sectionHeaderVisual.ariaLabel }}</span>\n }\n }\n {{ getSectionTitle(section) }}\n @if (enableCustomization) {\n <button type=\"button\" class=\"inline-edit-btn\" praxisIconButton=\"edit\" size=\"dense\" (click)=\"openSectionEditor(section, 'title')\"\n aria-label=\"Editar t\u00EDtulo da se\u00E7\u00E3o\" matTooltip=\"Editar t\u00EDtulo\">\n </button>\n }\n </h3>\n }\n @if (getSectionDescription(section)) {\n <p class=\"section-description\" [class.body-large]=\"getSectionDescriptionStyle(section) === 'bodyLarge'\"\n [class.body-medium]=\"getSectionDescriptionStyle(section) === 'bodyMedium'\"\n [class.body-small]=\"getSectionDescriptionStyle(section) === 'bodySmall'\"\n [style.marginBottom.px]=\"getSectionDescriptionGapBottom(section) ?? 8\" [style.color]=\"getSectionDescriptionColor(section) || null\"\n [class.align-center]=\"getSectionHeaderAlign(section) === 'center'\">\n {{ getSectionDescription(section) }}\n @if (enableCustomization) {\n <button type=\"button\" class=\"inline-edit-btn\" praxisIconButton=\"edit\" size=\"dense\"\n (click)=\"openSectionEditor(section, 'description')\" aria-label=\"Editar descri\u00E7\u00E3o da se\u00E7\u00E3o\"\n matTooltip=\"Editar descri\u00E7\u00E3o\">\n </button>\n }\n </p>\n }\n </div>\n @if (getSectionHeaderActions(section).length) {\n <div class=\"section-heading-actions\" [class.align-center]=\"getSectionHeaderAlign(section) === 'center'\">\n @for (action of getSectionHeaderActions(section); track action.id) {\n <button\n type=\"button\"\n class=\"section-heading-action-btn\"\n [praxisIconButton]=\"action.icon\"\n size=\"compact\"\n [busy]=\"action.loading\"\n [disabled]=\"isSectionHeaderActionDisabled(action)\"\n [matTooltip]=\"getSectionHeaderActionTooltip(action)\"\n [attr.aria-label]=\"action.label\"\n [attr.aria-busy]=\"action.loading ? 'true' : null\"\n [ngClass]=\"getSectionHeaderActionNgClass(action)\"\n [ngStyle]=\"getSectionHeaderActionStyles(action)\"\n (click)=\"onSectionHeaderActionClick(section, action, $event)\"\n >\n @if (action.loading) {\n <span class=\"section-heading-action-sr-only\">{{ getSectionHeaderActionLoadingLabel(action) }}</span>\n }\n </button>\n }\n </div>\n }\n @if (isSectionCollapsible(section)) {\n <button type=\"button\" class=\"section-collapse-btn\" [praxisIconButton]=\"isSectionCollapsed(section) ? 'expand_more' : 'expand_less'\" size=\"compact\"\n (click)=\"toggleSectionCollapse($event, section)\" [attr.aria-expanded]=\"!isSectionCollapsed(section)\"\n [attr.aria-controls]=\"sectionPanelId(section, sectionIndex)\"\n [attr.aria-label]=\"isSectionCollapsed(section) ? 'Expandir se\u00E7\u00E3o' : 'Recolher se\u00E7\u00E3o'\">\n </button>\n }\n </div>\n }\n\n <div class=\"section-body\" [class.collapsed]=\"isSectionCollapsed(section)\"\n [attr.id]=\"sectionPanelId(section, sectionIndex)\"\n [attr.role]=\"getSectionTitle(section) ? 'region' : null\"\n [attr.aria-labelledby]=\"getSectionTitle(section) ? sectionPanelId(section, sectionIndex) + '-title' : null\">\n @if (!isSectionCollapsed(section)) {\n @for (row of section.rows; track (row.id ?? $index); let rowIndex = $index) {\n @if (isRowVisible(row)) {\n <div class=\"row-drop-wrapper\" [attr.data-section-id]=\"section.id\">\n <div #rowEl class=\"form-row grid-12 canvas-element\" data-canvas-type=\"row\" [attr.data-row-index]=\"rowIndex\"\n [attr.data-section-id]=\"section.id\" [attr.data-row-id]=\"row.id\" [style.--pfx-grid-gap.px]=\"getRowGap(row)\"\n [style.--pfx-field-gap.px]=\"getRowRowGap(row)\"\n [style.--pfx-mount-index]=\"rowIndex\"\n [style.marginBottom.px]=\"rowIndex < section.rows.length - 1 ? (getRowRowGap(row) ?? null) : null\"\n [ngClass]=\"getRowClasses(row)\" [ngStyle]=\"getRowStyles(row)\"\n (mouseenter)=\"onElementMouseEnter($event, 'row', row, rowEl)\" (mouseleave)=\"onElementMouseLeave($event)\"\n (click)=\"onElementClick($event, 'row', row, rowEl)\" [class.selected]=\"selectedElement?.domElement === rowEl\"\n [class.hovered]=\"hoveredElement?.domElement === rowEl && selectedElement?.domElement !== rowEl\">\n @for (column of row.columns; track (column.id ?? $index); let colIndex = $index) {\n @if (isColumnVisible(column)) {\n <div class=\"column-drop-wrapper\" [attr.data-section-id]=\"section.id\" [attr.data-row-id]=\"row.id\">\n <div #colEl class=\"form-column canvas-element\" [ngClass]=\"getColumnClasses(column, row)\"\n [style.padding.px]=\"getColumnPadding(column)\" [style.--pfx-field-gap.px]=\"getRowRowGap(row)\"\n [ngStyle]=\"getColumnStyles(column)\" [attr.data-testid]=\"column.testId || null\"\n [attr.data-row-gap]=\"getRowRowGap(row)\" data-canvas-type=\"column\" [attr.data-column-index]=\"colIndex\"\n [attr.data-row-index]=\"rowIndex\" [attr.data-section-id]=\"section.id\" [attr.data-row-id]=\"row.id\"\n [attr.data-column-id]=\"column.id\" (mouseenter)=\"onElementMouseEnter($event, 'column', column, colEl)\"\n (mouseleave)=\"onElementMouseLeave($event)\" (click)=\"onElementClick($event, 'column', column, colEl)\"\n [class.selected]=\"selectedElement?.domElement === colEl\"\n [class.hovered]=\"hoveredElement?.domElement === colEl && selectedElement?.domElement !== colEl\">\n @for (renderItem of getColumnRenderItems(column); track renderItem.id) {\n @if (renderItem.kind === 'fields') {\n <ng-container dynamicFieldLoader [fields]=\"getRenderableFieldsForLoader(renderItem.fields)\" [formGroup]=\"form\"\n [enableExternalControlBinding]=\"true\"\n [readonlyMode]=\"effectiveReadonly\"\n [disabledMode]=\"effectiveDisabledMode\"\n [presentationMode]=\"presentationForLoader\" [visible]=\"visibleGlobal === null ? null : visibleGlobal\"\n [canvasMode]=\"enableCustomization\" (canvasMouseEnter)=\"onFieldMouseEnter($event)\"\n (canvasMouseLeave)=\"onFieldMouseLeave($event)\" (canvasClick)=\"onFieldClick($event)\"\n (canvasFocus)=\"onFieldFocus($event)\"\n (renderError)=\"onFieldRenderError($event)\">\n </ng-container>\n } @else {\n <praxis-rich-content\n class=\"form-layout-rich-content\"\n [ngClass]=\"renderItem.className || null\"\n [ngStyle]=\"renderItem.style || null\"\n [document]=\"renderItem.document\"\n [layout]=\"renderItem.layout\"\n [rootClassName]=\"renderItem.rootClassName || ''\"\n [context]=\"getEditorialRichContentContext()\"\n [hostCapabilities]=\"richContentHostCapabilities\"\n ></praxis-rich-content>\n }\n }\n </div>\n </div>\n } }\n </div>\n </div>\n }\n }\n } @else {\n <div class=\"section-collapsed-placeholder\">\n <mat-icon aria-hidden=\"true\" [praxisIcon]=\"'unfold_more'\"></mat-icon>\n <span>{{ getSectionCollapsedSummary(section) }}</span>\n </div>\n }\n @if (isLastVisibleSection(section) && beforeActionsPlacement === 'insideLastSection' && formBlocksBeforeActions?.nodes?.length) {\n <section class=\"form-editorial-blocks form-editorial-blocks-before-actions\" data-editorial-placement=\"beforeActions\">\n <praxis-rich-content\n [document]=\"formBlocksBeforeActionsDocument\"\n [context]=\"getEditorialRichContentContext()\"\n [hostCapabilities]=\"richContentHostCapabilities\"\n ></praxis-rich-content>\n </section>\n }\n @if (actionPlacement === 'insideLastSection' && isLastVisibleSection(section) && !(effectivePresentation\n || effectiveReadonly)) {\n <praxis-form-actions data-actions-placement=\"insideLastSection\" [actions]=\"effectiveActions\"\n [isSubmitting]=\"submitting\" [formIsValid]=\"effectiveFormIsValid\" [submitError]=\"submitError\" [formId]=\"formId\"\n [actionOverrides]=\"actionRuleProps\" [invalidRequiredFieldLabels]=\"invalidRequiredFieldLabels\"\n [suppressInvalidSubmitHint]=\"entityHydrationPending\"\n [editorialVisualContext]=\"hasEditorialVisualContext()\"\n (action)=\"onFormAction($event)\"></praxis-form-actions>\n }\n </div>\n <!-- Overlay de bloqueio durante submiss\u00E3o -->\n @if (submitting) {\n <div class=\"form-blocking-overlay\" aria-live=\"polite\">\n <mat-progress-spinner\n diameter=\"40\"\n color=\"primary\"\n [attr.aria-label]=\"config.messages?.loading?.submit || 'Salvando formul\u00E1rio'\"\n ></mat-progress-spinner>\n <p>{{ config.messages?.loading?.submit || 'Salvando...' }}</p>\n </div>\n }\n </div>\n\n @if (enableCustomization && selectedElement?.domElement === sectionEl) {\n <div class=\"add-section-container\">\n <div class=\"add-section-line\"></div>\n <button mat-fab color=\"primary\" aria-label=\"Adicionar nova se\u00E7\u00E3o\" (click)=\"addNewSectionAfter(sectionIndex)\"\n matTooltip=\"Adicionar nova se\u00E7\u00E3o aqui\">\n <mat-icon [praxisIcon]=\"'add'\"></mat-icon>\n </button>\n <div class=\"add-section-line\"></div>\n </div>\n }\n }\n </div>\n }\n\n @if (beforeActionsPlacement !== 'insideLastSection' && formBlocksBeforeActions?.nodes?.length) {\n <section class=\"form-editorial-blocks form-editorial-blocks-before-actions\" data-editorial-placement=\"beforeActions\">\n <praxis-rich-content\n [document]=\"formBlocksBeforeActionsDocument\"\n [context]=\"getEditorialRichContentContext()\"\n [hostCapabilities]=\"richContentHostCapabilities\"\n ></praxis-rich-content>\n </section>\n }\n\n @if (actionPlacement === 'afterSections' && !(effectivePresentation || effectiveReadonly)) {\n <praxis-form-actions data-actions-placement=\"afterSections\" [actions]=\"effectiveActions\" [isSubmitting]=\"submitting\"\n [formIsValid]=\"effectiveFormIsValid\" [submitError]=\"submitError\" [formId]=\"formId\"\n [actionOverrides]=\"actionRuleProps\" [invalidRequiredFieldLabels]=\"invalidRequiredFieldLabels\"\n [suppressInvalidSubmitHint]=\"entityHydrationPending\"\n [editorialVisualContext]=\"hasEditorialVisualContext()\"\n (action)=\"onFormAction($event)\"></praxis-form-actions>\n }\n\n @if (formBlocksAfter?.nodes?.length) {\n <section class=\"form-editorial-blocks form-editorial-blocks-after\" data-editorial-placement=\"after\">\n <praxis-rich-content\n [document]=\"formBlocksAfterDocument\"\n [context]=\"getEditorialRichContentContext()\"\n [hostCapabilities]=\"richContentHostCapabilities\"\n ></praxis-rich-content>\n </section>\n }\n </form>\n </div>\n }\n @if (showAiAssistant && !enableCustomization && (mode === 'view' || mode === 'presentation' || mode === 'dossier') && !shouldShowContextEmptyState()) {\n <div class=\"ai-floating-assistant\">\n <button type=\"button\" praxisIconButton=\"auto_awesome\" size=\"compact\" (click)=\"openAiAssistant()\" [disabled]=\"isLoading || entityHydrationPending || entityReadFailed\"\n [attr.data-testid]=\"aiAssistantTriggerTestId('view-floating')\"\n aria-label=\"Abrir copiloto semantico Praxis do formulario\"\n matTooltip=\"Pedir ajuda sobre este formul\u00E1rio\">\n </button>\n </div>\n }\n @if (showAiAssistant && aiAssistantOpen && aiAssistantViewState) {\n <praxis-ai-assistant-shell\n [labels]=\"aiAssistantLabels\"\n [mode]=\"aiAssistantViewState.mode\"\n [state]=\"aiAssistantViewState.state\"\n [contextItems]=\"aiAssistantViewState.contextItems\"\n [attachments]=\"aiAssistantViewState.attachments\"\n [messages]=\"aiAssistantViewState.messages\"\n [quickReplies]=\"aiAssistantViewState.quickReplies\"\n [prompt]=\"aiAssistantPrompt\"\n [statusText]=\"aiAssistantViewState.statusText\"\n [errorText]=\"aiAssistantViewState.errorText\"\n [busy]=\"aiAssistantViewState.state === 'processing' || aiAssistantViewState.state === 'applying'\"\n [canApply]=\"aiAssistantViewState.canApply\"\n [layout]=\"aiAssistantLayout\"\n testIdPrefix=\"dynamic-form-ai-assistant\"\n panelTestId=\"dynamic-form-ai-assistant-panel\"\n submitTestId=\"dynamic-form-ai-assistant-submit\"\n applyTestId=\"dynamic-form-ai-assistant-apply\"\n (promptChange)=\"onAiAssistantPromptChange($event)\"\n (submitPrompt)=\"onAiAssistantSubmit($event)\"\n (apply)=\"onAiAssistantApply()\"\n (retryTurn)=\"onAiAssistantRetry()\"\n (cancelTurn)=\"onAiAssistantCancel()\"\n (quickReply)=\"onAiAssistantQuickReply($event)\"\n (editMessage)=\"onAiAssistantEditMessage($event)\"\n (resendMessage)=\"onAiAssistantResendMessage($event)\"\n (layoutChange)=\"onAiAssistantLayoutChange($event)\"\n (close)=\"closeAiAssistant()\"\n ></praxis-ai-assistant-shell>\n }\n }\n", styles: ["@charset \"UTF-8\";.span-xs-1{grid-column:span 1}.span-xs-2{grid-column:span 2}.span-xs-3{grid-column:span 3}.span-xs-4{grid-column:span 4}.span-xs-5{grid-column:span 5}.span-xs-6{grid-column:span 6}.span-xs-7{grid-column:span 7}.span-xs-8{grid-column:span 8}.span-xs-9{grid-column:span 9}.span-xs-10{grid-column:span 10}.span-xs-11{grid-column:span 11}.span-xs-12{grid-column:span 12}.offset-xs-0{margin-left:0%}.offset-xs-1{margin-left:calc(1 / 12 * 100%)}.offset-xs-2{margin-left:calc(2 / 12 * 100%)}.offset-xs-3{margin-left:25%}.offset-xs-4{margin-left:calc(4 / 12 * 100%)}.offset-xs-5{margin-left:calc(5 / 12 * 100%)}.offset-xs-6{margin-left:50%}.offset-xs-7{margin-left:calc(7 / 12 * 100%)}.offset-xs-8{margin-left:calc(8 / 12 * 100%)}.offset-xs-9{margin-left:75%}.offset-xs-10{margin-left:calc(10 / 12 * 100%)}.offset-xs-11{margin-left:calc(11 / 12 * 100%)}.order-xs--12{order:-12}.order-xs--11{order:-11}.order-xs--10{order:-10}.order-xs--9{order:-9}.order-xs--8{order:-8}.order-xs--7{order:-7}.order-xs--6{order:-6}.order-xs--5{order:-5}.order-xs--4{order:-4}.order-xs--3{order:-3}.order-xs--2{order:-2}.order-xs--1{order:-1}.order-xs-0{order:0}.order-xs-1{order:1}.order-xs-2{order:2}.order-xs-3{order:3}.order-xs-4{order:4}.order-xs-5{order:5}.order-xs-6{order:6}.order-xs-7{order:7}.order-xs-8{order:8}.order-xs-9{order:9}.order-xs-10{order:10}.order-xs-11{order:11}.order-xs-12{order:12}.hidden-xs{display:none}@container praxis-form-row (min-width: 600px){.span-sm-1{grid-column:span 1}.span-sm-2{grid-column:span 2}.span-sm-3{grid-column:span 3}.span-sm-4{grid-column:span 4}.span-sm-5{grid-column:span 5}.span-sm-6{grid-column:span 6}.span-sm-7{grid-column:span 7}.span-sm-8{grid-column:span 8}.span-sm-9{grid-column:span 9}.span-sm-10{grid-column:span 10}.span-sm-11{grid-column:span 11}.span-sm-12{grid-column:span 12}.offset-sm-0{margin-left:0%}.offset-sm-1{margin-left:calc(1 / 12 * 100%)}.offset-sm-2{margin-left:calc(2 / 12 * 100%)}.offset-sm-3{margin-left:25%}.offset-sm-4{margin-left:calc(4 / 12 * 100%)}.offset-sm-5{margin-left:calc(5 / 12 * 100%)}.offset-sm-6{margin-left:50%}.offset-sm-7{margin-left:calc(7 / 12 * 100%)}.offset-sm-8{margin-left:calc(8 / 12 * 100%)}.offset-sm-9{margin-left:75%}.offset-sm-10{margin-left:calc(10 / 12 * 100%)}.offset-sm-11{margin-left:calc(11 / 12 * 100%)}.order-sm--12{order:-12}.order-sm--11{order:-11}.order-sm--10{order:-10}.order-sm--9{order:-9}.order-sm--8{order:-8}.order-sm--7{order:-7}.order-sm--6{order:-6}.order-sm--5{order:-5}.order-sm--4{order:-4}.order-sm--3{order:-3}.order-sm--2{order:-2}.order-sm--1{order:-1}.order-sm-0{order:0}.order-sm-1{order:1}.order-sm-2{order:2}.order-sm-3{order:3}.order-sm-4{order:4}.order-sm-5{order:5}.order-sm-6{order:6}.order-sm-7{order:7}.order-sm-8{order:8}.order-sm-9{order:9}.order-sm-10{order:10}.order-sm-11{order:11}.order-sm-12{order:12}.hidden-sm{display:none}}@container praxis-form-row (min-width: 900px){.span-md-1{grid-column:span 1}.span-md-2{grid-column:span 2}.span-md-3{grid-column:span 3}.span-md-4{grid-column:span 4}.span-md-5{grid-column:span 5}.span-md-6{grid-column:span 6}.span-md-7{grid-column:span 7}.span-md-8{grid-column:span 8}.span-md-9{grid-column:span 9}.span-md-10{grid-column:span 10}.span-md-11{grid-column:span 11}.span-md-12{grid-column:span 12}.offset-md-0{margin-left:0%}.offset-md-1{margin-left:calc(1 / 12 * 100%)}.offset-md-2{margin-left:calc(2 / 12 * 100%)}.offset-md-3{margin-left:25%}.offset-md-4{margin-left:calc(4 / 12 * 100%)}.offset-md-5{margin-left:calc(5 / 12 * 100%)}.offset-md-6{margin-left:50%}.offset-md-7{margin-left:calc(7 / 12 * 100%)}.offset-md-8{margin-left:calc(8 / 12 * 100%)}.offset-md-9{margin-left:75%}.offset-md-10{margin-left:calc(10 / 12 * 100%)}.offset-md-11{margin-left:calc(11 / 12 * 100%)}.order-md--12{order:-12}.order-md--11{order:-11}.order-md--10{order:-10}.order-md--9{order:-9}.order-md--8{order:-8}.order-md--7{order:-7}.order-md--6{order:-6}.order-md--5{order:-5}.order-md--4{order:-4}.order-md--3{order:-3}.order-md--2{order:-2}.order-md--1{order:-1}.order-md-0{order:0}.order-md-1{order:1}.order-md-2{order:2}.order-md-3{order:3}.order-md-4{order:4}.order-md-5{order:5}.order-md-6{order:6}.order-md-7{order:7}.order-md-8{order:8}.order-md-9{order:9}.order-md-10{order:10}.order-md-11{order:11}.order-md-12{order:12}.hidden-md{display:none}}@container praxis-form-row (min-width: 1200px){.span-lg-1{grid-column:span 1}.span-lg-2{grid-column:span 2}.span-lg-3{grid-column:span 3}.span-lg-4{grid-column:span 4}.span-lg-5{grid-column:span 5}.span-lg-6{grid-column:span 6}.span-lg-7{grid-column:span 7}.span-lg-8{grid-column:span 8}.span-lg-9{grid-column:span 9}.span-lg-10{grid-column:span 10}.span-lg-11{grid-column:span 11}.span-lg-12{grid-column:span 12}.offset-lg-0{margin-left:0%}.offset-lg-1{margin-left:calc(1 / 12 * 100%)}.offset-lg-2{margin-left:calc(2 / 12 * 100%)}.offset-lg-3{margin-left:25%}.offset-lg-4{margin-left:calc(4 / 12 * 100%)}.offset-lg-5{margin-left:calc(5 / 12 * 100%)}.offset-lg-6{margin-left:50%}.offset-lg-7{margin-left:calc(7 / 12 * 100%)}.offset-lg-8{margin-left:calc(8 / 12 * 100%)}.offset-lg-9{margin-left:75%}.offset-lg-10{margin-left:calc(10 / 12 * 100%)}.offset-lg-11{margin-left:calc(11 / 12 * 100%)}.order-lg--12{order:-12}.order-lg--11{order:-11}.order-lg--10{order:-10}.order-lg--9{order:-9}.order-lg--8{order:-8}.order-lg--7{order:-7}.order-lg--6{order:-6}.order-lg--5{order:-5}.order-lg--4{order:-4}.order-lg--3{order:-3}.order-lg--2{order:-2}.order-lg--1{order:-1}.order-lg-0{order:0}.order-lg-1{order:1}.order-lg-2{order:2}.order-lg-3{order:3}.order-lg-4{order:4}.order-lg-5{order:5}.order-lg-6{order:6}.order-lg-7{order:7}.order-lg-8{order:8}.order-lg-9{order:9}.order-lg-10{order:10}.order-lg-11{order:11}.order-lg-12{order:12}.hidden-lg{display:none}}@container praxis-form-row (min-width: 1536px){.span-xl-1{grid-column:span 1}.span-xl-2{grid-column:span 2}.span-xl-3{grid-column:span 3}.span-xl-4{grid-column:span 4}.span-xl-5{grid-column:span 5}.span-xl-6{grid-column:span 6}.span-xl-7{grid-column:span 7}.span-xl-8{grid-column:span 8}.span-xl-9{grid-column:span 9}.span-xl-10{grid-column:span 10}.span-xl-11{grid-column:span 11}.span-xl-12{grid-column:span 12}.offset-xl-0{margin-left:0%}.offset-xl-1{margin-left:calc(1 / 12 * 100%)}.offset-xl-2{margin-left:calc(2 / 12 * 100%)}.offset-xl-3{margin-left:25%}.offset-xl-4{margin-left:calc(4 / 12 * 100%)}.offset-xl-5{margin-left:calc(5 / 12 * 100%)}.offset-xl-6{margin-left:50%}.offset-xl-7{margin-left:calc(7 / 12 * 100%)}.offset-xl-8{margin-left:calc(8 / 12 * 100%)}.offset-xl-9{margin-left:75%}.offset-xl-10{margin-left:calc(10 / 12 * 100%)}.offset-xl-11{margin-left:calc(11 / 12 * 100%)}.order-xl--12{order:-12}.order-xl--11{order:-11}.order-xl--10{order:-10}.order-xl--9{order:-9}.order-xl--8{order:-8}.order-xl--7{order:-7}.order-xl--6{order:-6}.order-xl--5{order:-5}.order-xl--4{order:-4}.order-xl--3{order:-3}.order-xl--2{order:-2}.order-xl--1{order:-1}.order-xl-0{order:0}.order-xl-1{order:1}.order-xl-2{order:2}.order-xl-3{order:3}.order-xl-4{order:4}.order-xl-5{order:5}.order-xl-6{order:6}.order-xl-7{order:7}.order-xl-8{order:8}.order-xl-9{order:9}.order-xl-10{order:10}.order-xl-11{order:11}.order-xl-12{order:12}.hidden-xl{display:none}}.canvas-mode-enabled{--canvas-hit: 14px}.canvas-mode-enabled .canvas-element{position:relative;z-index:0;border-radius:8px;outline:2px solid transparent;outline-offset:2px;transition:outline-color .2s ease,outline-style .2s ease}.canvas-mode-enabled .canvas-element:before{content:\"\";position:absolute;inset:calc(-1 * var(--canvas-hit));pointer-events:none;border-radius:inherit;background:transparent}.canvas-mode-enabled .canvas-element[data-canvas-type=section]{--outline-color: var(--md-sys-color-primary)}.canvas-mode-enabled .canvas-element[data-canvas-type=row]{--outline-color: var(--md-sys-color-secondary)}.canvas-mode-enabled .canvas-element[data-canvas-type=column],.canvas-mode-enabled .canvas-element[data-canvas-type=field]{--outline-color: var(--md-sys-color-tertiary)}.canvas-mode-enabled .canvas-element[data-canvas-type=actions]{--outline-color: var(--md-sys-color-primary)}.canvas-mode-enabled .canvas-element.hovered:not(.selected){outline-color:var(--outline-color, var(--md-sys-color-primary));outline-style:dashed}.canvas-mode-enabled .canvas-element.selected{outline-color:var(--outline-color, var(--md-sys-color-primary));outline-style:solid;box-shadow:0 0 0 2px var(--outline-color, var(--md-sys-color-primary))}.canvas-mode-enabled .canvas-element.hovered{z-index:var(--praxis-layer-authoring-hover, 300)}.canvas-mode-enabled .canvas-element.selected{z-index:var(--praxis-layer-authoring-selected, 320)}.section-drop-wrapper,.row-drop-wrapper,.column-drop-wrapper{display:contents}.add-section-container{display:flex;align-items:center;justify-content:center;padding:.5rem 0;margin:-.5rem 0;position:relative;z-index:var(--praxis-layer-authoring-insert, 280)}.add-section-container .add-section-line{flex-grow:1;height:1px;background:repeating-linear-gradient(90deg,var(--md-sys-color-outline-variant),var(--md-sys-color-outline-variant) 4px,transparent 4px,transparent 8px)}.add-section-container button{margin:0 1rem;transform:scale(.85)}:host{display:block;position:relative;--pfx-editorial-form-radius: var(--pfx-form-section-radius, 8px);--pfx-editorial-form-border: var( --pfx-form-stroke, var(--pdx-color-border-subtle, var(--md-sys-color-outline-variant)) );--pfx-editorial-form-surface: var( --pfx-form-section-surface, var(--pdx-color-surface, var(--md-sys-color-surface-container)) );--pfx-editorial-form-surface-muted: var( --pdx-color-surface-muted, var(--md-sys-color-surface-container-low) );--pfx-form-shell-surface: color-mix( in srgb, var(--pfx-editorial-form-surface) 36%, transparent );--pfx-form-section-divider: color-mix( in srgb, var(--pfx-editorial-form-border) 68%, transparent );--pfx-form-footer-surface: color-mix( in srgb, var(--pfx-editorial-form-surface) 70%, var(--pfx-editorial-form-surface-muted) 30% );--pfx-form-footer-border: color-mix( in srgb, var(--pfx-editorial-form-border) 76%, transparent );--pfx-form-shell-padding: clamp(.9rem, 1.4vw, 1.2rem)}.form-config-controls{position:relative;top:auto;margin:0;display:flex;align-items:center;gap:.35rem;z-index:60;background:color-mix(in srgb,var(--pfx-form-shell-surface) 88%,var(--md-sys-color-surface) 12%);padding:8px var(--pfx-form-shell-padding);border:1px solid var(--pfx-form-footer-border);border-bottom-color:color-mix(in srgb,var(--pfx-form-footer-border) 72%,transparent);border-radius:var(--pfx-editorial-form-radius) var(--pfx-editorial-form-radius) 0 0;-webkit-backdrop-filter:blur(12px);backdrop-filter:blur(12px);box-shadow:none;min-width:0;justify-content:flex-end;pointer-events:none;opacity:.96;transition:opacity .16s ease,border-color .16s ease}.form-config-controls>*{pointer-events:auto}.form-config-controls:hover,.form-config-controls:focus-within{opacity:1;border-color:color-mix(in srgb,var(--md-sys-color-primary) 26%,var(--md-sys-color-outline-variant) 74%)}.form-config-controls .praxis-icon-button{color:var(--md-sys-color-on-surface-variant)}.form-config-controls .praxis-icon-button:hover{color:var(--md-sys-color-primary)}.ai-floating-assistant{position:sticky;right:0;bottom:12px;margin-top:14px;margin-left:auto;width:fit-content;z-index:70;pointer-events:none}.ai-floating-assistant button{pointer-events:auto;display:inline-flex}.ai-floating-assistant .ai-trigger-btn{box-shadow:0 12px 28px #0f172a24}.config-button{color:var(--md-sys-color-primary)}.form-loading{display:flex;flex-direction:column;align-items:stretch;justify-content:center;padding:1.25rem;text-align:left;color:var(--md-sys-color-on-surface);gap:1rem;min-height:220px;border:1px solid color-mix(in srgb,var(--md-sys-color-primary) 14%,var(--md-sys-color-outline-variant) 86%);border-radius:8px;background:linear-gradient(135deg,color-mix(in srgb,var(--md-sys-color-primary) 8%,transparent),transparent 42%),color-mix(in srgb,var(--md-sys-color-surface-container-low) 78%,var(--md-sys-color-surface) 22%);box-shadow:0 12px 28px #0f172a14}.entity-read-region{position:relative;min-width:0}.entity-read-feedback{position:absolute;inset:0;display:flex;flex-direction:column;align-items:center;justify-content:flex-start;gap:1rem;padding:2rem 1rem;box-sizing:border-box;text-align:center;color:var(--md-sys-color-on-surface)}.entity-read-feedback p{margin:0;max-width:40ch}.form-loading-header{display:flex;align-items:center;gap:.85rem}.form-loading-copy{min-width:0}.form-loading p{margin:0}.form-loading-title{font-weight:700;color:var(--md-sys-color-on-surface)}.form-loading-subtitle{margin-top:.2rem;font-size:.875rem;color:var(--md-sys-color-on-surface-variant)}.form-loading-skeleton{display:grid;gap:.7rem}.form-loading-line,.form-loading-field{display:block;overflow:hidden;position:relative;border-radius:6px;background:color-mix(in srgb,var(--md-sys-color-surface-container-high) 74%,var(--md-sys-color-primary) 6%)}.form-loading-line:after,.form-loading-field:after{content:\"\";position:absolute;inset:0;transform:translate(-100%);background:linear-gradient(90deg,transparent,color-mix(in srgb,var(--md-sys-color-primary) 16%,white 18%),transparent);animation:form-loading-shimmer 1.4s ease-in-out infinite}.form-loading-line{height:12px}.form-loading-line-title{width:min(42%,240px)}.form-loading-line-short{width:min(64%,360px)}.form-loading-field{height:44px}.form-loading-field-wide{height:72px}@keyframes form-loading-shimmer{to{transform:translate(100%)}}@media(prefers-reduced-motion:reduce){.form-loading-line:after,.form-loading-field:after{animation:none;transform:none;opacity:.28}}.form-error{display:flex;flex-direction:column;align-items:center;justify-content:center;padding:3rem;text-align:center;color:var(--md-sys-color-error);gap:1rem;border:1px solid var(--md-sys-color-error);border-radius:8px;background-color:var(--md-sys-color-error-container);margin:1rem;box-shadow:0 12px 30px #7f1d1d1f}.form-error h3{margin:0;color:var(--md-sys-color-on-error-container)}.form-error p{margin:0;color:var(--md-sys-color-on-error-container);opacity:.8}.form-error button{margin-top:.5rem}.pfx-form-info-banner{margin-bottom:14px;padding:12px 14px;border-radius:16px;border:1px solid color-mix(in srgb,var(--md-sys-color-primary) 18%,var(--md-sys-color-outline-variant) 82%);background:color-mix(in srgb,var(--md-sys-color-primary-container) 24%,var(--md-sys-color-surface) 76%);color:var(--md-sys-color-on-surface);display:flex;align-items:flex-start;justify-content:space-between;gap:14px}.pfx-form-info-banner .text{font-size:.92rem;line-height:1.5;font-weight:600}.pfx-form-info-banner .actions{display:flex;flex-wrap:wrap;justify-content:flex-end;gap:8px}.praxis-dynamic-form{display:flex;flex-direction:column;max-width:100%;min-width:0;transition:all .3s ease;position:relative;font-family:inherit;font-size:inherit;color:inherit;--pfx-editorial-form-surface: var( --pfx-form-section-surface, var(--md-sys-color-surface-container) );--pfx-editorial-form-surface-muted: var( --pdx-color-surface-muted, var(--md-sys-color-surface-container-low) );--pfx-editorial-form-border: var( --pfx-form-stroke, var(--pdx-color-border-subtle, var(--md-sys-color-outline-variant)) );--pfx-editorial-form-text: var( --pdx-color-text-primary, var(--md-sys-color-on-surface) );--pfx-editorial-form-text-muted: var( --pdx-color-text-secondary, var(--md-sys-color-on-surface-variant) );--pfx-editorial-form-field-surface: color-mix( in srgb, var(--pfx-editorial-form-surface-muted) 76%, var(--pfx-editorial-form-surface) 24% );--pfx-editorial-form-field-outline: color-mix( in srgb, var(--pfx-editorial-form-border) 88%, transparent );--pfx-editorial-form-accent: var( --pdx-color-primary, var(--md-sys-color-primary) );--pfx-editorial-form-accent-text: var(--md-sys-color-on-primary);--pfx-editorial-form-radius: var(--pfx-form-section-radius, 8px);--pfx-editorial-form-field-radius: var(--pfx-form-field-radius, 4px);--pfx-editorial-form-border-width: 1px;--pfx-editorial-form-field-border-width: 1px;--pfx-editorial-form-shadow: none;--pfx-form-shell-surface: color-mix( in srgb, var(--pfx-editorial-form-surface) 36%, transparent );--pfx-form-section-surface-flat: color-mix( in srgb, var(--pfx-editorial-form-surface) 78%, var(--pfx-editorial-form-surface-muted) 22% );--pfx-form-section-divider: color-mix( in srgb, var(--pfx-editorial-form-border) 68%, transparent );--pfx-form-label-strong: color-mix( in srgb, var(--pfx-editorial-form-text) 96%, white 4% );--pfx-form-label-muted: color-mix( in srgb, var(--pfx-editorial-form-text-muted) 92%, var(--pfx-editorial-form-text) 8% );--pfx-form-field-surface-rest: color-mix( in srgb, var(--pfx-editorial-form-field-surface) 82%, var(--pfx-editorial-form-surface) 18% );--pfx-form-field-surface-focus: color-mix( in srgb, var(--pfx-editorial-form-accent) 4%, var(--pfx-form-field-surface-rest) 96% );--pfx-form-field-min-height: 48px;--pfx-form-section-padding: clamp(1.1rem, 1.8vw, 1.5rem);--pfx-form-section-gap: 22px;--pdx-presentation-label-size: var(--pfx-pres-compact-label-size, .78rem);--pdx-presentation-value-size: var(--pfx-pres-compact-value-size, 1rem);--pdx-presentation-icon-size: var(--pfx-pres-icon-size, 18px);--pdx-presentation-row-gap: var(--pfx-pres-row-gap, .5rem);--pdx-presentation-column-gap: var(--pfx-pres-column-gap, .5rem);--pdx-presentation-section-gap: var(--pfx-pres-section-gap, .75rem);--pdx-presentation-label-width: var(--pfx-pres-label-width, 220px);--pdx-presentation-flag-height: var(--pfx-pres-boolean-min-height, 22px);--pdx-presentation-flag-radius: var(--pfx-pres-boolean-radius, 999px);--pdx-presentation-flag-padding: var(--pfx-pres-boolean-padding, 0 8px);--pdx-presentation-flag-active-color: var( --pfx-pres-boolean-active-color, var(--md-sys-color-primary) );--pdx-presentation-flag-active-bg: var( --pfx-pres-boolean-active-bg, color-mix(in srgb, var(--md-sys-color-primary) 14%, transparent) );--pdx-presentation-flag-inactive-color: var( --pfx-pres-boolean-inactive-color, var(--md-sys-color-on-surface-variant) );--pdx-presentation-flag-inactive-bg: var( --pfx-pres-boolean-inactive-bg, color-mix(in srgb, var(--md-sys-color-outline-variant) 34%, transparent) );--pfx-form-footer-surface: color-mix( in srgb, var(--pfx-editorial-form-surface) 70%, var(--pfx-editorial-form-surface-muted) 30% );--pfx-form-footer-border: color-mix( in srgb, var(--pfx-editorial-form-border) 76%, transparent )}.praxis-dynamic-form.canvas-mode-enabled{border:1px solid var(--pfx-form-footer-border);border-radius:var(--pfx-editorial-form-radius);background:linear-gradient(180deg,color-mix(in srgb,var(--pfx-form-shell-surface) 86%,transparent),color-mix(in srgb,var(--pfx-editorial-form-surface-muted) 42%,transparent));overflow:visible}.form-config-controls+.praxis-dynamic-form.canvas-mode-enabled{border-top:0;border-top-left-radius:0;border-top-right-radius:0}.praxis-dynamic-form.canvas-mode-enabled>.section-drop-wrapper,.praxis-dynamic-form.canvas-mode-enabled>.form-editorial-blocks{margin-inline:var(--pfx-form-shell-padding)}.praxis-dynamic-form.canvas-mode-enabled>.section-drop-wrapper:first-of-type,.praxis-dynamic-form.canvas-mode-enabled>.form-editorial-blocks:first-child{margin-top:var(--pfx-form-shell-padding)}.praxis-dynamic-form.canvas-mode-enabled>praxis-form-actions[data-actions-placement=afterSections]{display:block;margin-top:var(--pfx-form-shell-padding)}.praxis-dynamic-form.editorial-visual-context{--_pfx-editorial-host-text: var( --editorial-text-primary, var(--foreground, var(--mat-sys-on-surface, #1d1b20)) );--_pfx-editorial-host-text-muted: var( --editorial-text-secondary, var( --muted-foreground, color-mix(in srgb, var(--_pfx-editorial-host-text) 64%, transparent) ) );--_pfx-editorial-host-surface: var( --editorial-surface-primary, var(--card, var(--mat-sys-surface-container, #ffffff)) );--_pfx-editorial-host-surface-muted: var( --editorial-surface-secondary, var(--surface-dim, var(--muted, var(--mat-sys-surface-container-low, #f7f2fa))) );--_pfx-editorial-host-border: var( --editorial-border-color, var(--border, var(--mat-sys-outline-variant, #cac4d0)) );--_pfx-editorial-host-accent: var( --editorial-cta-primary, var(--editorial-accent, var(--primary, var(--mat-sys-primary, #6750a4))) );--_pfx-editorial-host-accent-text: var( --editorial-cta-primary-text, var( --editorial-accent-contrast, var(--primary-foreground, var(--mat-sys-on-primary, #ffffff)) ) );--_pfx-editorial-host-accent-container: var( --primary-container, color-mix(in srgb, var(--_pfx-editorial-host-accent) 16%, var(--_pfx-editorial-host-surface) 84%) );--_pfx-editorial-host-accent-container-text: var( --primary-container-fg, var(--_pfx-editorial-host-accent) );font-family:var(--editorial-body-font-family, inherit);font-size:var(--editorial-body-size, 1rem);color:var(--_pfx-editorial-host-text);--pfx-editorial-form-surface: var( --editorial-surface-primary, var(--pfx-form-section-surface, var(--_pfx-editorial-host-surface)) );--pfx-editorial-form-surface-muted: var( --editorial-surface-secondary, var(--_pfx-editorial-host-surface-muted) );--pfx-editorial-form-border: var( --editorial-border-color, var(--pfx-form-stroke, var(--_pfx-editorial-host-border)) );--pfx-editorial-form-text: var( --editorial-text-primary, var(--_pfx-editorial-host-text) );--pfx-editorial-form-text-muted: var( --editorial-text-secondary, color-mix( in srgb, var(--_pfx-editorial-host-text-muted) 86%, var(--_pfx-editorial-host-text) 14% ) );--pfx-editorial-form-accent: var( --editorial-cta-primary, var(--editorial-accent, var(--_pfx-editorial-host-accent)) );--pfx-editorial-form-accent-text: var( --editorial-cta-primary-text, var(--editorial-accent-contrast, var(--_pfx-editorial-host-accent-text)) );--pfx-editorial-form-accent-container: var(--_pfx-editorial-host-accent-container);--pfx-editorial-form-accent-container-text: var(--_pfx-editorial-host-accent-container-text);--pfx-editorial-form-radius: var(--editorial-card-radius, 18px);--pfx-editorial-form-field-radius: var( --editorial-field-radius, var(--editorial-card-radius, 14px) );--pfx-editorial-form-border-width: var(--editorial-card-border-width, 1px);--pfx-editorial-form-field-border-width: var(--editorial-field-border-width, 1px);--pfx-editorial-form-shadow: var(--editorial-card-shadow, none);--md-sys-color-surface: var( --pfx-editorial-form-surface, var(--md-sys-color-surface) );--md-sys-color-surface-container: var( --pfx-editorial-form-surface, var(--md-sys-color-surface-container) );--md-sys-color-surface-container-low: var( --pfx-editorial-form-surface-muted, var(--md-sys-color-surface-container-low) );--md-sys-color-surface-variant: var( --pfx-editorial-form-field-surface, var(--md-sys-color-surface-variant) );--md-sys-color-outline: var( --pfx-editorial-form-field-outline, var(--md-sys-color-outline) );--md-sys-color-outline-variant: var( --pfx-editorial-form-border, var(--md-sys-color-outline-variant) );--md-sys-color-on-surface: var( --editorial-text-primary, inherit );--md-sys-color-on-surface-variant: var( --editorial-text-secondary, inherit );--md-sys-color-primary: var( --pfx-editorial-form-accent, var(--md-sys-color-primary) );--md-sys-color-primary-container: var( --pfx-editorial-form-accent-container, var(--md-sys-color-primary-container) );--md-sys-color-on-primary-container: var( --pfx-editorial-form-accent-container-text, var(--md-sys-color-on-primary-container) );--md-sys-color-on-primary: var( --pfx-editorial-form-accent-text, var(--md-sys-color-on-primary) );--md-sys-color-on-surface-rgb: var( --editorial-text-primary-rgb, inherit );--mat-sys-on-surface: var( --editorial-text-primary, inherit );--mat-sys-on-surface-variant: var( --editorial-text-secondary, inherit );--mat-sys-on-surface-rgb: var( --editorial-text-primary-rgb, inherit );color:inherit;color-scheme:light}.praxis-dynamic-form.presentation-mode .form-row,.praxis-dynamic-form.readonly-mode .form-row{gap:var(--pdx-presentation-column-gap);margin-bottom:var(--pdx-presentation-row-gap)}.praxis-dynamic-form.presentation-mode{--pfx-pres-on-surface: var( --pdx-color-text-primary, var(--pfx-editorial-form-text, var(--pfx-form-label-strong, currentColor)) );--pfx-pres-on-surface-variant: var( --pdx-color-text-secondary, var( --pfx-editorial-form-text-muted, var( --pfx-form-label-muted, color-mix(in srgb, var(--pfx-pres-on-surface) 78%, transparent) ) ) )}.praxis-dynamic-form.presentation-mode .form-section,.praxis-dynamic-form.readonly-mode .form-section{padding:var(--pdx-presentation-section-gap) .875rem}.praxis-dynamic-form.pres-compact .form-row{gap:var(--pdx-presentation-column-gap, .35rem);margin-bottom:var(--pdx-presentation-row-gap, .35rem)}.praxis-dynamic-form.pres-compact .form-section{padding:var(--pdx-presentation-section-gap, .5rem) .75rem}.praxis-dynamic-form.pres-label-left .praxis-presentation{display:grid;grid-template-columns:minmax(0,var(--pfx-presentation-label-w, var(--pdx-presentation-label-width))) minmax(0,1fr);align-items:baseline;column-gap:var(--pdx-presentation-column-gap, 10px)}.praxis-dynamic-form.pres-label-left .praxis-presentation__label{text-align:right;margin-bottom:0}@media(max-width:480px){.praxis-dynamic-form.pres-label-left .praxis-presentation{grid-template-columns:minmax(0,1fr);row-gap:4px}.praxis-dynamic-form.pres-label-left .praxis-presentation__label{text-align:start}}.praxis-dynamic-form.praxis-dynamic-form--corporate-dossier .form-section:not(.section-appearance-plain),.praxis-dynamic-form .form-section.form-section--corporate-dossier:not(.section-appearance-plain),.praxis-dynamic-form .form-section[data-presentation-preset=corporate-dossier]:not(.section-appearance-plain){background:var(--md-sys-color-surface-container-low, #f8f9fa);border:1px solid var(--md-sys-color-outline-variant, #e0e2ec);border-radius:16px;padding:16px 20px;box-shadow:0 1px 3px #0000000a}.praxis-dynamic-form.praxis-dynamic-form--corporate-dossier .form-section .section-heading,.praxis-dynamic-form .form-section.form-section--corporate-dossier .section-heading,.praxis-dynamic-form .form-section[data-presentation-preset=corporate-dossier] .section-heading{margin-bottom:12px;padding-bottom:8px;border-bottom:1px solid var(--md-sys-color-outline-variant, #e0e2ec)}.praxis-dynamic-form.praxis-dynamic-form--corporate-dossier .form-section .section-title,.praxis-dynamic-form .form-section.form-section--corporate-dossier .section-title,.praxis-dynamic-form .form-section[data-presentation-preset=corporate-dossier] .section-title{font-size:.88rem;font-weight:700;letter-spacing:.05em;text-transform:uppercase;color:var(--md-sys-color-primary, #005ac1)}:host ::ng-deep .praxis-dynamic-form--corporate-dossier .praxis-presentation,:host ::ng-deep .form-section--corporate-dossier .praxis-presentation,:host ::ng-deep [data-presentation-preset=corporate-dossier] .praxis-presentation{padding:8px 0;border-bottom:1px dashed var(--md-sys-color-outline-variant, rgba(0, 0, 0, .08))}:host ::ng-deep .praxis-dynamic-form--corporate-dossier .form-row:last-child .praxis-presentation,:host ::ng-deep .praxis-dynamic-form--corporate-dossier .praxis-presentation:last-child,:host ::ng-deep .form-section--corporate-dossier .form-row:last-child .praxis-presentation,:host ::ng-deep .form-section--corporate-dossier .praxis-presentation:last-child,:host ::ng-deep [data-presentation-preset=corporate-dossier] .form-row:last-child .praxis-presentation,:host ::ng-deep [data-presentation-preset=corporate-dossier] .praxis-presentation:last-child{border-bottom:none}:host ::ng-deep .praxis-dynamic-form--corporate-dossier .praxis-presentation__label,:host ::ng-deep .form-section--corporate-dossier .praxis-presentation__label,:host ::ng-deep [data-presentation-preset=corporate-dossier] .praxis-presentation__label{font-size:.74rem;font-weight:600;text-transform:uppercase;letter-spacing:.05em;color:var(--md-sys-color-on-surface-variant, #44474f);margin-bottom:3px}:host ::ng-deep .praxis-dynamic-form--corporate-dossier .praxis-presentation__value,:host ::ng-deep .form-section--corporate-dossier .praxis-presentation__value,:host ::ng-deep [data-presentation-preset=corporate-dossier] .praxis-presentation__value{font-size:.95rem;font-weight:600;color:var(--md-sys-color-on-surface, #1a1c1e);line-height:1.4}.praxis-dynamic-form.praxis-dynamic-form--editorial-card .form-section:not(.section-appearance-plain),.praxis-dynamic-form .form-section.form-section--editorial-card:not(.section-appearance-plain),.praxis-dynamic-form .form-section[data-presentation-preset=editorial-card]:not(.section-appearance-plain){background:var(--pfx-editorial-form-surface, var(--md-sys-color-surface-container-low, #ffffff));border:1px solid var(--pfx-editorial-form-border, var(--md-sys-color-outline-variant, #e0e2ec));border-radius:20px;padding:24px;box-shadow:0 2px 8px #0000000d}.praxis-dynamic-form.praxis-dynamic-form--editorial-card .form-section .section-heading,.praxis-dynamic-form .form-section.form-section--editorial-card .section-heading,.praxis-dynamic-form .form-section[data-presentation-preset=editorial-card] .section-heading{margin-bottom:16px;padding-bottom:10px;border-bottom:1px solid color-mix(in srgb,var(--md-sys-color-outline-variant, #e0e2ec) 40%,transparent)}.praxis-dynamic-form.praxis-dynamic-form--editorial-card .form-section .section-title,.praxis-dynamic-form .form-section.form-section--editorial-card .section-title,.praxis-dynamic-form .form-section[data-presentation-preset=editorial-card] .section-title{font-size:1.15rem;font-weight:700;color:var(--pfx-editorial-form-accent, var(--md-sys-color-primary, #005ac1))}:host ::ng-deep .praxis-dynamic-form--editorial-card .praxis-presentation,:host ::ng-deep .form-section--editorial-card .praxis-presentation,:host ::ng-deep [data-presentation-preset=editorial-card] .praxis-presentation{padding:10px 0;border-bottom:1px solid color-mix(in srgb,var(--md-sys-color-outline-variant, #e0e2ec) 35%,transparent)}:host ::ng-deep .praxis-dynamic-form--editorial-card .form-row:last-child .praxis-presentation,:host ::ng-deep .praxis-dynamic-form--editorial-card .praxis-presentation:last-child,:host ::ng-deep .form-section--editorial-card .form-row:last-child .praxis-presentation,:host ::ng-deep .form-section--editorial-card .praxis-presentation:last-child,:host ::ng-deep [data-presentation-preset=editorial-card] .form-row:last-child .praxis-presentation,:host ::ng-deep [data-presentation-preset=editorial-card] .praxis-presentation:last-child{border-bottom:none}:host ::ng-deep .praxis-dynamic-form--editorial-card .praxis-presentation__label,:host ::ng-deep .form-section--editorial-card .praxis-presentation__label,:host ::ng-deep [data-presentation-preset=editorial-card] .praxis-presentation__label{font-size:.8rem;font-weight:500;color:var(--pfx-editorial-form-text-muted, var(--md-sys-color-on-surface-variant, #44474f));margin-bottom:4px}:host ::ng-deep .praxis-dynamic-form--editorial-card .praxis-presentation__value,:host ::ng-deep .form-section--editorial-card .praxis-presentation__value,:host ::ng-deep [data-presentation-preset=editorial-card] .praxis-presentation__value{font-size:1rem;font-weight:600;color:var(--pfx-editorial-form-text, var(--md-sys-color-on-surface, #1a1c1e));line-height:1.5}.praxis-dynamic-form.praxis-dynamic-form--compact-presentation .form-section:not(.section-appearance-plain),.praxis-dynamic-form .form-section.form-section--compact-presentation:not(.section-appearance-plain),.praxis-dynamic-form .form-section[data-presentation-preset=compact-presentation]:not(.section-appearance-plain){background:transparent;border:1px solid color-mix(in srgb,var(--md-sys-color-outline-variant, #e0e2ec) 50%,transparent);border-radius:8px;padding:10px 14px;box-shadow:none}.praxis-dynamic-form.praxis-dynamic-form--compact-presentation .form-section .section-heading,.praxis-dynamic-form .form-section.form-section--compact-presentation .section-heading,.praxis-dynamic-form .form-section[data-presentation-preset=compact-presentation] .section-heading{margin-bottom:8px;padding-bottom:4px;border-bottom:1px solid color-mix(in srgb,var(--md-sys-color-outline-variant, #e0e2ec) 25%,transparent)}.praxis-dynamic-form.praxis-dynamic-form--compact-presentation .form-section .section-title,.praxis-dynamic-form .form-section.form-section--compact-presentation .section-title,.praxis-dynamic-form .form-section[data-presentation-preset=compact-presentation] .section-title{font-size:.82rem;font-weight:700;letter-spacing:.03em;text-transform:uppercase;color:var(--md-sys-color-on-surface-variant, #44474f)}:host ::ng-deep .praxis-dynamic-form--compact-presentation .praxis-presentation,:host ::ng-deep .form-section--compact-presentation .praxis-presentation,:host ::ng-deep [data-presentation-preset=compact-presentation] .praxis-presentation{padding:4px 0;border-bottom:none}:host ::ng-deep .praxis-dynamic-form--compact-presentation .praxis-presentation__label,:host ::ng-deep .form-section--compact-presentation .praxis-presentation__label,:host ::ng-deep [data-presentation-preset=compact-presentation] .praxis-presentation__label{font-size:.72rem;font-weight:600;color:var(--md-sys-color-on-surface-variant, #44474f);margin-bottom:2px}:host ::ng-deep .praxis-dynamic-form--compact-presentation .praxis-presentation__value,:host ::ng-deep .form-section--compact-presentation .praxis-presentation__value,:host ::ng-deep [data-presentation-preset=compact-presentation] .praxis-presentation__value{font-size:.88rem;font-weight:500;color:var(--md-sys-color-on-surface, #1a1c1e);line-height:1.35}:host-context(.mdc-theme-dark) .praxis-dynamic-form.praxis-dynamic-form--corporate-dossier .form-section:not(.section-appearance-plain),:host-context(.mdc-theme-dark) .praxis-dynamic-form .form-section.form-section--corporate-dossier:not(.section-appearance-plain),:host-context(.mdc-theme-dark) .praxis-dynamic-form .form-section[data-presentation-preset=corporate-dossier]:not(.section-appearance-plain),:host-context(.theme-dark) .praxis-dynamic-form.praxis-dynamic-form--corporate-dossier .form-section:not(.section-appearance-plain),:host-context(.theme-dark) .praxis-dynamic-form .form-section.form-section--corporate-dossier:not(.section-appearance-plain),:host-context(.theme-dark) .praxis-dynamic-form .form-section[data-presentation-preset=corporate-dossier]:not(.section-appearance-plain){background:var(--md-sys-color-surface-container-low);border-color:color-mix(in srgb,var(--md-sys-color-outline-variant) 70%,transparent);box-shadow:0 2px 8px #0000004d}:host-context(.mdc-theme-dark) .praxis-dynamic-form.praxis-dynamic-form--editorial-card .form-section:not(.section-appearance-plain),:host-context(.mdc-theme-dark) .praxis-dynamic-form .form-section.form-section--editorial-card:not(.section-appearance-plain),:host-context(.mdc-theme-dark) .praxis-dynamic-form .form-section[data-presentation-preset=editorial-card]:not(.section-appearance-plain),:host-context(.theme-dark) .praxis-dynamic-form.praxis-dynamic-form--editorial-card .form-section:not(.section-appearance-plain),:host-context(.theme-dark) .praxis-dynamic-form .form-section.form-section--editorial-card:not(.section-appearance-plain),:host-context(.theme-dark) .praxis-dynamic-form .form-section[data-presentation-preset=editorial-card]:not(.section-appearance-plain){background:var(--pfx-editorial-form-surface, var(--md-sys-color-surface-container-low));border-color:color-mix(in srgb,var(--md-sys-color-outline-variant) 70%,transparent);box-shadow:0 4px 16px #0006}.form-section{border:1px solid var(--pfx-form-section-divider);border-radius:var(--pfx-editorial-form-radius);padding:var(--pfx-form-section-padding);max-width:100%;min-width:0;background:var(--pfx-form-section-surface-flat);box-shadow:none;transition:all .2s ease;position:relative}.praxis-dynamic-form.editorial-visual-context .form-section:not(.section-appearance-plain){border:var(--pfx-editorial-form-border-width) solid var(--pfx-editorial-form-border)!important;background:var(--pfx-editorial-form-surface)!important;color:var(--pfx-editorial-form-text);box-shadow:var(--editorial-card-shadow, none)}.praxis-dynamic-form.editorial-visual-context .form-section.section-appearance-step{background-color:var(--pfx-editorial-form-surface)!important;background-image:linear-gradient(180deg,color-mix(in srgb,var(--editorial-accent, var(--md-sys-color-primary)) 6%,transparent) 0%,transparent 132px)!important;background-repeat:no-repeat!important}.section-drop-wrapper>.form-section{margin-bottom:var(--pfx-section-gap, 20px)}.section-drop-wrapper:last-of-type>.form-section{margin-bottom:0}.praxis-dynamic-form>praxis-form-actions[data-actions-placement=afterSections]{margin-top:var(--pfx-actions-gap-top, var(--pfx-section-gap, 20px))}.section-title{margin:0 0 var(--pfx-section-title-mb, 12px) 0;font-family:var(--editorial-title-font-family, var(--editorial-body-font-family, inherit));font-size:var(--editorial-step-title-size, 1.12rem);font-weight:700;color:var(--pfx-form-label-strong)}.section-heading{position:relative;display:flex;align-items:flex-start;gap:12px;margin-bottom:18px;padding-bottom:var(--pfx-form-section-heading-divider-gap, 18px)}.section-heading:after{content:\"\";position:absolute;right:0;bottom:0;left:0;height:2px;pointer-events:none;background:linear-gradient(90deg,transparent 0%,color-mix(in srgb,var(--pfx-form-section-divider) 18%,transparent) 8%,var(--pfx-form-section-divider) 46%,var(--pfx-form-section-divider) 54%,color-mix(in srgb,var(--pfx-form-section-divider) 18%,transparent) 92%,transparent 100%);border-radius:999px;-webkit-mask-image:linear-gradient(90deg,transparent 0%,black 18%,black 82%,transparent 100%);mask-image:linear-gradient(90deg,transparent 0%,black 18%,black 82%,transparent 100%)}.section-heading.title-only{padding-bottom:var(--pfx-form-section-heading-title-only-divider-gap, 10px)}:host(.pfx-form-section-divider-inline-title) .section-heading.title-only{padding-bottom:var(--pfx-form-section-heading-title-only-inline-divider-gap, 0)}:host(.pfx-form-section-divider-inline-title) .section-heading.title-only:after{display:none}.section-heading.align-center{flex-direction:column;align-items:center;text-align:center}.section-heading.align-center .section-heading-text{display:grid;justify-items:center}.section-step-label{display:inline-flex;align-items:center;min-height:24px;padding:0 10px;margin:0 0 8px;border-radius:999px;background:color-mix(in srgb,var(--pfx-editorial-form-accent) 10%,transparent);color:color-mix(in srgb,var(--pfx-editorial-form-accent) 84%,var(--pfx-form-label-strong) 16%);font-size:.72rem;font-weight:800;font-family:var(--editorial-title-font-family, var(--editorial-body-font-family, inherit));letter-spacing:.08em;text-transform:uppercase}.section-heading-text{flex:1 1 auto;min-width:0}.section-heading-actions{display:inline-flex;align-items:center;align-self:flex-start;flex-wrap:wrap;gap:4px;margin-left:auto}.section-heading-actions.align-center{align-self:center;margin-left:0}.section-heading-action-btn{color:var(--pfx-form-label-muted)}.section-heading-action-btn.tone-primary{color:var(--md-sys-color-primary)}.section-heading-action-btn.tone-accent,.section-heading-action-btn.tone-secondary{color:var(--md-sys-color-tertiary)}.section-heading-action-btn.tone-warn,.section-heading-action-btn.tone-danger,.section-heading-action-btn.tone-error{color:var(--md-sys-color-error)}.section-heading-action-btn .mat-mdc-progress-spinner,.section-heading-action-btn mat-progress-spinner{--mdc-circular-progress-active-indicator-color: currentColor}.section-heading-action-btn.loading{opacity:.72;pointer-events:none}.section-heading-action-sr-only{position:absolute;width:1px;height:1px;padding:0;margin:-1px;overflow:hidden;clip:rect(0,0,0,0);white-space:nowrap;border:0}.section-collapse-btn{margin-left:4px;color:var(--pfx-form-label-muted)}.section-title.title-large{font:var(--mdc-typography-title-large, 500 22px/28px system-ui)}.section-title.title-medium{font:var(--mdc-typography-title-medium, 500 16px/24px system-ui)}.section-title.title-small{font:var(--mdc-typography-title-small, 500 14px/20px system-ui)}.section-title.headline-small{font:var(--mdc-typography-headline-small, 600 24px/32px system-ui)}.section-title.title-large,.section-title.title-medium,.section-title.title-small,.section-title.headline-small{font-family:var(--editorial-title-font-family, var(--editorial-body-font-family, inherit));font-weight:var(--editorial-title-weight, 600)}.section-description{margin:0;font-family:var(--editorial-body-font-family, inherit);font-size:.93rem;color:var(--pfx-form-label-muted);line-height:1.6}.section-description.body-large{font:var(--mdc-typography-body-large, 400 16px/24px system-ui)}.section-description.body-medium{font:var(--mdc-typography-body-medium, 400 14px/20px system-ui)}.section-description.body-small{font:var(--mdc-typography-body-small, 400 12px/16px system-ui)}.section-description.body-large,.section-description.body-medium,.section-description.body-small{font-family:var(--editorial-body-font-family, inherit);font-weight:var(--editorial-body-weight, 400)}.section-title.align-center,.section-description.align-center,.section-step-label.align-center{text-align:center}.praxis-dynamic-form .form-section.section-appearance-plain{border-color:transparent;border-width:0;border-radius:0;padding:0;background:transparent;box-shadow:none}.praxis-dynamic-form .form-section.section-appearance-plain.section-has-divider{padding-bottom:16px;border-bottom:1px solid var(--pfx-form-section-divider, var(--md-sys-color-outline-variant, #e0e2ec))}.praxis-dynamic-form .section-drop-wrapper:last-of-type>.form-section.section-appearance-plain.section-has-divider,.praxis-dynamic-form>.form-section.section-appearance-plain.section-has-divider:last-of-type{border-bottom:none;padding-bottom:0}.form-section.section-appearance-plain .section-heading{margin-bottom:14px}.form-section.section-appearance-step{border-radius:var(--pfx-editorial-form-radius);padding:var(--pfx-form-section-padding);background:var(--pfx-form-section-surface-flat);border-color:var(--pfx-form-section-divider);box-shadow:none}.praxis-dynamic-form.editorial-visual-context .form-section.section-appearance-step{border-radius:var(--editorial-card-radius, 20px);box-shadow:none}.form-section.section-appearance-step .section-heading{margin-bottom:22px;padding-bottom:var(--pfx-form-section-heading-divider-gap, 16px)}.form-section.section-appearance-step .section-heading.title-only{padding-bottom:var(--pfx-form-section-heading-title-only-divider-gap, 16px)}:host(.pfx-form-section-divider-inline-title) .form-section.section-appearance-step .section-heading.title-only{padding-bottom:var(--pfx-form-section-heading-title-only-inline-divider-gap, 0)}.form-section.section-appearance-step .section-title{font:var(--mdc-typography-title-large, 700 22px/28px system-ui);color:var(--pfx-form-label-strong);margin-bottom:8px}.form-section.section-appearance-step .section-description{color:var(--pfx-form-label-muted);max-width:60ch}.form-section.section-appearance-step .section-step-label{min-height:24px;padding:0 10px;margin-bottom:10px;box-shadow:none}.form-section.section-appearance-step .section-heading.align-center .section-description{max-width:52ch}.form-section.section-appearance-step .section-body{display:grid;gap:8px;padding-top:0}.form-section.section-appearance-step .form-row{margin-bottom:var(--pfx-field-gap, 1rem)}.form-section.section-appearance-step .form-column{gap:var(--pfx-field-gap, 12px)}.form-section .form-editorial-blocks{display:grid;gap:16px}.form-section .form-editorial-blocks[data-editorial-placement=beforeActions]{margin-top:24px;padding-top:18px;border-top:1px solid var(--pfx-form-section-divider)}.form-section.section-appearance-step .form-editorial-blocks[data-editorial-placement=beforeActions]{gap:18px}.form-section.section-appearance-step .form-editorial-blocks[data-editorial-placement=beforeActions]>*+*{margin-top:2px}.praxis-dynamic-form:not(.canvas-mode-enabled)>praxis-form-actions[data-actions-placement=afterSections]{margin-top:18px}.praxis-dynamic-form>.form-editorial-blocks[data-editorial-placement=after]{margin-top:6px}:host-context(.mdc-theme-dark) .form-section.section-appearance-step,:host-context(.theme-dark) .form-section.section-appearance-step{border-color:color-mix(in srgb,var(--pfx-editorial-form-border) 82%,transparent);box-shadow:none}:host-context(.mdc-theme-dark) .form-section.section-appearance-step .section-title,:host-context(.theme-dark) .form-section.section-appearance-step .section-title{color:color-mix(in srgb,var(--pfx-editorial-form-text) 96%,white)}:host-context(.mdc-theme-dark) .form-section.section-appearance-step .section-description,:host-context(.theme-dark) .form-section.section-appearance-step .section-description{color:color-mix(in srgb,var(--pfx-editorial-form-text-muted) 86%,var(--pfx-editorial-form-text) 14%)}:host-context(.mdc-theme-dark) .section-step-label,:host-context(.theme-dark) .section-step-label{background:color-mix(in srgb,var(--md-sys-color-primary-container) 54%,transparent);color:color-mix(in srgb,var(--md-sys-color-primary) 88%,white)}:host-context(.mdc-theme-dark) .form-section .form-editorial-blocks[data-editorial-placement=beforeActions],:host-context(.theme-dark) .form-section .form-editorial-blocks[data-editorial-placement=beforeActions]{border-top-color:color-mix(in srgb,var(--md-sys-color-outline-variant) 90%,transparent)}.inline-edit-btn{margin-left:6px;vertical-align:middle}.section-body.collapsed{border:1px dashed var(--md-sys-color-outline-variant);background:var(--md-sys-color-surface-container-low);border-radius:6px;padding:8px 10px}.section-collapsed-placeholder{display:flex;align-items:center;gap:8px;color:var(--md-sys-color-on-surface-variant);font-size:.95rem}.section-collapsed-placeholder mat-icon{font-size:20px;width:20px;height:20px}.form-row{display:flex;gap:1.1rem;margin-bottom:var(--pfx-field-gap, 1.1rem);max-width:100%;min-width:0;transition:all .2s ease;border-radius:6px;position:relative}.praxis-dynamic-form.pfx-mounting .form-row{opacity:0;transform:translateY(var(--pdx-form-mount-offset, 6px));animation:pdxFormMount var(--pdx-form-mount-duration, .16s) ease-out both;animation-delay:calc(var(--pfx-mount-index, 0) * var(--pdx-form-mount-stagger, 20ms))}@media(prefers-reduced-motion:reduce){.praxis-dynamic-form.pfx-mounting .form-row{animation:none;opacity:1;transform:none}}@keyframes pdxFormMount{to{opacity:1;transform:translateY(0)}}.praxis-dynamic-form .mat-mdc-form-field{width:100%;margin-bottom:var(--pfx-field-gap, 10px);font-family:inherit;--mdc-filled-text-field-container-color: var(--pfx-form-field-surface-rest);--mdc-filled-text-field-focus-active-indicator-color: var(--pfx-editorial-form-accent);--mdc-filled-text-field-active-indicator-color: var(--pfx-editorial-form-field-outline);--mdc-filled-text-field-hover-active-indicator-color: var(--pfx-editorial-form-accent);--mdc-filled-text-field-focus-label-text-color: var(--pfx-editorial-form-accent);--mdc-filled-text-field-label-text-color: var(--pfx-form-label-muted);--mdc-filled-text-field-input-text-color: var(--pfx-editorial-form-text);--mdc-filled-text-field-caret-color: var(--pfx-editorial-form-accent);--mdc-filled-text-field-input-text-placeholder-color: color-mix( in srgb, var(--pfx-editorial-form-text-muted) 82%, transparent );--mdc-outlined-text-field-outline-color: var(--pfx-editorial-form-field-outline);--mdc-outlined-text-field-hover-outline-color: var(--pfx-editorial-form-accent);--mdc-outlined-text-field-focus-outline-color: var(--pfx-editorial-form-accent);--mdc-outlined-text-field-focus-label-text-color: var(--pfx-editorial-form-accent);--mdc-outlined-text-field-label-text-color: var(--pfx-form-label-muted);--mdc-outlined-text-field-input-text-color: var(--pfx-editorial-form-text);--mdc-filled-text-field-container-shape: var(--pfx-editorial-form-field-radius);--mdc-outlined-text-field-container-shape: var(--pfx-editorial-form-field-radius);--mdc-filled-text-field-active-indicator-height: var(--pfx-editorial-form-field-border-width);--mdc-filled-text-field-focus-active-indicator-height: var(--pfx-editorial-form-field-border-width);--mdc-outlined-text-field-outline-width: var(--pfx-editorial-form-field-border-width);--mdc-outlined-text-field-focus-outline-width: var(--pfx-editorial-form-field-border-width);--mat-select-enabled-trigger-text-color: var(--pfx-editorial-form-text);--mat-select-enabled-arrow-color: var(--pfx-form-label-muted);--mat-form-field-enabled-select-arrow-color: var(--pfx-form-label-muted);--mat-form-field-focus-select-arrow-color: var(--pfx-editorial-form-accent);--mat-form-field-hover-state-layer-opacity: 0;--mat-form-field-focus-state-layer-opacity: 0}.praxis-dynamic-form.editorial-visual-context .mat-mdc-form-field{font-family:var(--editorial-body-font-family, inherit)}.praxis-dynamic-form .mat-mdc-text-field-wrapper,.praxis-dynamic-form .mdc-text-field{background:var(--pfx-form-field-surface-rest);border-radius:var(--pfx-editorial-form-field-radius);min-height:var(--pfx-form-field-min-height);transition:background-color .16s ease,box-shadow .16s ease,border-color .16s ease}.praxis-dynamic-form.editorial-visual-context .mat-mdc-text-field-wrapper,.praxis-dynamic-form.editorial-visual-context .mdc-text-field,.praxis-dynamic-form.editorial-visual-context .mdc-text-field--filled,.praxis-dynamic-form.editorial-visual-context .mdc-text-field--outlined{background-color:var(--pfx-form-field-surface-rest)!important;background:var(--pfx-form-field-surface-rest)!important}.praxis-dynamic-form .mat-mdc-form-field .mdc-floating-label,.praxis-dynamic-form .mat-mdc-form-field .mat-mdc-form-field-hint,.praxis-dynamic-form .mat-mdc-form-field .mat-mdc-form-field-error,.praxis-dynamic-form .mat-mdc-form-field .mat-mdc-form-field-required-marker,.praxis-dynamic-form .mat-mdc-form-field .mat-mdc-select-arrow,.praxis-dynamic-form .mat-mdc-form-field .mat-mdc-select-placeholder,.praxis-dynamic-form .mat-mdc-form-field .mat-mdc-form-field-icon-suffix,.praxis-dynamic-form .mat-mdc-form-field .mat-mdc-form-field-icon-prefix{color:var(--pfx-form-label-muted)}.praxis-dynamic-form .mat-mdc-input-element,.praxis-dynamic-form .mat-mdc-select-value-text,.praxis-dynamic-form .mat-mdc-form-field-infix,.praxis-dynamic-form .mat-mdc-select-min-line{color:var(--pfx-editorial-form-text)}.praxis-dynamic-form .mat-mdc-form-field:hover .mat-mdc-text-field-wrapper,.praxis-dynamic-form .mat-mdc-form-field:hover .mdc-text-field,.praxis-dynamic-form .mat-mdc-form-field.mat-focused .mat-mdc-text-field-wrapper,.praxis-dynamic-form .mat-mdc-form-field.mat-focused .mdc-text-field{background:var(--pfx-form-field-surface-focus)}.praxis-dynamic-form.editorial-visual-context .mat-mdc-input-element,.praxis-dynamic-form.editorial-visual-context .mat-mdc-select-value-text,.praxis-dynamic-form.editorial-visual-context .mat-mdc-form-field-infix,.praxis-dynamic-form.editorial-visual-context .mat-mdc-select-min-line,.praxis-dynamic-form.editorial-visual-context .mdc-text-field__input{color:var(--pfx-editorial-form-text)!important;-webkit-text-fill-color:var(--pfx-editorial-form-text)!important}.praxis-dynamic-form.editorial-visual-context .mat-mdc-form-field .mdc-floating-label,.praxis-dynamic-form.editorial-visual-context .mat-mdc-form-field .mat-mdc-form-field-hint,.praxis-dynamic-form.editorial-visual-context .mat-mdc-form-field .mat-mdc-form-field-error,.praxis-dynamic-form.editorial-visual-context .mat-mdc-form-field .mat-mdc-form-field-required-marker,.praxis-dynamic-form.editorial-visual-context .mat-mdc-form-field .mat-mdc-select-arrow,.praxis-dynamic-form.editorial-visual-context .mat-mdc-form-field .mat-mdc-select-placeholder,.praxis-dynamic-form.editorial-visual-context .mat-mdc-form-field .mat-mdc-form-field-icon-suffix,.praxis-dynamic-form.editorial-visual-context .mat-mdc-form-field .mat-mdc-form-field-icon-prefix{color:var(--pfx-editorial-form-text-muted)!important}.praxis-dynamic-form.editorial-visual-context .mat-mdc-floating-label,.praxis-dynamic-form.editorial-visual-context .mdc-floating-label,.praxis-dynamic-form.editorial-visual-context .mdc-text-field__input::placeholder{color:color-mix(in srgb,var(--pfx-editorial-form-text) 68%,transparent)!important}.praxis-dynamic-form.editorial-visual-context .mat-mdc-input-element::placeholder,.praxis-dynamic-form.editorial-visual-context textarea.mat-mdc-input-element::placeholder{color:color-mix(in srgb,var(--pfx-editorial-form-text) 58%,transparent)!important}.praxis-dynamic-form .mat-mdc-radio-button,.praxis-dynamic-form .mat-mdc-checkbox,.praxis-dynamic-form .mat-mdc-slide-toggle{--mdc-radio-selected-icon-color: var(--pfx-editorial-form-accent);--mdc-radio-selected-hover-icon-color: var(--pfx-editorial-form-accent);--mdc-radio-selected-focus-icon-color: var(--pfx-editorial-form-accent);--mdc-checkbox-selected-checkmark-color: var(--pfx-editorial-form-accent-text);--mdc-checkbox-selected-focus-icon-color: var(--pfx-editorial-form-accent);--mdc-checkbox-selected-hover-icon-color: var(--pfx-editorial-form-accent);--mdc-checkbox-selected-icon-color: var(--pfx-editorial-form-accent);--mdc-switch-selected-focus-state-layer-color: var(--pfx-editorial-form-accent);--mdc-switch-selected-handle-color: var(--pfx-editorial-form-accent);--mdc-switch-selected-track-color: color-mix(in srgb, var(--pfx-editorial-form-accent) 45%, #fff)}.praxis-dynamic-form [data-field-type=input],.praxis-dynamic-form [data-field-type=textarea],.praxis-dynamic-form [data-field-type=email],.praxis-dynamic-form [data-field-type=password],.praxis-dynamic-form [data-field-type=url],.praxis-dynamic-form [data-field-type=search],.praxis-dynamic-form [data-field-type=phone],.praxis-dynamic-form [data-field-type=numericTextBox],.praxis-dynamic-form [data-field-type=currency],.praxis-dynamic-form [data-field-type=cpfCnpj],.praxis-dynamic-form [data-field-type=date],.praxis-dynamic-form [data-field-type=dateInput],.praxis-dynamic-form [data-field-type=dateRange],.praxis-dynamic-form [data-field-type=dateTimeLocal],.praxis-dynamic-form [data-field-type=time],.praxis-dynamic-form [data-field-type=timePicker],.praxis-dynamic-form [data-field-type=timeRange],.praxis-dynamic-form [data-field-type=month],.praxis-dynamic-form [data-field-type=week],.praxis-dynamic-form [data-field-type=yearInput],.praxis-dynamic-form [data-field-type=select],.praxis-dynamic-form [data-field-type=multi-select],.praxis-dynamic-form [data-field-type=searchable-select],.praxis-dynamic-form [data-field-type=async-select],.praxis-dynamic-form [data-field-type=autocomplete],.praxis-dynamic-form [data-field-type=entityLookup],.praxis-dynamic-form [data-field-type=tree-select],.praxis-dynamic-form [data-field-type=multi-select-tree],.praxis-dynamic-form [data-field-type=priceRange],.praxis-dynamic-form [data-field-type=file-upload]{display:block;width:100%;min-width:0}.praxis-dynamic-form .mat-mdc-form-field-subscript-wrapper{min-height:var(--pfx-subscript-min-h, 22px)}.form-row:last-child{margin-bottom:0}.form-column{display:grid;grid-template-columns:minmax(0,1fr);align-content:start;gap:var(--pfx-field-gap, 10px);flex:1;max-width:100%;min-width:0;transition:all .2s ease;border-radius:4px;position:relative}.form-layout-rich-content{display:block;width:100%;max-width:100%;min-width:0;margin-bottom:var(--pfx-field-gap, 10px);color:var(--pfx-editorial-form-text-muted, var(--md-sys-color-on-surface-variant));font:var(--mdc-typography-body-medium, 400 14px/20px system-ui);overflow-wrap:anywhere}:host ::ng-deep .form-layout-rich-content .prx-rich-content-root{display:grid;gap:8px;min-width:0;max-width:100%}:host ::ng-deep .form-layout-rich-content .prx-rich-node{min-width:0;max-width:100%}:host ::ng-deep .form-layout-rich-content .prx-rich-text{color:inherit;line-height:20px}:host ::ng-deep .form-layout-rich-content .praxis-form-visual-block--note,:host ::ng-deep .form-layout-rich-content .praxis-rich-content-notice{border:1px solid color-mix(in srgb,var(--pfx-editorial-form-accent) 12%,var(--pfx-editorial-form-border) 88%);border-left:3px solid var(--pfx-editorial-form-accent);border-radius:8px;background:color-mix(in srgb,var(--pfx-editorial-form-accent-container) 12%,var(--pfx-editorial-form-surface-muted) 88%)}:host ::ng-deep .form-layout-rich-content .praxis-form-visual-block--note{display:grid;grid-template-columns:20px minmax(0,1fr);gap:10px;align-items:flex-start;padding:11px 12px}:host ::ng-deep .form-layout-rich-content .praxis-form-visual-block--note:before{content:\"info\";display:inline-flex;align-items:center;justify-content:center;width:20px;height:20px;color:var(--pfx-editorial-form-accent);font-family:Material Symbols Outlined;font-size:20px;font-weight:400;line-height:20px}:host ::ng-deep .form-layout-rich-content .praxis-form-visual-block--note .prx-rich-text{color:var(--pfx-editorial-form-text-muted)}:host ::ng-deep .form-layout-rich-content .praxis-rich-content-notice{padding:10px 12px;color:var(--pfx-editorial-form-text)}:host ::ng-deep .form-layout-rich-content .praxis-rich-content-notice .prx-rich-compose{align-items:flex-start;gap:10px}:host ::ng-deep .form-layout-rich-content .praxis-rich-content-notice .prx-rich-icon{color:var(--pfx-editorial-form-accent);font-size:20px;line-height:20px;margin-top:1px}:host ::ng-deep .form-layout-rich-content .praxis-rich-content-divider{display:grid;grid-template-columns:minmax(24px,1fr) auto minmax(24px,1fr);align-items:center;gap:10px;color:var(--pfx-editorial-form-text-muted);font:var(--mdc-typography-label-small, 600 12px/16px system-ui);text-transform:uppercase}:host ::ng-deep .form-layout-rich-content .praxis-rich-content-divider:before,:host ::ng-deep .form-layout-rich-content .praxis-rich-content-divider:after{content:\"\";height:1px;background:var(--pfx-editorial-form-border)}:host ::ng-deep .form-layout-rich-content .prx-rich-card{gap:6px;padding:12px 14px;border-color:var(--pfx-editorial-form-border);border-radius:8px;background:var(--pfx-editorial-form-surface-muted);color:var(--pfx-editorial-form-text);box-shadow:none}:host ::ng-deep .form-layout-rich-content .prx-rich-card-title{color:var(--pfx-editorial-form-text);font:var(--mdc-typography-title-small, 600 14px/20px system-ui)}:host ::ng-deep .form-layout-rich-content .prx-rich-card-subtitle,:host ::ng-deep .form-layout-rich-content .prx-rich-metric-caption{color:var(--pfx-editorial-form-text-muted)}:host ::ng-deep .form-layout-rich-content .prx-rich-card .prx-rich-text{color:var(--pfx-editorial-form-text-muted)}:host ::ng-deep .form-layout-rich-content .prx-rich-badge{background:var(--pfx-editorial-form-accent-container);color:var(--pfx-editorial-form-accent-container-text)}.form-row.grid-12{container-type:inline-size;container-name:praxis-form-row;display:grid;grid-template-columns:repeat(12,minmax(0,1fr));gap:var(--pfx-grid-gap, 16px)}.align-start{align-self:flex-start}.align-center{align-self:center}.align-end{align-self:flex-end}.align-stretch{align-self:stretch}.form-blocking-overlay{position:absolute;inset:0;background:transparent;color:var(--md-sys-color-on-surface);backdrop-filter:blur(2px) saturate(103%);-webkit-backdrop-filter:blur(2px) saturate(103%);display:flex;align-items:center;justify-content:center;flex-direction:column;gap:12px;z-index:10;pointer-events:all}@media(max-width:768px){.column-drop-wrapper,.row-drop-wrapper,.form-layout-rich-content,.praxis-dynamic-form .mat-mdc-form-field,.praxis-dynamic-form .mat-mdc-text-field-wrapper,.praxis-dynamic-form .mdc-text-field{max-width:100%;min-width:0}:host ::ng-deep .praxis-dynamic-form .pfx-field-shell,:host ::ng-deep .praxis-dynamic-form .pfx-field-shell-wrapper,:host ::ng-deep .praxis-dynamic-form .pfx-field-shell-host,:host ::ng-deep .praxis-dynamic-form .mat-mdc-form-field,:host ::ng-deep .praxis-dynamic-form .mat-mdc-text-field-wrapper,:host ::ng-deep .praxis-dynamic-form .mdc-text-field{width:100%;max-width:100%;min-width:0}.form-section{padding:clamp(.75rem,4vw,1rem)}.section-heading{gap:10px;margin-bottom:16px;padding-bottom:var(--pfx-form-section-heading-divider-gap, 14px)}.section-heading.title-only{padding-bottom:var(--pfx-form-section-heading-title-only-divider-gap, 8px)}}.section-title{display:flex;align-items:center;gap:8px}:host(.pfx-form-section-divider-inline-title) .section-heading.title-only .section-title{width:100%;min-width:0}:host(.pfx-form-section-divider-inline-title) .section-heading.title-only .section-title:after{content:\"\";display:block;flex:1 1 auto;min-width:var(--pfx-form-section-title-inline-divider-min-width, 48px);height:2px;margin-left:var(--pfx-form-section-title-inline-divider-gap, 12px);pointer-events:none;background:linear-gradient(90deg,var(--pfx-form-section-divider) 0%,var(--pfx-form-section-divider) 62%,color-mix(in srgb,var(--pfx-form-section-divider) 18%,transparent) 88%,transparent 100%);border-radius:999px;-webkit-mask-image:linear-gradient(90deg,black 0%,black 72%,transparent 100%);mask-image:linear-gradient(90deg,black 0%,black 72%,transparent 100%)}:host(.pfx-form-section-divider-inline-title) .section-heading.align-center .section-title:after{display:none}@media(max-width:640px){:host(.pfx-form-section-divider-inline-title) .section-heading.title-only{padding-bottom:var(--pfx-form-section-heading-title-only-divider-gap, 8px)}:host(.pfx-form-section-divider-inline-title) .section-heading.title-only:after{display:block}:host(.pfx-form-section-divider-inline-title) .section-heading.title-only .section-title{width:auto}:host(.pfx-form-section-divider-inline-title) .section-heading.title-only .section-title:after{display:none}}.section-title .section-title-icon{font-size:1.25em;line-height:1}.section-title-avatar{--_pfx-form-section-avatar-size: var(--pfx-form-section-avatar-size-md, var(--pfx-form-section-avatar-size, 32px));display:inline-flex;align-items:center;justify-content:center;width:var(--_pfx-form-section-avatar-size);height:var(--_pfx-form-section-avatar-size);border-radius:999px;flex:0 0 var(--_pfx-form-section-avatar-size);overflow:hidden}.section-title-avatar.size-sm{--_pfx-form-section-avatar-size: var(--pfx-form-section-avatar-size-sm, 24px)}.section-title-avatar.size-md{--_pfx-form-section-avatar-size: var(--pfx-form-section-avatar-size-md, var(--pfx-form-section-avatar-size, 32px))}.section-title-avatar.size-lg{--_pfx-form-section-avatar-size: var(--pfx-form-section-avatar-size-lg, 40px)}.section-title-avatar-image{object-fit:cover;border:1px solid color-mix(in srgb,var(--pfx-form-section-divider) 72%,transparent);background:var(--pfx-form-section-surface-flat)}.section-title-avatar-text,.section-title-avatar-placeholder{background:color-mix(in srgb,var(--pfx-editorial-form-accent) 14%,var(--pfx-form-section-surface-flat));color:color-mix(in srgb,var(--pfx-editorial-form-accent) 82%,var(--pfx-form-label-strong) 18%);font-size:calc(var(--_pfx-form-section-avatar-size) * .41);font-weight:800;letter-spacing:.04em;text-transform:uppercase}.section-title-avatar-placeholder mat-icon{font-size:calc(var(--_pfx-form-section-avatar-size) * .5625);width:calc(var(--_pfx-form-section-avatar-size) * .5625);height:calc(var(--_pfx-form-section-avatar-size) * .5625);line-height:calc(var(--_pfx-form-section-avatar-size) * .5625)}.section-title-avatar-sr-only{position:absolute;width:1px;height:1px;padding:0;margin:-1px;overflow:hidden;clip:rect(0,0,0,0);white-space:nowrap;border:0}.form-context-empty-state{display:grid;min-height:var(--pdx-form-context-empty-min-height, 0);place-items:center;padding:var(--pdx-form-context-empty-padding, 0)}.form-context-empty-state praxis-empty-state-card{display:block;width:min(100%,var(--pdx-form-context-empty-max-width, 32rem))}.prx-form-tabs{display:block;margin-bottom:16px;max-width:100%}.prx-form-tabs__tablist{display:flex;flex-wrap:wrap;align-items:center;gap:8px;max-width:100%}.prx-form-tabs__tablist--scrollable{flex-wrap:nowrap;overflow-x:auto;overflow-y:hidden;scrollbar-width:none;-webkit-overflow-scrolling:touch;padding:4px 2px}.prx-form-tabs__tablist--scrollable::-webkit-scrollbar{display:none}.prx-form-tabs__tab{display:inline-flex;align-items:center;gap:8px;min-width:0;padding:8px 14px;border-radius:999px;border:1px solid var(--md-sys-color-outline-variant, rgba(0, 0, 0, .12));background:color-mix(in srgb,var(--md-sys-color-surface, transparent) 40%,transparent);color:var(--md-sys-color-on-surface, #1d1b20);font-family:inherit;font-size:.84rem;font-weight:500;cursor:pointer;white-space:nowrap;flex-shrink:0;-webkit-user-select:none;user-select:none;transition:all .2s cubic-bezier(.2,0,0,1)}.prx-form-tabs__tab:hover:not(:disabled):not(.prx-form-tabs__tab--active){background:var(--md-sys-color-surface-container-high, rgba(0, 0, 0, .05));border-color:var(--md-sys-color-outline, rgba(0, 0, 0, .24));color:var(--md-sys-color-on-surface)}.prx-form-tabs__tab:focus-visible{outline:2px solid var(--md-sys-color-primary, #005ac1);outline-offset:2px}.prx-form-tabs__tab:disabled{cursor:not-allowed;opacity:.45}.prx-form-tabs__tab--active{background:var(--md-sys-color-primary-container, color-mix(in srgb, var(--md-sys-color-primary, #005ac1) 16%, var(--md-sys-color-surface-container-high, #2b2930)));color:var(--md-sys-color-on-primary-container, var(--md-sys-color-primary, #005ac1));border-color:transparent;font-weight:600;box-shadow:0 1px 3px #00000014}.prx-form-tabs__tab-icon{font-size:18px;width:18px;height:18px;display:inline-flex;align-items:center;justify-content:center}.prx-form-tabs__tab-badge{display:inline-flex;align-items:center;justify-content:center;padding:1px 7px;font-size:.72rem;font-weight:600;border-radius:999px;background:color-mix(in srgb,currentColor 14%,transparent)}.prx-form-tabs__tab-error-badge{display:inline-flex;align-items:center;justify-content:center;min-width:18px;height:18px;padding:0 5px;border-radius:999px;font-size:.7rem;font-weight:700;background:var(--md-sys-color-error, #ba1a1a);color:var(--md-sys-color-on-error, #ffffff);box-shadow:0 1px 2px #0003}.prx-form-tabs[data-appearance=underline]{border-bottom:1px solid var(--md-sys-color-outline-variant, #cac4d0)}.prx-form-tabs[data-appearance=underline] .prx-form-tabs__tablist{gap:16px;padding-bottom:0}.prx-form-tabs[data-appearance=underline] .prx-form-tabs__tab{border:none;border-radius:0;border-bottom:2px solid transparent;background:transparent;padding:8px 4px 10px;margin-bottom:-1px}.prx-form-tabs[data-appearance=underline] .prx-form-tabs__tab:hover:not(:disabled):not(.prx-form-tabs__tab--active){background:transparent;border-bottom-color:var(--md-sys-color-outline-variant, #cac4d0)}.prx-form-tabs[data-appearance=underline] .prx-form-tabs__tab--active{background:transparent;box-shadow:none;border-bottom-color:var(--md-sys-color-primary, #005ac1);color:var(--md-sys-color-primary, #005ac1)}.prx-form-tabs[data-appearance=buttons] .prx-form-tabs__tablist{background:var(--md-sys-color-surface-container, rgba(0, 0, 0, .04));border-radius:12px;padding:4px;gap:4px;border:1px solid var(--md-sys-color-outline-variant, rgba(0, 0, 0, .08))}.prx-form-tabs[data-appearance=buttons] .prx-form-tabs__tab{border:none;border-radius:8px;padding:6px 12px;background:transparent}.prx-form-tabs[data-appearance=buttons] .prx-form-tabs__tab:hover:not(:disabled):not(.prx-form-tabs__tab--active){background:color-mix(in srgb,currentColor 8%,transparent)}.prx-form-tabs[data-appearance=buttons] .prx-form-tabs__tab--active{background:var(--md-sys-color-surface, #ffffff);color:var(--md-sys-color-primary, #005ac1);box-shadow:0 1px 3px #0000001f}.section-drop-wrapper[hidden]{display:none!important}\n"], dependencies: [{ kind: "ngmodule", type: CommonModule }, { kind: "directive", type: i1$2.NgClass, selector: "[ngClass]", inputs: ["class", "ngClass"] }, { kind: "directive", type: i1$2.NgStyle, selector: "[ngStyle]", inputs: ["ngStyle"] }, { kind: "ngmodule", type: ReactiveFormsModule }, { kind: "directive", type: i1$3.ɵNgNoValidate, selector: "form:not([ngNoForm]):not([ngNativeValidate])" }, { kind: "directive", type: i1$3.NgControlStatusGroup, selector: "[formGroupName],[formArrayName],[ngModelGroup],[formGroup],[formArray],form:not([ngNoForm]),[ngForm]" }, { kind: "directive", type: i1$3.FormGroupDirective, selector: "[formGroup]", inputs: ["formGroup"], outputs: ["ngSubmit"], exportAs: ["ngForm"] }, { kind: "directive", type: DynamicFieldLoaderDirective, selector: "[dynamicFieldLoader]", inputs: ["fields", "formGroup", "enableExternalControlBinding", "itemTemplate", "debugTrace", "debugTraceLabel", "readonlyMode", "disabledMode", "presentationMode", "visible", "canvasMode"], outputs: ["componentsCreated", "fieldCreated", "fieldDestroyed", "renderError", "canvasMouseEnter", "canvasMouseLeave", "canvasClick", "canvasFocus"] }, { kind: "ngmodule", type: MatIconModule }, { kind: "component", type: i4.MatIcon, selector: "mat-icon", inputs: ["color", "inline", "svgIcon", "fontSet", "fontIcon"], exportAs: ["matIcon"] }, { kind: "ngmodule", type: MatButtonModule }, { kind: "component", type: i3.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: i3.MatFabButton, selector: "button[mat-fab], a[mat-fab], button[matFab], a[matFab]", inputs: ["extended"], exportAs: ["matButton", "matAnchor"] }, { kind: "ngmodule", type: MatProgressSpinnerModule }, { kind: "component", type: i17.MatProgressSpinner, selector: "mat-progress-spinner, mat-spinner", inputs: ["color", "mode", "value", "diameter", "strokeWidth"], exportAs: ["matProgressSpinner"] }, { kind: "ngmodule", type: MatTooltipModule }, { kind: "directive", type: i5.MatTooltip, selector: "[matTooltip]", inputs: ["matTooltipPosition", "matTooltipPositionAtOrigin", "matTooltipDisabled", "matTooltipShowDelay", "matTooltipHideDelay", "matTooltipTouchGestures", "matTooltip", "matTooltipClass"], exportAs: ["matTooltip"] }, { kind: "ngmodule", type: MatDialogModule }, { kind: "ngmodule", type: MatSnackBarModule }, { kind: "ngmodule", type: MatBadgeModule }, { kind: "directive", type: i19.MatBadge, selector: "[matBadge]", inputs: ["matBadgeColor", "matBadgeOverlap", "matBadgeDisabled", "matBadgePosition", "matBadge", "matBadgeDescription", "matBadgeSize", "matBadgeHidden"] }, { kind: "component", type: PraxisIconButtonComponent, selector: "button[praxisIconButton]", inputs: ["praxisIconButton", "size", "appearance", "presentation", "pressed", "busy"] }, { kind: "directive", type: PraxisIconDirective, selector: "mat-icon[praxisIcon]", inputs: ["praxisIcon"] }, { kind: "component", type: CanvasToolbarComponent, selector: "praxis-canvas-toolbar", inputs: ["selectedElement"], outputs: ["editMetadata", "delete", "moveUp", "moveDown", "selectPath", "requestClose", "toggleReadonly", "toggleRequired", "toggleHidden", "toggleDisabled"] }, { kind: "component", type: PraxisFormActionsComponent, selector: "praxis-form-actions", inputs: ["actions", "editorialVisualContext", "isSubmitting", "formIsValid", "submitError", "invalidRequiredFieldLabels", "suppressInvalidSubmitHint", "formId", "actionOverrides"], outputs: ["action"] }, { kind: "component", type: EmptyStateCardComponent, selector: "praxis-empty-state-card", inputs: ["icon", "title", "description", "primaryAction", "secondaryActions", "inline", "tone", "variant", "alignment", "density", "iconContainer"] }, { kind: "component", type: PraxisAiAssistantShellComponent, selector: "praxis-ai-assistant-shell", inputs: ["labels", "mode", "state", "contextItems", "attachments", "messages", "quickReplies", "recommendedIntents", "prompt", "statusText", "errorText", "testIdPrefix", "panelTestId", "submitTestId", "applyTestId", "primaryAction", "secondaryActions", "governanceActions", "busy", "canSubmit", "canApply", "submitOnEnter", "showAttachAction", "enablePastedAttachments", "enableFileAttachments", "attachmentAccept", "attachmentMultiple", "voiceInputMode", "voiceLanguage", "draggable", "resizable", "minWidth", "minHeight", "margin", "layout"], outputs: ["promptChange", "submitPrompt", "apply", "retryTurn", "cancelTurn", "shellAction", "close", "attach", "attachmentsPasted", "attachmentsSelected", "removeAttachment", "messageAction", "editMessage", "resendMessage", "quickReply", "recommendedIntent", "layoutChange"] }, { kind: "component", type: PraxisRichContent, selector: "praxis-rich-content", inputs: ["document", "nodes", "context", "hostCapabilities", "layout", "rootClassName"], outputs: ["nodeAction"] }] });
|
|
21978
|
+
static ɵcmp = i0.ɵɵngDeclareComponent({ minVersion: "17.0.0", version: "21.2.14", type: PraxisDynamicForm, isStandalone: true, selector: "praxis-dynamic-form", inputs: { resourcePath: "resourcePath", resourceId: "resourceId", initialValue: "initialValue", emptyState: "emptyState", editorialContext: "editorialContext", mode: "mode", config: "config", actions: "actions", schemaSource: "schemaSource", schemaUrl: "schemaUrl", readUrl: "readUrl", submitUrl: "submitUrl", submitMethod: "submitMethod", submitIdempotencyKey: "submitIdempotencyKey", submitCorrelationId: "submitCorrelationId", submitResourceVersion: "submitResourceVersion", submitResourceVersionTargetResourceKey: "submitResourceVersionTargetResourceKey", submitResourceVersionTargetIdField: "submitResourceVersionTargetIdField", responseSchemaUrl: "responseSchemaUrl", apiEndpointKey: "apiEndpointKey", apiUrlEntry: "apiUrlEntry", enableCustomization: "enableCustomization", showAiAssistant: "showAiAssistant", formId: "formId", componentInstanceId: "componentInstanceId", configPersistenceStrategy: "configPersistenceStrategy", layout: "layout", layoutMode: "layoutMode", formLayout: "formLayout", generatedLayoutPreset: "generatedLayoutPreset", layoutPolicy: "layoutPolicy", backConfig: "backConfig", hooks: "hooks", removeEmptyContainersOnSave: "removeEmptyContainersOnSave", reactiveValidation: "reactiveValidation", reactiveValidationDebounceMs: "reactiveValidationDebounceMs", notifyIfOutdated: "notifyIfOutdated", snoozeMs: "snoozeMs", autoOpenSettingsOnOutdated: "autoOpenSettingsOnOutdated", readonlyModeGlobal: "readonlyModeGlobal", disabledModeGlobal: "disabledModeGlobal", presentationModeGlobal: "presentationModeGlobal", presentation: "presentation", presentationPreset: "presentationPreset", sectionDefaultAppearance: "sectionDefaultAppearance", sectionDivider: "sectionDivider", visibleGlobal: "visibleGlobal", fieldIconPolicy: "fieldIconPolicy", domainRules: "domainRules", customEndpoints: "customEndpoints" }, outputs: { formSubmit: "formSubmit", formCancel: "formCancel", formReset: "formReset", configChange: "configChange", configPatchChange: "configPatchChange", formReady: "formReady", valueChange: "valueChange", payloadPreviewChange: "payloadPreviewChange", syncCompleted: "syncCompleted", initializationError: "initializationError", loadingStateChange: "loadingStateChange", enableCustomizationChange: "enableCustomizationChange", customAction: "customAction", actionConfirmation: "actionConfirmation", schemaStatusChange: "schemaStatusChange", fieldRenderError: "fieldRenderError", ruleDiagnosticsChange: "ruleDiagnosticsChange", reactiveDeterminationExecuted: "reactiveDeterminationExecuted", reactiveDeterminationPendingChange: "reactiveDeterminationPendingChange", tabChange: "tabChange", tabSelected: "tabSelected" }, providers: [providePraxisI18nConfig(PRAXIS_DYNAMIC_FORM_I18N_CONFIG)], viewQueries: [{ propertyName: "formHost", first: true, predicate: ["formHost"], descendants: true }, { propertyName: "fieldLoaders", predicate: DynamicFieldLoaderDirective, descendants: true }], usesOnChanges: true, ngImport: i0, template: "@if (isLoading) {\n <!-- Loading State -->\n <div class=\"form-loading\" role=\"status\" aria-live=\"polite\" aria-label=\"Carregando formul\u00E1rio\">\n <div class=\"form-loading-header\">\n <mat-progress-spinner diameter=\"32\" aria-label=\"Carregando formul\u00E1rio\"></mat-progress-spinner>\n <div class=\"form-loading-copy\">\n <p class=\"form-loading-title\">Carregando formul\u00E1rio...</p>\n <p class=\"form-loading-subtitle\">Preparando campos e op\u00E7\u00F5es do cadastro.</p>\n </div>\n </div>\n <div class=\"form-loading-skeleton\" aria-hidden=\"true\">\n <span class=\"form-loading-line form-loading-line-title\"></span>\n <span class=\"form-loading-line\"></span>\n <span class=\"form-loading-line form-loading-line-short\"></span>\n <span class=\"form-loading-field\"></span>\n <span class=\"form-loading-field form-loading-field-wide\"></span>\n </div>\n </div>\n} @else if (initializationStatus === 'error') {\n <!-- Error State -->\n <div class=\"form-error\">\n <mat-icon color=\"warn\" [praxisIcon]=\"'error'\"></mat-icon>\n <h3>{{ getErrorTitle() }}</h3>\n <p>{{ currentErrorMessage }}</p>\n @if (isRecoverable) {\n <button mat-stroked-button (click)=\"retryInitialization()\">\n <mat-icon [praxisIcon]=\"'refresh'\"></mat-icon>\n Tentar Novamente\n </button>\n }\n <button mat-button (click)=\"showDetailedError()\" class=\"show-details\">\n Ver Detalhes T\u00E9cnicos\n </button>\n <!-- Permitir corre\u00E7\u00E3o do resourcePath diretamente do estado de erro -->\n <button mat-flat-button color=\"primary\" (click)=\"openQuickConnect()\" class=\"connect-action\">\n <mat-icon [praxisIcon]=\"'bolt'\"></mat-icon>\n Conectar a recurso\n </button>\n </div>\n} @else if (initializationStatus === 'success') {\n <!-- Inline banner for schema change (only when customization is enabled) -->\n @if (shouldShowOutdatedInline()) {\n <div class=\"pfx-form-info-banner\" role=\"status\" aria-live=\"polite\">\n <div class=\"text\">O schema do servidor mudou. Reconciliar agora?</div>\n <div class=\"actions\">\n <button mat-stroked-button color=\"primary\" (click)=\"openConfigEditor()\">\n <mat-icon [praxisIcon]=\"'sync'\"></mat-icon>\n Reconciliar\n </button>\n <button mat-button (click)=\"onSnoozeOutdated()\">Lembrar depois</button>\n <button mat-button (click)=\"onIgnoreOutdated()\">Ignorar</button>\n </div>\n </div>\n }\n\n <!-- Configuration Controls -->\n @if (shouldShowConfigControls && enableCustomization) {\n <div class=\"form-config-controls\">\n @if (showAiAssistant) {\n <button type=\"button\" praxisIconButton=\"auto_awesome\" size=\"dense\" (click)=\"openAiAssistant()\" [disabled]=\"isLoading\"\n [attr.data-testid]=\"aiAssistantTriggerTestId('config-controls')\"\n aria-label=\"Abrir copiloto semantico Praxis do formulario\"\n matTooltip=\"Abrir copiloto sem\u00E2ntico do formul\u00E1rio\">\n </button>\n }\n <button type=\"button\" praxisIconButton=\"settings\" size=\"dense\" (click)=\"openConfigEditor()\" [disabled]=\"isLoading\" class=\"config-button\"\n [matBadge]=\"schemaOutdated ? '!' : ''\" [matBadgeHidden]=\"!schemaOutdated\" matBadgeColor=\"warn\" matBadgeSize=\"small\"\n matBadgePosition=\"above after\"\n [attr.aria-label]=\"configControlLabel\" [matTooltip]=\"configControlLabel\">\n </button>\n <button type=\"button\" praxisIconButton=\"link_off\" size=\"dense\" (click)=\"disconnect()\"\n [attr.aria-label]=\"disconnectControlLabel\" [matTooltip]=\"disconnectControlLabel\"\n [disabled]=\"isLoading\">\n </button>\n </div>\n }\n\n <!-- Form Content -->\n @if (!resourcePath && !hasExplicitSchemaUrl() && !hasRenderableConfig()) {\n <praxis-empty-state-card icon=\"link\" [title]=\"'Conecte o formul\u00E1rio \u00E0 fonte de dados'\"\n [description]=\"'Informe a rota do recurso da API para gerar automaticamente os campos do formul\u00E1rio.'\"\n [primaryAction]=\"{ label: 'Conectar \u00E0 fonte de dados', icon: 'bolt', action: openQuickConnect.bind(this) }\"></praxis-empty-state-card>\n }\n @if (shouldShowContextEmptyState()) {\n <div class=\"form-context-empty-state\" role=\"status\" aria-live=\"polite\">\n <praxis-empty-state-card\n [icon]=\"emptyState?.icon || 'touch_app'\"\n [title]=\"emptyState!.title\"\n [description]=\"emptyState?.description\"\n [tone]=\"emptyState?.tone || 'primary'\"\n [variant]=\"emptyState?.variant || 'transparent'\"\n [alignment]=\"emptyState?.alignment || 'center'\"\n [density]=\"emptyState?.density || 'compact'\"\n [iconContainer]=\"emptyState?.iconContainer || 'circle'\"\n [inline]=\"true\"\n />\n </div>\n } @else {\n <div #entityReadRegion class=\"entity-read-region\" tabindex=\"-1\" role=\"region\" [attr.aria-label]=\"entityReadText('region')\">\n <span class=\"cdk-visually-hidden\" role=\"status\" aria-live=\"polite\" aria-atomic=\"true\">{{ entityReadStatusText() }}</span>\n @if (entityHydrationPending || entityReadFailed) {\n <div class=\"entity-read-feedback\" data-testid=\"form-entity-read-feedback\">\n @if (entityHydrationPending) {\n <mat-progress-spinner diameter=\"28\" mode=\"indeterminate\" aria-hidden=\"true\"></mat-progress-spinner>\n <p aria-hidden=\"true\">{{ entityReadText('loading') }}</p>\n } @else {\n <mat-icon [praxisIcon]=\"'error_outline'\" aria-hidden=\"true\"></mat-icon>\n <p aria-hidden=\"true\">{{ entityReadText('error') }}</p>\n <button mat-stroked-button type=\"button\" (click)=\"retryEntityRead(entityReadRegion)\">{{ entityReadText('retry') }}</button>\n }\n </div>\n }\n <form #formHost (ngSubmit)=\"onSubmit()\" [attr.aria-busy]=\"submitting || entityHydrationPending ? 'true' : null\"\n [style.opacity]=\"entityHydrationPending || entityReadFailed ? '0' : null\"\n [style.transition]=\"entityHydrationPending || entityReadFailed ? 'none' : null\"\n [attr.inert]=\"entityHydrationPending || entityReadFailed ? '' : null\"\n [attr.aria-hidden]=\"entityHydrationPending || entityReadFailed ? 'true' : null\"\n [attr.aria-label]=\"'Formul\u00E1rio ' + (config.metadata?.version || '')\" [class.canvas-mode-enabled]=\"enableCustomization\"\n [class.presentation-mode]=\"effectivePresentation\"\n [class.praxis-dynamic-form--presentation]=\"effectivePresentation\"\n [class.readonly-mode]=\"effectiveReadonly\"\n [attr.data-presentation-preset]=\"effectivePresentation ? effectivePresentationPreset : null\"\n [class.praxis-dynamic-form--corporate-dossier]=\"isCorporateDossierPreset()\"\n [class.praxis-dynamic-form--editorial-card]=\"isEditorialCardPreset()\"\n [class.praxis-dynamic-form--compact-presentation]=\"isCompactPresentationPreset()\"\n [class.editorial-visual-context]=\"hasEditorialVisualContext()\"\n [class.pfx-mounting]=\"isMounting\" [formGroup]=\"form\"\n [ngClass]=\"{\n 'pres-compact': presentationVars.compact,\n 'pres-label-left': presentationVars.labelPosition === 'left',\n 'pres-label-above': presentationVars.labelPosition === 'above'\n }\" [style.--pfx-pres-label-align]=\"presentationVars.labelAlign\"\n [style.--pfx-pres-label-size]=\"presentationVars.labelSize\"\n [style.--pfx-pres-label-width]=\"presentationVars.labelWidth\"\n [style.--pfx-pres-row-gap]=\"presentationVars.density === 'compact' ? '6px' : (presentationVars.density === 'cozy' ? '8px' : '10px')\"\n [style.--pfx-pres-row-padding]=\"presentationVars.density === 'compact' ? '2px 0' : (presentationVars.density === 'cozy' ? '6px 0' : '8px 0')\"\n [style.--pfx-pres-value-align]=\"presentationVars.valueAlign\"\n [style.--pfx-pres-value-size]=\"presentationVars.valueSize\"\n [style.--pdx-form-mount-duration]=\"getMountDurationVar()\"\n [style.--pdx-form-mount-offset]=\"getMountOffsetVar()\"\n [style.--pdx-form-mount-stagger]=\"getMountStaggerVar()\"\n class=\"praxis-dynamic-form\">\n @if (enableCustomization && selectedElement) {\n <praxis-canvas-toolbar (editMetadata)=\"openSelectedElementEditor()\" (selectPath)=\"onSelectPath($event)\"\n (moveUp)=\"onToolbarMove('up')\" (moveDown)=\"onToolbarMove('down')\" (toggleReadonly)=\"onToolbarToggleReadonly()\"\n (toggleRequired)=\"onToolbarToggleRequired()\" (toggleHidden)=\"onToolbarToggleHidden()\"\n (toggleDisabled)=\"onToolbarToggleDisabled()\" (requestClose)=\"onToolbarRequestClose()\"\n [selectedElement]=\"selectedElement\"\n [style.transform]=\"toolbarTransform\"></praxis-canvas-toolbar>\n }\n\n @if (formBlocksBefore?.nodes?.length) {\n <section class=\"form-editorial-blocks form-editorial-blocks-before\" data-editorial-placement=\"before\">\n <praxis-rich-content\n [document]=\"formBlocksBeforeDocument\"\n [context]=\"getEditorialRichContentContext()\"\n [hostCapabilities]=\"richContentHostCapabilities\"\n ></praxis-rich-content>\n </section>\n }\n\n @if (actionPlacement === 'top' && !(effectivePresentation || effectiveReadonly)) {\n <praxis-form-actions data-actions-placement=\"top\" [actions]=\"effectiveActions\" [isSubmitting]=\"submitting\"\n [formIsValid]=\"effectiveFormIsValid\" [submitError]=\"submitError\" [formId]=\"formId\" [actionOverrides]=\"actionRuleProps\"\n [invalidRequiredFieldLabels]=\"invalidRequiredFieldLabels\"\n [suppressInvalidSubmitHint]=\"entityHydrationPending\"\n [editorialVisualContext]=\"hasEditorialVisualContext()\"\n (action)=\"onFormAction($event)\"></praxis-form-actions>\n }\n\n <!-- Tab Layout Navigation Bar -->\n @if (effectiveLayoutMode === 'tabs' && effectiveTabs.length > 1) {\n <nav class=\"prx-form-tabs\" [attr.data-appearance]=\"effectiveTabsAppearance\" role=\"tablist\" aria-label=\"Navega\u00E7\u00E3o em abas do formul\u00E1rio\">\n <div class=\"prx-form-tabs__tablist prx-form-tabs__tablist--scrollable\">\n @for (tab of effectiveTabs; track tab.id) {\n <button\n type=\"button\"\n role=\"tab\"\n class=\"prx-form-tabs__tab\"\n [class.prx-form-tabs__tab--active]=\"activeTabId === tab.id\"\n [attr.aria-selected]=\"activeTabId === tab.id\"\n [attr.aria-controls]=\"getTabAriaControls(tab)\"\n [attr.id]=\"'tab-' + tab.id\"\n [disabled]=\"tab.disabled\"\n [matTooltip]=\"tab.tooltip || null\"\n [matTooltipDisabled]=\"!tab.tooltip\"\n (click)=\"selectTab(tab.id)\"\n >\n @if (tab.icon) {\n <mat-icon class=\"prx-form-tabs__tab-icon\" [praxisIcon]=\"tab.icon\" aria-hidden=\"true\"></mat-icon>\n }\n <span class=\"prx-form-tabs__tab-label\">{{ tab.label }}</span>\n @if (tab.badge != null) {\n <span class=\"prx-form-tabs__tab-badge\">{{ tab.badge }}</span>\n }\n @if (getTabErrorCount(tab) > 0) {\n <span class=\"prx-form-tabs__tab-error-badge\" [attr.aria-label]=\"getTabErrorCount(tab) + ' erros na aba'\">\n {{ getTabErrorCount(tab) }}\n </span>\n }\n </button>\n }\n </div>\n </nav>\n }\n\n @for (section of (config.sections || []); track (section.id ?? $index); let sectionIndex = $index) {\n <div class=\"section-drop-wrapper\" [attr.data-section-id]=\"section.id\" [hidden]=\"!isSectionInActiveTab(section)\"\n [attr.role]=\"effectiveLayoutMode === 'tabs' ? 'tabpanel' : null\"\n [attr.id]=\"effectiveLayoutMode === 'tabs' ? ('section-tabpanel-' + section.id) : null\"\n [attr.aria-labelledby]=\"effectiveLayoutMode === 'tabs' ? ('tab-' + (getTabIdForSection(section) || section.id)) : null\">\n @if (isSectionVisible(section)) {\n <div #sectionEl class=\"form-section canvas-element\" data-canvas-type=\"section\" [attr.data-section-id]=\"section.id\"\n [attr.data-section-index]=\"sectionIndex\" (mouseenter)=\"onElementMouseEnter($event, 'section', section, sectionEl)\"\n (mouseleave)=\"onElementMouseLeave($event)\" (click)=\"onElementClick($event, 'section', section, sectionEl)\"\n [class.selected]=\"selectedElement?.domElement === sectionEl\"\n [class.hovered]=\"hoveredElement?.domElement === sectionEl && selectedElement?.domElement !== sectionEl\"\n [attr.data-section-appearance]=\"getSectionAppearance(section) || null\"\n [attr.data-section-divider]=\"isSectionDividerEnabled(section) ? 'true' : null\"\n [attr.data-presentation-preset]=\"effectivePresentation ? getSectionPresentationPreset(section) : null\"\n [class.form-section--corporate-dossier]=\"isSectionCorporateDossier(section)\"\n [class.form-section--editorial-card]=\"isSectionEditorialCard(section)\"\n [class.form-section--compact-presentation]=\"isSectionCompactPresentation(section)\"\n [style.marginBottom.px]=\"!isLastVisibleSection(section) ? getSectionGapBottom(section) : null\" [ngClass]=\"getSectionClasses(section)\"\n [ngStyle]=\"getSectionStyles(section)\">\n @if (!shouldHideSectionHeader(section)) {\n <div\n class=\"section-heading\"\n [class.align-center]=\"getSectionHeaderAlign(section) === 'center'\"\n [class.step-appearance]=\"getSectionAppearance(section) === 'step'\"\n [class.title-only]=\"isSectionHeaderTitleOnly(section)\"\n >\n <div class=\"section-heading-text\" [matTooltip]=\"getSectionHeaderTooltip(section) || null\"\n [matTooltipDisabled]=\"!getSectionHeaderTooltip(section)\">\n @if (getSectionStepLabel(section)) {\n <div class=\"section-step-label\" [class.align-center]=\"getSectionHeaderAlign(section) === 'center'\">\n {{ getSectionStepLabel(section) }}\n </div>\n }\n @if (getSectionTitle(section)) {\n <h3 class=\"section-title\" [class.title-large]=\"getSectionTitleStyle(section) === 'titleLarge'\"\n [class.title-medium]=\"getSectionTitleStyle(section) === 'titleMedium'\"\n [class.title-small]=\"getSectionTitleStyle(section) === 'titleSmall'\"\n [class.headline-small]=\"getSectionTitleStyle(section) === 'headlineSmall'\"\n [style.marginBottom.px]=\"getEffectiveSectionTitleGapBottom(section)\" [style.color]=\"getSectionTitleColor(section) || null\"\n [class.align-center]=\"getSectionHeaderAlign(section) === 'center'\"\n [attr.id]=\"sectionPanelId(section, sectionIndex) + '-title'\">\n @let sectionHeaderVisual = getSectionHeaderVisual(section);\n @let sectionHeaderAvatarSize = getSectionHeaderAvatarSize(section);\n @if (sectionHeaderVisual.kind === 'icon') {\n <mat-icon class=\"section-title-icon\" aria-hidden=\"true\" [praxisIcon]=\"sectionHeaderVisual.icon\"></mat-icon>\n }\n @if (sectionHeaderVisual.kind === 'image') {\n <img class=\"section-title-avatar section-title-avatar-image\" [class.size-sm]=\"sectionHeaderAvatarSize === 'sm'\"\n [class.size-md]=\"sectionHeaderAvatarSize === 'md'\" [class.size-lg]=\"sectionHeaderAvatarSize === 'lg'\"\n [src]=\"sectionHeaderVisual.src\" [alt]=\"sectionHeaderVisual.alt\" />\n }\n @if (sectionHeaderVisual.kind === 'initials') {\n <span class=\"section-title-avatar section-title-avatar-text\" [class.size-sm]=\"sectionHeaderAvatarSize === 'sm'\"\n [class.size-md]=\"sectionHeaderAvatarSize === 'md'\" [class.size-lg]=\"sectionHeaderAvatarSize === 'lg'\" aria-hidden=\"true\">\n {{ sectionHeaderVisual.text }}\n </span>\n @if (sectionHeaderVisual.ariaLabel) {\n <span class=\"section-title-avatar-sr-only\">{{ sectionHeaderVisual.ariaLabel }}</span>\n }\n }\n @if (sectionHeaderVisual.kind === 'placeholder') {\n <span class=\"section-title-avatar section-title-avatar-placeholder\" [class.size-sm]=\"sectionHeaderAvatarSize === 'sm'\"\n [class.size-md]=\"sectionHeaderAvatarSize === 'md'\" [class.size-lg]=\"sectionHeaderAvatarSize === 'lg'\" aria-hidden=\"true\">\n @if (sectionHeaderVisual.icon) {\n <mat-icon aria-hidden=\"true\" [praxisIcon]=\"sectionHeaderVisual.icon\"></mat-icon>\n }\n @if (sectionHeaderVisual.text) {\n <span>{{ sectionHeaderVisual.text }}</span>\n }\n </span>\n @if (sectionHeaderVisual.ariaLabel) {\n <span class=\"section-title-avatar-sr-only\">{{ sectionHeaderVisual.ariaLabel }}</span>\n }\n }\n {{ getSectionTitle(section) }}\n @if (enableCustomization) {\n <button type=\"button\" class=\"inline-edit-btn\" praxisIconButton=\"edit\" size=\"dense\" (click)=\"openSectionEditor(section, 'title')\"\n aria-label=\"Editar t\u00EDtulo da se\u00E7\u00E3o\" matTooltip=\"Editar t\u00EDtulo\">\n </button>\n }\n </h3>\n }\n @if (getSectionDescription(section)) {\n <p class=\"section-description\" [class.body-large]=\"getSectionDescriptionStyle(section) === 'bodyLarge'\"\n [class.body-medium]=\"getSectionDescriptionStyle(section) === 'bodyMedium'\"\n [class.body-small]=\"getSectionDescriptionStyle(section) === 'bodySmall'\"\n [style.marginBottom.px]=\"getSectionDescriptionGapBottom(section) ?? 8\" [style.color]=\"getSectionDescriptionColor(section) || null\"\n [class.align-center]=\"getSectionHeaderAlign(section) === 'center'\">\n {{ getSectionDescription(section) }}\n @if (enableCustomization) {\n <button type=\"button\" class=\"inline-edit-btn\" praxisIconButton=\"edit\" size=\"dense\"\n (click)=\"openSectionEditor(section, 'description')\" aria-label=\"Editar descri\u00E7\u00E3o da se\u00E7\u00E3o\"\n matTooltip=\"Editar descri\u00E7\u00E3o\">\n </button>\n }\n </p>\n }\n </div>\n @if (getSectionHeaderActions(section).length) {\n <div class=\"section-heading-actions\" [class.align-center]=\"getSectionHeaderAlign(section) === 'center'\">\n @for (action of getSectionHeaderActions(section); track action.id) {\n <button\n type=\"button\"\n class=\"section-heading-action-btn\"\n [praxisIconButton]=\"action.icon\"\n size=\"compact\"\n [busy]=\"action.loading\"\n [disabled]=\"isSectionHeaderActionDisabled(action)\"\n [matTooltip]=\"getSectionHeaderActionTooltip(action)\"\n [attr.aria-label]=\"action.label\"\n [attr.aria-busy]=\"action.loading ? 'true' : null\"\n [ngClass]=\"getSectionHeaderActionNgClass(action)\"\n [ngStyle]=\"getSectionHeaderActionStyles(action)\"\n (click)=\"onSectionHeaderActionClick(section, action, $event)\"\n >\n @if (action.loading) {\n <span class=\"section-heading-action-sr-only\">{{ getSectionHeaderActionLoadingLabel(action) }}</span>\n }\n </button>\n }\n </div>\n }\n @if (isSectionCollapsible(section)) {\n <button type=\"button\" class=\"section-collapse-btn\" [praxisIconButton]=\"isSectionCollapsed(section) ? 'expand_more' : 'expand_less'\" size=\"compact\"\n (click)=\"toggleSectionCollapse($event, section)\" [attr.aria-expanded]=\"!isSectionCollapsed(section)\"\n [attr.aria-controls]=\"sectionPanelId(section, sectionIndex)\"\n [attr.aria-label]=\"isSectionCollapsed(section) ? 'Expandir se\u00E7\u00E3o' : 'Recolher se\u00E7\u00E3o'\">\n </button>\n }\n </div>\n }\n\n <div class=\"section-body\" [class.collapsed]=\"isSectionCollapsed(section)\"\n [attr.id]=\"sectionPanelId(section, sectionIndex)\"\n [attr.role]=\"getSectionTitle(section) ? 'region' : null\"\n [attr.aria-labelledby]=\"getSectionTitle(section) ? sectionPanelId(section, sectionIndex) + '-title' : null\">\n @if (!isSectionCollapsed(section)) {\n @for (row of section.rows; track (row.id ?? $index); let rowIndex = $index) {\n @if (isRowVisible(row)) {\n <div class=\"row-drop-wrapper\" [attr.data-section-id]=\"section.id\">\n <div #rowEl class=\"form-row grid-12 canvas-element\" data-canvas-type=\"row\" [attr.data-row-index]=\"rowIndex\"\n [attr.data-section-id]=\"section.id\" [attr.data-row-id]=\"row.id\" [style.--pfx-grid-gap.px]=\"getRowGap(row)\"\n [style.--pfx-field-gap.px]=\"getRowRowGap(row)\"\n [style.--pfx-mount-index]=\"rowIndex\"\n [style.marginBottom.px]=\"rowIndex < section.rows.length - 1 ? (getRowRowGap(row) ?? null) : null\"\n [ngClass]=\"getRowClasses(row)\" [ngStyle]=\"getRowStyles(row)\"\n (mouseenter)=\"onElementMouseEnter($event, 'row', row, rowEl)\" (mouseleave)=\"onElementMouseLeave($event)\"\n (click)=\"onElementClick($event, 'row', row, rowEl)\" [class.selected]=\"selectedElement?.domElement === rowEl\"\n [class.hovered]=\"hoveredElement?.domElement === rowEl && selectedElement?.domElement !== rowEl\">\n @for (column of row.columns; track (column.id ?? $index); let colIndex = $index) {\n @if (isColumnVisible(column)) {\n <div class=\"column-drop-wrapper\" [attr.data-section-id]=\"section.id\" [attr.data-row-id]=\"row.id\">\n <div #colEl class=\"form-column canvas-element\" [ngClass]=\"getColumnClasses(column, row)\"\n [style.padding.px]=\"getColumnPadding(column)\" [style.--pfx-field-gap.px]=\"getRowRowGap(row)\"\n [ngStyle]=\"getColumnStyles(column)\" [attr.data-testid]=\"column.testId || null\"\n [attr.data-row-gap]=\"getRowRowGap(row)\" data-canvas-type=\"column\" [attr.data-column-index]=\"colIndex\"\n [attr.data-row-index]=\"rowIndex\" [attr.data-section-id]=\"section.id\" [attr.data-row-id]=\"row.id\"\n [attr.data-column-id]=\"column.id\" (mouseenter)=\"onElementMouseEnter($event, 'column', column, colEl)\"\n (mouseleave)=\"onElementMouseLeave($event)\" (click)=\"onElementClick($event, 'column', column, colEl)\"\n [class.selected]=\"selectedElement?.domElement === colEl\"\n [class.hovered]=\"hoveredElement?.domElement === colEl && selectedElement?.domElement !== colEl\">\n @for (renderItem of getColumnRenderItems(column); track renderItem.id) {\n @if (renderItem.kind === 'fields') {\n <ng-container dynamicFieldLoader [fields]=\"getRenderableFieldsForLoader(renderItem.fields)\" [formGroup]=\"form\"\n [enableExternalControlBinding]=\"true\"\n [readonlyMode]=\"effectiveReadonly\"\n [disabledMode]=\"effectiveDisabledMode\"\n [presentationMode]=\"presentationForLoader\" [visible]=\"visibleGlobal === null ? null : visibleGlobal\"\n [canvasMode]=\"enableCustomization\" (canvasMouseEnter)=\"onFieldMouseEnter($event)\"\n (canvasMouseLeave)=\"onFieldMouseLeave($event)\" (canvasClick)=\"onFieldClick($event)\"\n (canvasFocus)=\"onFieldFocus($event)\"\n (renderError)=\"onFieldRenderError($event)\">\n </ng-container>\n } @else {\n <praxis-rich-content\n class=\"form-layout-rich-content\"\n [ngClass]=\"renderItem.className || null\"\n [ngStyle]=\"renderItem.style || null\"\n [document]=\"renderItem.document\"\n [layout]=\"renderItem.layout\"\n [rootClassName]=\"renderItem.rootClassName || ''\"\n [context]=\"getEditorialRichContentContext()\"\n [hostCapabilities]=\"richContentHostCapabilities\"\n ></praxis-rich-content>\n }\n }\n </div>\n </div>\n } }\n </div>\n </div>\n }\n }\n } @else {\n <div class=\"section-collapsed-placeholder\">\n <mat-icon aria-hidden=\"true\" [praxisIcon]=\"'unfold_more'\"></mat-icon>\n <span>{{ getSectionCollapsedSummary(section) }}</span>\n </div>\n }\n @if (isLastVisibleSection(section) && beforeActionsPlacement === 'insideLastSection' && formBlocksBeforeActions?.nodes?.length) {\n <section class=\"form-editorial-blocks form-editorial-blocks-before-actions\" data-editorial-placement=\"beforeActions\">\n <praxis-rich-content\n [document]=\"formBlocksBeforeActionsDocument\"\n [context]=\"getEditorialRichContentContext()\"\n [hostCapabilities]=\"richContentHostCapabilities\"\n ></praxis-rich-content>\n </section>\n }\n @if (actionPlacement === 'insideLastSection' && isLastVisibleSection(section) && !(effectivePresentation\n || effectiveReadonly)) {\n <praxis-form-actions data-actions-placement=\"insideLastSection\" [actions]=\"effectiveActions\"\n [isSubmitting]=\"submitting\" [formIsValid]=\"effectiveFormIsValid\" [submitError]=\"submitError\" [formId]=\"formId\"\n [actionOverrides]=\"actionRuleProps\" [invalidRequiredFieldLabels]=\"invalidRequiredFieldLabels\"\n [suppressInvalidSubmitHint]=\"entityHydrationPending\"\n [editorialVisualContext]=\"hasEditorialVisualContext()\"\n (action)=\"onFormAction($event)\"></praxis-form-actions>\n }\n </div>\n <!-- Overlay de bloqueio durante submiss\u00E3o -->\n @if (submitting) {\n <div class=\"form-blocking-overlay\" aria-live=\"polite\">\n <mat-progress-spinner\n diameter=\"40\"\n color=\"primary\"\n [attr.aria-label]=\"config.messages?.loading?.submit || 'Salvando formul\u00E1rio'\"\n ></mat-progress-spinner>\n <p>{{ config.messages?.loading?.submit || 'Salvando...' }}</p>\n </div>\n }\n </div>\n\n @if (enableCustomization && selectedElement?.domElement === sectionEl) {\n <div class=\"add-section-container\">\n <div class=\"add-section-line\"></div>\n <button mat-fab color=\"primary\" aria-label=\"Adicionar nova se\u00E7\u00E3o\" (click)=\"addNewSectionAfter(sectionIndex)\"\n matTooltip=\"Adicionar nova se\u00E7\u00E3o aqui\">\n <mat-icon [praxisIcon]=\"'add'\"></mat-icon>\n </button>\n <div class=\"add-section-line\"></div>\n </div>\n }\n }\n </div>\n }\n\n @if (beforeActionsPlacement !== 'insideLastSection' && formBlocksBeforeActions?.nodes?.length) {\n <section class=\"form-editorial-blocks form-editorial-blocks-before-actions\" data-editorial-placement=\"beforeActions\">\n <praxis-rich-content\n [document]=\"formBlocksBeforeActionsDocument\"\n [context]=\"getEditorialRichContentContext()\"\n [hostCapabilities]=\"richContentHostCapabilities\"\n ></praxis-rich-content>\n </section>\n }\n\n @if (actionPlacement === 'afterSections' && !(effectivePresentation || effectiveReadonly)) {\n <praxis-form-actions data-actions-placement=\"afterSections\" [actions]=\"effectiveActions\" [isSubmitting]=\"submitting\"\n [formIsValid]=\"effectiveFormIsValid\" [submitError]=\"submitError\" [formId]=\"formId\"\n [actionOverrides]=\"actionRuleProps\" [invalidRequiredFieldLabels]=\"invalidRequiredFieldLabels\"\n [suppressInvalidSubmitHint]=\"entityHydrationPending\"\n [editorialVisualContext]=\"hasEditorialVisualContext()\"\n (action)=\"onFormAction($event)\"></praxis-form-actions>\n }\n\n @if (formBlocksAfter?.nodes?.length) {\n <section class=\"form-editorial-blocks form-editorial-blocks-after\" data-editorial-placement=\"after\">\n <praxis-rich-content\n [document]=\"formBlocksAfterDocument\"\n [context]=\"getEditorialRichContentContext()\"\n [hostCapabilities]=\"richContentHostCapabilities\"\n ></praxis-rich-content>\n </section>\n }\n </form>\n </div>\n }\n @if (showAiAssistant && !enableCustomization && (mode === 'view' || mode === 'presentation' || mode === 'dossier') && !shouldShowContextEmptyState()) {\n <div class=\"ai-floating-assistant\">\n <button type=\"button\" praxisIconButton=\"auto_awesome\" size=\"compact\" (click)=\"openAiAssistant()\" [disabled]=\"isLoading || entityHydrationPending || entityReadFailed\"\n [attr.data-testid]=\"aiAssistantTriggerTestId('view-floating')\"\n aria-label=\"Abrir copiloto semantico Praxis do formulario\"\n matTooltip=\"Pedir ajuda sobre este formul\u00E1rio\">\n </button>\n </div>\n }\n @if (showAiAssistant && aiAssistantOpen && aiAssistantViewState) {\n <praxis-ai-assistant-shell\n [labels]=\"aiAssistantLabels\"\n [mode]=\"aiAssistantViewState.mode\"\n [state]=\"aiAssistantViewState.state\"\n [contextItems]=\"aiAssistantViewState.contextItems\"\n [attachments]=\"aiAssistantViewState.attachments\"\n [messages]=\"aiAssistantViewState.messages\"\n [quickReplies]=\"aiAssistantViewState.quickReplies\"\n [prompt]=\"aiAssistantPrompt\"\n [statusText]=\"aiAssistantViewState.statusText\"\n [errorText]=\"aiAssistantViewState.errorText\"\n [busy]=\"aiAssistantViewState.state === 'processing' || aiAssistantViewState.state === 'applying'\"\n [canApply]=\"aiAssistantViewState.canApply\"\n [layout]=\"aiAssistantLayout\"\n testIdPrefix=\"dynamic-form-ai-assistant\"\n panelTestId=\"dynamic-form-ai-assistant-panel\"\n submitTestId=\"dynamic-form-ai-assistant-submit\"\n applyTestId=\"dynamic-form-ai-assistant-apply\"\n (promptChange)=\"onAiAssistantPromptChange($event)\"\n (submitPrompt)=\"onAiAssistantSubmit($event)\"\n (apply)=\"onAiAssistantApply()\"\n (retryTurn)=\"onAiAssistantRetry()\"\n (cancelTurn)=\"onAiAssistantCancel()\"\n (quickReply)=\"onAiAssistantQuickReply($event)\"\n (editMessage)=\"onAiAssistantEditMessage($event)\"\n (resendMessage)=\"onAiAssistantResendMessage($event)\"\n (layoutChange)=\"onAiAssistantLayoutChange($event)\"\n (close)=\"closeAiAssistant()\"\n ></praxis-ai-assistant-shell>\n }\n }\n", styles: ["@charset \"UTF-8\";.span-xs-1{grid-column:span 1}.span-xs-2{grid-column:span 2}.span-xs-3{grid-column:span 3}.span-xs-4{grid-column:span 4}.span-xs-5{grid-column:span 5}.span-xs-6{grid-column:span 6}.span-xs-7{grid-column:span 7}.span-xs-8{grid-column:span 8}.span-xs-9{grid-column:span 9}.span-xs-10{grid-column:span 10}.span-xs-11{grid-column:span 11}.span-xs-12{grid-column:span 12}.offset-xs-0{margin-left:0%}.offset-xs-1{margin-left:calc(1 / 12 * 100%)}.offset-xs-2{margin-left:calc(2 / 12 * 100%)}.offset-xs-3{margin-left:25%}.offset-xs-4{margin-left:calc(4 / 12 * 100%)}.offset-xs-5{margin-left:calc(5 / 12 * 100%)}.offset-xs-6{margin-left:50%}.offset-xs-7{margin-left:calc(7 / 12 * 100%)}.offset-xs-8{margin-left:calc(8 / 12 * 100%)}.offset-xs-9{margin-left:75%}.offset-xs-10{margin-left:calc(10 / 12 * 100%)}.offset-xs-11{margin-left:calc(11 / 12 * 100%)}.order-xs--12{order:-12}.order-xs--11{order:-11}.order-xs--10{order:-10}.order-xs--9{order:-9}.order-xs--8{order:-8}.order-xs--7{order:-7}.order-xs--6{order:-6}.order-xs--5{order:-5}.order-xs--4{order:-4}.order-xs--3{order:-3}.order-xs--2{order:-2}.order-xs--1{order:-1}.order-xs-0{order:0}.order-xs-1{order:1}.order-xs-2{order:2}.order-xs-3{order:3}.order-xs-4{order:4}.order-xs-5{order:5}.order-xs-6{order:6}.order-xs-7{order:7}.order-xs-8{order:8}.order-xs-9{order:9}.order-xs-10{order:10}.order-xs-11{order:11}.order-xs-12{order:12}.hidden-xs{display:none}@container praxis-form-row (min-width: 600px){.span-sm-1{grid-column:span 1}.span-sm-2{grid-column:span 2}.span-sm-3{grid-column:span 3}.span-sm-4{grid-column:span 4}.span-sm-5{grid-column:span 5}.span-sm-6{grid-column:span 6}.span-sm-7{grid-column:span 7}.span-sm-8{grid-column:span 8}.span-sm-9{grid-column:span 9}.span-sm-10{grid-column:span 10}.span-sm-11{grid-column:span 11}.span-sm-12{grid-column:span 12}.offset-sm-0{margin-left:0%}.offset-sm-1{margin-left:calc(1 / 12 * 100%)}.offset-sm-2{margin-left:calc(2 / 12 * 100%)}.offset-sm-3{margin-left:25%}.offset-sm-4{margin-left:calc(4 / 12 * 100%)}.offset-sm-5{margin-left:calc(5 / 12 * 100%)}.offset-sm-6{margin-left:50%}.offset-sm-7{margin-left:calc(7 / 12 * 100%)}.offset-sm-8{margin-left:calc(8 / 12 * 100%)}.offset-sm-9{margin-left:75%}.offset-sm-10{margin-left:calc(10 / 12 * 100%)}.offset-sm-11{margin-left:calc(11 / 12 * 100%)}.order-sm--12{order:-12}.order-sm--11{order:-11}.order-sm--10{order:-10}.order-sm--9{order:-9}.order-sm--8{order:-8}.order-sm--7{order:-7}.order-sm--6{order:-6}.order-sm--5{order:-5}.order-sm--4{order:-4}.order-sm--3{order:-3}.order-sm--2{order:-2}.order-sm--1{order:-1}.order-sm-0{order:0}.order-sm-1{order:1}.order-sm-2{order:2}.order-sm-3{order:3}.order-sm-4{order:4}.order-sm-5{order:5}.order-sm-6{order:6}.order-sm-7{order:7}.order-sm-8{order:8}.order-sm-9{order:9}.order-sm-10{order:10}.order-sm-11{order:11}.order-sm-12{order:12}.hidden-sm{display:none}}@container praxis-form-row (min-width: 900px){.span-md-1{grid-column:span 1}.span-md-2{grid-column:span 2}.span-md-3{grid-column:span 3}.span-md-4{grid-column:span 4}.span-md-5{grid-column:span 5}.span-md-6{grid-column:span 6}.span-md-7{grid-column:span 7}.span-md-8{grid-column:span 8}.span-md-9{grid-column:span 9}.span-md-10{grid-column:span 10}.span-md-11{grid-column:span 11}.span-md-12{grid-column:span 12}.offset-md-0{margin-left:0%}.offset-md-1{margin-left:calc(1 / 12 * 100%)}.offset-md-2{margin-left:calc(2 / 12 * 100%)}.offset-md-3{margin-left:25%}.offset-md-4{margin-left:calc(4 / 12 * 100%)}.offset-md-5{margin-left:calc(5 / 12 * 100%)}.offset-md-6{margin-left:50%}.offset-md-7{margin-left:calc(7 / 12 * 100%)}.offset-md-8{margin-left:calc(8 / 12 * 100%)}.offset-md-9{margin-left:75%}.offset-md-10{margin-left:calc(10 / 12 * 100%)}.offset-md-11{margin-left:calc(11 / 12 * 100%)}.order-md--12{order:-12}.order-md--11{order:-11}.order-md--10{order:-10}.order-md--9{order:-9}.order-md--8{order:-8}.order-md--7{order:-7}.order-md--6{order:-6}.order-md--5{order:-5}.order-md--4{order:-4}.order-md--3{order:-3}.order-md--2{order:-2}.order-md--1{order:-1}.order-md-0{order:0}.order-md-1{order:1}.order-md-2{order:2}.order-md-3{order:3}.order-md-4{order:4}.order-md-5{order:5}.order-md-6{order:6}.order-md-7{order:7}.order-md-8{order:8}.order-md-9{order:9}.order-md-10{order:10}.order-md-11{order:11}.order-md-12{order:12}.hidden-md{display:none}}@container praxis-form-row (min-width: 1200px){.span-lg-1{grid-column:span 1}.span-lg-2{grid-column:span 2}.span-lg-3{grid-column:span 3}.span-lg-4{grid-column:span 4}.span-lg-5{grid-column:span 5}.span-lg-6{grid-column:span 6}.span-lg-7{grid-column:span 7}.span-lg-8{grid-column:span 8}.span-lg-9{grid-column:span 9}.span-lg-10{grid-column:span 10}.span-lg-11{grid-column:span 11}.span-lg-12{grid-column:span 12}.offset-lg-0{margin-left:0%}.offset-lg-1{margin-left:calc(1 / 12 * 100%)}.offset-lg-2{margin-left:calc(2 / 12 * 100%)}.offset-lg-3{margin-left:25%}.offset-lg-4{margin-left:calc(4 / 12 * 100%)}.offset-lg-5{margin-left:calc(5 / 12 * 100%)}.offset-lg-6{margin-left:50%}.offset-lg-7{margin-left:calc(7 / 12 * 100%)}.offset-lg-8{margin-left:calc(8 / 12 * 100%)}.offset-lg-9{margin-left:75%}.offset-lg-10{margin-left:calc(10 / 12 * 100%)}.offset-lg-11{margin-left:calc(11 / 12 * 100%)}.order-lg--12{order:-12}.order-lg--11{order:-11}.order-lg--10{order:-10}.order-lg--9{order:-9}.order-lg--8{order:-8}.order-lg--7{order:-7}.order-lg--6{order:-6}.order-lg--5{order:-5}.order-lg--4{order:-4}.order-lg--3{order:-3}.order-lg--2{order:-2}.order-lg--1{order:-1}.order-lg-0{order:0}.order-lg-1{order:1}.order-lg-2{order:2}.order-lg-3{order:3}.order-lg-4{order:4}.order-lg-5{order:5}.order-lg-6{order:6}.order-lg-7{order:7}.order-lg-8{order:8}.order-lg-9{order:9}.order-lg-10{order:10}.order-lg-11{order:11}.order-lg-12{order:12}.hidden-lg{display:none}}@container praxis-form-row (min-width: 1536px){.span-xl-1{grid-column:span 1}.span-xl-2{grid-column:span 2}.span-xl-3{grid-column:span 3}.span-xl-4{grid-column:span 4}.span-xl-5{grid-column:span 5}.span-xl-6{grid-column:span 6}.span-xl-7{grid-column:span 7}.span-xl-8{grid-column:span 8}.span-xl-9{grid-column:span 9}.span-xl-10{grid-column:span 10}.span-xl-11{grid-column:span 11}.span-xl-12{grid-column:span 12}.offset-xl-0{margin-left:0%}.offset-xl-1{margin-left:calc(1 / 12 * 100%)}.offset-xl-2{margin-left:calc(2 / 12 * 100%)}.offset-xl-3{margin-left:25%}.offset-xl-4{margin-left:calc(4 / 12 * 100%)}.offset-xl-5{margin-left:calc(5 / 12 * 100%)}.offset-xl-6{margin-left:50%}.offset-xl-7{margin-left:calc(7 / 12 * 100%)}.offset-xl-8{margin-left:calc(8 / 12 * 100%)}.offset-xl-9{margin-left:75%}.offset-xl-10{margin-left:calc(10 / 12 * 100%)}.offset-xl-11{margin-left:calc(11 / 12 * 100%)}.order-xl--12{order:-12}.order-xl--11{order:-11}.order-xl--10{order:-10}.order-xl--9{order:-9}.order-xl--8{order:-8}.order-xl--7{order:-7}.order-xl--6{order:-6}.order-xl--5{order:-5}.order-xl--4{order:-4}.order-xl--3{order:-3}.order-xl--2{order:-2}.order-xl--1{order:-1}.order-xl-0{order:0}.order-xl-1{order:1}.order-xl-2{order:2}.order-xl-3{order:3}.order-xl-4{order:4}.order-xl-5{order:5}.order-xl-6{order:6}.order-xl-7{order:7}.order-xl-8{order:8}.order-xl-9{order:9}.order-xl-10{order:10}.order-xl-11{order:11}.order-xl-12{order:12}.hidden-xl{display:none}}.canvas-mode-enabled{--canvas-hit: 14px}.canvas-mode-enabled .canvas-element{position:relative;z-index:0;border-radius:8px;outline:2px solid transparent;outline-offset:2px;transition:outline-color .2s ease,outline-style .2s ease}.canvas-mode-enabled .canvas-element:before{content:\"\";position:absolute;inset:calc(-1 * var(--canvas-hit));pointer-events:none;border-radius:inherit;background:transparent}.canvas-mode-enabled .canvas-element[data-canvas-type=section]{--outline-color: var(--md-sys-color-primary)}.canvas-mode-enabled .canvas-element[data-canvas-type=row]{--outline-color: var(--md-sys-color-secondary)}.canvas-mode-enabled .canvas-element[data-canvas-type=column],.canvas-mode-enabled .canvas-element[data-canvas-type=field]{--outline-color: var(--md-sys-color-tertiary)}.canvas-mode-enabled .canvas-element[data-canvas-type=actions]{--outline-color: var(--md-sys-color-primary)}.canvas-mode-enabled .canvas-element.hovered:not(.selected){outline-color:var(--outline-color, var(--md-sys-color-primary));outline-style:dashed}.canvas-mode-enabled .canvas-element.selected{outline-color:var(--outline-color, var(--md-sys-color-primary));outline-style:solid;box-shadow:0 0 0 2px var(--outline-color, var(--md-sys-color-primary))}.canvas-mode-enabled .canvas-element.hovered{z-index:var(--praxis-layer-authoring-hover, 300)}.canvas-mode-enabled .canvas-element.selected{z-index:var(--praxis-layer-authoring-selected, 320)}.section-drop-wrapper,.row-drop-wrapper,.column-drop-wrapper{display:contents}.add-section-container{display:flex;align-items:center;justify-content:center;padding:.5rem 0;margin:-.5rem 0;position:relative;z-index:var(--praxis-layer-authoring-insert, 280)}.add-section-container .add-section-line{flex-grow:1;height:1px;background:repeating-linear-gradient(90deg,var(--md-sys-color-outline-variant),var(--md-sys-color-outline-variant) 4px,transparent 4px,transparent 8px)}.add-section-container button{margin:0 1rem;transform:scale(.85)}:host{display:block;position:relative;--pfx-editorial-form-radius: var(--pfx-form-section-radius, 8px);--pfx-editorial-form-border: var( --pfx-form-stroke, var(--pdx-color-border-subtle, var(--md-sys-color-outline-variant)) );--pfx-editorial-form-surface: var( --pfx-form-section-surface, var(--pdx-color-surface, var(--md-sys-color-surface-container)) );--pfx-editorial-form-surface-muted: var( --pdx-color-surface-muted, var(--md-sys-color-surface-container-low) );--pfx-form-shell-surface: color-mix( in srgb, var(--pfx-editorial-form-surface) 36%, transparent );--pfx-form-section-divider: color-mix( in srgb, var(--pfx-editorial-form-border) 68%, transparent );--pfx-form-footer-surface: color-mix( in srgb, var(--pfx-editorial-form-surface) 70%, var(--pfx-editorial-form-surface-muted) 30% );--pfx-form-footer-border: color-mix( in srgb, var(--pfx-editorial-form-border) 76%, transparent );--pfx-form-shell-padding: clamp(.9rem, 1.4vw, 1.2rem)}.form-config-controls{position:relative;top:auto;margin:0;display:flex;align-items:center;gap:.35rem;z-index:60;background:color-mix(in srgb,var(--pfx-form-shell-surface) 88%,var(--md-sys-color-surface) 12%);padding:8px var(--pfx-form-shell-padding);border:1px solid var(--pfx-form-footer-border);border-bottom-color:color-mix(in srgb,var(--pfx-form-footer-border) 72%,transparent);border-radius:var(--pfx-editorial-form-radius) var(--pfx-editorial-form-radius) 0 0;-webkit-backdrop-filter:blur(12px);backdrop-filter:blur(12px);box-shadow:none;min-width:0;justify-content:flex-end;pointer-events:none;opacity:.96;transition:opacity .16s ease,border-color .16s ease}.form-config-controls>*{pointer-events:auto}.form-config-controls:hover,.form-config-controls:focus-within{opacity:1;border-color:color-mix(in srgb,var(--md-sys-color-primary) 26%,var(--md-sys-color-outline-variant) 74%)}.form-config-controls .praxis-icon-button{color:var(--md-sys-color-on-surface-variant)}.form-config-controls .praxis-icon-button:hover{color:var(--md-sys-color-primary)}.ai-floating-assistant{position:sticky;right:0;bottom:12px;margin-top:14px;margin-left:auto;width:fit-content;z-index:70;pointer-events:none}.ai-floating-assistant button{pointer-events:auto;display:inline-flex}.ai-floating-assistant .ai-trigger-btn{box-shadow:0 12px 28px #0f172a24}.config-button{color:var(--md-sys-color-primary)}.form-loading{display:flex;flex-direction:column;align-items:stretch;justify-content:center;padding:1.25rem;text-align:left;color:var(--md-sys-color-on-surface);gap:1rem;min-height:220px;border:1px solid color-mix(in srgb,var(--md-sys-color-primary) 14%,var(--md-sys-color-outline-variant) 86%);border-radius:8px;background:linear-gradient(135deg,color-mix(in srgb,var(--md-sys-color-primary) 8%,transparent),transparent 42%),color-mix(in srgb,var(--md-sys-color-surface-container-low) 78%,var(--md-sys-color-surface) 22%);box-shadow:0 12px 28px #0f172a14}.entity-read-region{position:relative;min-width:0}.entity-read-feedback{position:absolute;inset:0;display:flex;flex-direction:column;align-items:center;justify-content:flex-start;gap:1rem;padding:2rem 1rem;box-sizing:border-box;text-align:center;color:var(--md-sys-color-on-surface)}.entity-read-feedback p{margin:0;max-width:40ch}.form-loading-header{display:flex;align-items:center;gap:.85rem}.form-loading-copy{min-width:0}.form-loading p{margin:0}.form-loading-title{font-weight:700;color:var(--md-sys-color-on-surface)}.form-loading-subtitle{margin-top:.2rem;font-size:.875rem;color:var(--md-sys-color-on-surface-variant)}.form-loading-skeleton{display:grid;gap:.7rem}.form-loading-line,.form-loading-field{display:block;overflow:hidden;position:relative;border-radius:6px;background:color-mix(in srgb,var(--md-sys-color-surface-container-high) 74%,var(--md-sys-color-primary) 6%)}.form-loading-line:after,.form-loading-field:after{content:\"\";position:absolute;inset:0;transform:translate(-100%);background:linear-gradient(90deg,transparent,color-mix(in srgb,var(--md-sys-color-primary) 16%,var(--md-sys-color-on-surface) 18%),transparent);animation:form-loading-shimmer 1.4s ease-in-out infinite}.form-loading-line{height:12px}.form-loading-line-title{width:min(42%,240px)}.form-loading-line-short{width:min(64%,360px)}.form-loading-field{height:44px}.form-loading-field-wide{height:72px}@keyframes form-loading-shimmer{to{transform:translate(100%)}}@media(prefers-reduced-motion:reduce){.form-loading-line:after,.form-loading-field:after{animation:none;transform:none;opacity:.28}}.form-error{display:flex;flex-direction:column;align-items:center;justify-content:center;padding:3rem;text-align:center;color:var(--md-sys-color-error);gap:1rem;border:1px solid var(--md-sys-color-error);border-radius:8px;background-color:var(--md-sys-color-error-container);margin:1rem;box-shadow:0 12px 30px #7f1d1d1f}.form-error h3{margin:0;color:var(--md-sys-color-on-error-container)}.form-error p{margin:0;color:var(--md-sys-color-on-error-container);opacity:.8}.form-error button{margin-top:.5rem}.pfx-form-info-banner{margin-bottom:14px;padding:12px 14px;border-radius:16px;border:1px solid color-mix(in srgb,var(--md-sys-color-primary) 18%,var(--md-sys-color-outline-variant) 82%);background:color-mix(in srgb,var(--md-sys-color-primary-container) 24%,var(--md-sys-color-surface) 76%);color:var(--md-sys-color-on-surface);display:flex;align-items:flex-start;justify-content:space-between;gap:14px}.pfx-form-info-banner .text{font-size:.92rem;line-height:1.5;font-weight:600}.pfx-form-info-banner .actions{display:flex;flex-wrap:wrap;justify-content:flex-end;gap:8px}.praxis-dynamic-form{display:flex;flex-direction:column;max-width:100%;min-width:0;transition:all .3s ease;position:relative;font-family:inherit;font-size:inherit;color:inherit;--pfx-editorial-form-surface: var( --pfx-form-section-surface, var(--md-sys-color-surface-container) );--pfx-editorial-form-surface-muted: var( --pdx-color-surface-muted, var(--md-sys-color-surface-container-low) );--pfx-editorial-form-border: var( --pfx-form-stroke, var(--pdx-color-border-subtle, var(--md-sys-color-outline-variant)) );--pfx-editorial-form-text: var( --pdx-color-text-primary, var(--md-sys-color-on-surface) );--pfx-editorial-form-text-muted: var( --pdx-color-text-secondary, var(--md-sys-color-on-surface-variant) );--pfx-editorial-form-field-surface: color-mix( in srgb, var(--pfx-editorial-form-surface-muted) 76%, var(--pfx-editorial-form-surface) 24% );--pfx-editorial-form-field-outline: color-mix( in srgb, var(--pfx-editorial-form-border) 88%, transparent );--pfx-editorial-form-accent: var( --pdx-color-primary, var(--md-sys-color-primary) );--pfx-editorial-form-accent-text: var(--md-sys-color-on-primary);--pfx-editorial-form-radius: var(--pfx-form-section-radius, 8px);--pfx-editorial-form-field-radius: var(--pfx-form-field-radius, 4px);--pfx-editorial-form-border-width: 1px;--pfx-editorial-form-field-border-width: 1px;--pfx-editorial-form-shadow: none;--pfx-form-shell-surface: color-mix( in srgb, var(--pfx-editorial-form-surface) 36%, transparent );--pfx-form-section-surface-flat: color-mix( in srgb, var(--pfx-editorial-form-surface) 78%, var(--pfx-editorial-form-surface-muted) 22% );--pfx-form-section-divider: color-mix( in srgb, var(--pfx-editorial-form-border) 68%, transparent );--pfx-form-label-strong: color-mix( in srgb, var(--pfx-editorial-form-text) 96%, white 4% );--pfx-form-label-muted: color-mix( in srgb, var(--pfx-editorial-form-text-muted) 92%, var(--pfx-editorial-form-text) 8% );--pfx-form-field-surface-rest: color-mix( in srgb, var(--pfx-editorial-form-field-surface) 82%, var(--pfx-editorial-form-surface) 18% );--pfx-form-field-surface-focus: color-mix( in srgb, var(--pfx-editorial-form-accent) 4%, var(--pfx-form-field-surface-rest) 96% );--pfx-form-field-min-height: 48px;--pfx-form-section-padding: clamp(1.1rem, 1.8vw, 1.5rem);--pfx-form-section-gap: 22px;--pdx-presentation-label-size: var(--pfx-pres-compact-label-size, .78rem);--pdx-presentation-value-size: var(--pfx-pres-compact-value-size, 1rem);--pdx-presentation-icon-size: var(--pfx-pres-icon-size, 18px);--pdx-presentation-row-gap: var(--pfx-pres-row-gap, .5rem);--pdx-presentation-column-gap: var(--pfx-pres-column-gap, .5rem);--pdx-presentation-section-gap: var(--pfx-pres-section-gap, .75rem);--pdx-presentation-label-width: var(--pfx-pres-label-width, 220px);--pdx-presentation-flag-height: var(--pfx-pres-boolean-min-height, 22px);--pdx-presentation-flag-radius: var(--pfx-pres-boolean-radius, 999px);--pdx-presentation-flag-padding: var(--pfx-pres-boolean-padding, 0 8px);--pdx-presentation-flag-active-color: var( --pfx-pres-boolean-active-color, var(--md-sys-color-primary) );--pdx-presentation-flag-active-bg: var( --pfx-pres-boolean-active-bg, color-mix(in srgb, var(--md-sys-color-primary) 14%, transparent) );--pdx-presentation-flag-inactive-color: var( --pfx-pres-boolean-inactive-color, var(--md-sys-color-on-surface-variant) );--pdx-presentation-flag-inactive-bg: var( --pfx-pres-boolean-inactive-bg, color-mix(in srgb, var(--md-sys-color-outline-variant) 34%, transparent) );--pfx-form-footer-surface: color-mix( in srgb, var(--pfx-editorial-form-surface) 70%, var(--pfx-editorial-form-surface-muted) 30% );--pfx-form-footer-border: color-mix( in srgb, var(--pfx-editorial-form-border) 76%, transparent )}.praxis-dynamic-form.canvas-mode-enabled{border:1px solid var(--pfx-form-footer-border);border-radius:var(--pfx-editorial-form-radius);background:linear-gradient(180deg,color-mix(in srgb,var(--pfx-form-shell-surface) 86%,transparent),color-mix(in srgb,var(--pfx-editorial-form-surface-muted) 42%,transparent));overflow:visible}.form-config-controls+.praxis-dynamic-form.canvas-mode-enabled{border-top:0;border-top-left-radius:0;border-top-right-radius:0}.praxis-dynamic-form.canvas-mode-enabled>.section-drop-wrapper,.praxis-dynamic-form.canvas-mode-enabled>.form-editorial-blocks{margin-inline:var(--pfx-form-shell-padding)}.praxis-dynamic-form.canvas-mode-enabled>.section-drop-wrapper:first-of-type,.praxis-dynamic-form.canvas-mode-enabled>.form-editorial-blocks:first-child{margin-top:var(--pfx-form-shell-padding)}.praxis-dynamic-form.canvas-mode-enabled>praxis-form-actions[data-actions-placement=afterSections]{display:block;margin-top:var(--pfx-form-shell-padding)}.praxis-dynamic-form.editorial-visual-context{--_pfx-editorial-host-text: var( --editorial-text-primary, var(--foreground, var(--mat-sys-on-surface, #1d1b20)) );--_pfx-editorial-host-text-muted: var( --editorial-text-secondary, var( --muted-foreground, color-mix(in srgb, var(--_pfx-editorial-host-text) 64%, transparent) ) );--_pfx-editorial-host-surface: var( --editorial-surface-primary, var(--card, var(--mat-sys-surface-container, #ffffff)) );--_pfx-editorial-host-surface-muted: var( --editorial-surface-secondary, var(--surface-dim, var(--muted, var(--mat-sys-surface-container-low, #f7f2fa))) );--_pfx-editorial-host-border: var( --editorial-border-color, var(--border, var(--mat-sys-outline-variant, #cac4d0)) );--_pfx-editorial-host-accent: var( --editorial-cta-primary, var(--editorial-accent, var(--primary, var(--mat-sys-primary, #6750a4))) );--_pfx-editorial-host-accent-text: var( --editorial-cta-primary-text, var( --editorial-accent-contrast, var(--primary-foreground, var(--mat-sys-on-primary, #ffffff)) ) );--_pfx-editorial-host-accent-container: var( --primary-container, color-mix(in srgb, var(--_pfx-editorial-host-accent) 16%, var(--_pfx-editorial-host-surface) 84%) );--_pfx-editorial-host-accent-container-text: var( --primary-container-fg, var(--_pfx-editorial-host-accent) );font-family:var(--editorial-body-font-family, inherit);font-size:var(--editorial-body-size, 1rem);color:var(--_pfx-editorial-host-text);--pfx-editorial-form-surface: var( --editorial-surface-primary, var(--pfx-form-section-surface, var(--_pfx-editorial-host-surface)) );--pfx-editorial-form-surface-muted: var( --editorial-surface-secondary, var(--_pfx-editorial-host-surface-muted) );--pfx-editorial-form-border: var( --editorial-border-color, var(--pfx-form-stroke, var(--_pfx-editorial-host-border)) );--pfx-editorial-form-text: var( --editorial-text-primary, var(--_pfx-editorial-host-text) );--pfx-editorial-form-text-muted: var( --editorial-text-secondary, color-mix( in srgb, var(--_pfx-editorial-host-text-muted) 86%, var(--_pfx-editorial-host-text) 14% ) );--pfx-editorial-form-accent: var( --editorial-cta-primary, var(--editorial-accent, var(--_pfx-editorial-host-accent)) );--pfx-editorial-form-accent-text: var( --editorial-cta-primary-text, var(--editorial-accent-contrast, var(--_pfx-editorial-host-accent-text)) );--pfx-editorial-form-accent-container: var(--_pfx-editorial-host-accent-container);--pfx-editorial-form-accent-container-text: var(--_pfx-editorial-host-accent-container-text);--pfx-editorial-form-radius: var(--editorial-card-radius, 18px);--pfx-editorial-form-field-radius: var( --editorial-field-radius, var(--editorial-card-radius, 14px) );--pfx-editorial-form-border-width: var(--editorial-card-border-width, 1px);--pfx-editorial-form-field-border-width: var(--editorial-field-border-width, 1px);--pfx-editorial-form-shadow: var(--editorial-card-shadow, none);--md-sys-color-surface: var( --pfx-editorial-form-surface, var(--md-sys-color-surface) );--md-sys-color-surface-container: var( --pfx-editorial-form-surface, var(--md-sys-color-surface-container) );--md-sys-color-surface-container-low: var( --pfx-editorial-form-surface-muted, var(--md-sys-color-surface-container-low) );--md-sys-color-surface-variant: var( --pfx-editorial-form-field-surface, var(--md-sys-color-surface-variant) );--md-sys-color-outline: var( --pfx-editorial-form-field-outline, var(--md-sys-color-outline) );--md-sys-color-outline-variant: var( --pfx-editorial-form-border, var(--md-sys-color-outline-variant) );--md-sys-color-on-surface: var( --editorial-text-primary, inherit );--md-sys-color-on-surface-variant: var( --editorial-text-secondary, inherit );--md-sys-color-primary: var( --pfx-editorial-form-accent, var(--md-sys-color-primary) );--md-sys-color-primary-container: var( --pfx-editorial-form-accent-container, var(--md-sys-color-primary-container) );--md-sys-color-on-primary-container: var( --pfx-editorial-form-accent-container-text, var(--md-sys-color-on-primary-container) );--md-sys-color-on-primary: var( --pfx-editorial-form-accent-text, var(--md-sys-color-on-primary) );--md-sys-color-on-surface-rgb: var( --editorial-text-primary-rgb, inherit );--mat-sys-on-surface: var( --editorial-text-primary, inherit );--mat-sys-on-surface-variant: var( --editorial-text-secondary, inherit );--mat-sys-on-surface-rgb: var( --editorial-text-primary-rgb, inherit );color:inherit;color-scheme:light}.praxis-dynamic-form.presentation-mode .form-row,.praxis-dynamic-form.readonly-mode .form-row{gap:var(--pdx-presentation-column-gap);margin-bottom:var(--pdx-presentation-row-gap)}.praxis-dynamic-form.presentation-mode{--pfx-pres-on-surface: var( --pdx-color-text-primary, var(--pfx-editorial-form-text, var(--pfx-form-label-strong, currentColor)) );--pfx-pres-on-surface-variant: var( --pdx-color-text-secondary, var( --pfx-editorial-form-text-muted, var( --pfx-form-label-muted, color-mix(in srgb, var(--pfx-pres-on-surface) 78%, transparent) ) ) )}.praxis-dynamic-form.presentation-mode .form-section,.praxis-dynamic-form.readonly-mode .form-section{padding:var(--pdx-presentation-section-gap) .875rem}.praxis-dynamic-form.pres-compact .form-row{gap:var(--pdx-presentation-column-gap, .35rem);margin-bottom:var(--pdx-presentation-row-gap, .35rem)}.praxis-dynamic-form.pres-compact .form-section{padding:var(--pdx-presentation-section-gap, .5rem) .75rem}.praxis-dynamic-form.pres-label-left .praxis-presentation{display:grid;grid-template-columns:minmax(0,var(--pfx-presentation-label-w, var(--pdx-presentation-label-width))) minmax(0,1fr);align-items:baseline;column-gap:var(--pdx-presentation-column-gap, 10px)}.praxis-dynamic-form.pres-label-left .praxis-presentation__label{text-align:right;margin-bottom:0}@media(max-width:480px){.praxis-dynamic-form.pres-label-left .praxis-presentation{grid-template-columns:minmax(0,1fr);row-gap:4px}.praxis-dynamic-form.pres-label-left .praxis-presentation__label{text-align:start}}.praxis-dynamic-form.praxis-dynamic-form--corporate-dossier .form-section:not(.section-appearance-plain),.praxis-dynamic-form .form-section.form-section--corporate-dossier:not(.section-appearance-plain),.praxis-dynamic-form .form-section[data-presentation-preset=corporate-dossier]:not(.section-appearance-plain){background:var(--md-sys-color-surface-container-low, #f8f9fa);border:1px solid var(--md-sys-color-outline-variant, #e0e2ec);border-radius:16px;padding:16px 20px;box-shadow:0 1px 3px #0000000a}.praxis-dynamic-form.praxis-dynamic-form--corporate-dossier .form-section .section-heading,.praxis-dynamic-form .form-section.form-section--corporate-dossier .section-heading,.praxis-dynamic-form .form-section[data-presentation-preset=corporate-dossier] .section-heading{margin-bottom:12px;padding-bottom:8px;border-bottom:1px solid var(--md-sys-color-outline-variant, #e0e2ec)}.praxis-dynamic-form.praxis-dynamic-form--corporate-dossier .form-section .section-title,.praxis-dynamic-form .form-section.form-section--corporate-dossier .section-title,.praxis-dynamic-form .form-section[data-presentation-preset=corporate-dossier] .section-title{font-size:.88rem;font-weight:700;letter-spacing:.05em;text-transform:uppercase;color:var(--md-sys-color-primary, #005ac1)}:host ::ng-deep .praxis-dynamic-form--corporate-dossier .praxis-presentation,:host ::ng-deep .form-section--corporate-dossier .praxis-presentation,:host ::ng-deep [data-presentation-preset=corporate-dossier] .praxis-presentation{padding:8px 0;border-bottom:1px dashed var(--md-sys-color-outline-variant, rgba(0, 0, 0, .08))}:host ::ng-deep .praxis-dynamic-form--corporate-dossier .form-row:last-child .praxis-presentation,:host ::ng-deep .praxis-dynamic-form--corporate-dossier .praxis-presentation:last-child,:host ::ng-deep .form-section--corporate-dossier .form-row:last-child .praxis-presentation,:host ::ng-deep .form-section--corporate-dossier .praxis-presentation:last-child,:host ::ng-deep [data-presentation-preset=corporate-dossier] .form-row:last-child .praxis-presentation,:host ::ng-deep [data-presentation-preset=corporate-dossier] .praxis-presentation:last-child{border-bottom:none}:host ::ng-deep .praxis-dynamic-form--corporate-dossier .praxis-presentation__label,:host ::ng-deep .form-section--corporate-dossier .praxis-presentation__label,:host ::ng-deep [data-presentation-preset=corporate-dossier] .praxis-presentation__label{font-size:.74rem;font-weight:600;text-transform:uppercase;letter-spacing:.05em;color:var(--md-sys-color-on-surface-variant, #44474f);margin-bottom:3px}:host ::ng-deep .praxis-dynamic-form--corporate-dossier .praxis-presentation__value,:host ::ng-deep .form-section--corporate-dossier .praxis-presentation__value,:host ::ng-deep [data-presentation-preset=corporate-dossier] .praxis-presentation__value{font-size:.95rem;font-weight:600;color:var(--md-sys-color-on-surface, #1a1c1e);line-height:1.4}.praxis-dynamic-form.praxis-dynamic-form--editorial-card .form-section:not(.section-appearance-plain),.praxis-dynamic-form .form-section.form-section--editorial-card:not(.section-appearance-plain),.praxis-dynamic-form .form-section[data-presentation-preset=editorial-card]:not(.section-appearance-plain){background:var(--pfx-editorial-form-surface, var(--md-sys-color-surface-container-low, var(--mat-sys-surface-container-low)));border:1px solid var(--pfx-editorial-form-border, var(--md-sys-color-outline-variant, #e0e2ec));border-radius:20px;padding:24px;box-shadow:0 2px 8px #0000000d}.praxis-dynamic-form.praxis-dynamic-form--editorial-card .form-section .section-heading,.praxis-dynamic-form .form-section.form-section--editorial-card .section-heading,.praxis-dynamic-form .form-section[data-presentation-preset=editorial-card] .section-heading{margin-bottom:16px;padding-bottom:10px;border-bottom:1px solid color-mix(in srgb,var(--md-sys-color-outline-variant, #e0e2ec) 40%,transparent)}.praxis-dynamic-form.praxis-dynamic-form--editorial-card .form-section .section-title,.praxis-dynamic-form .form-section.form-section--editorial-card .section-title,.praxis-dynamic-form .form-section[data-presentation-preset=editorial-card] .section-title{font-size:1.15rem;font-weight:700;color:var(--pfx-editorial-form-accent, var(--md-sys-color-primary, #005ac1))}:host ::ng-deep .praxis-dynamic-form--editorial-card .praxis-presentation,:host ::ng-deep .form-section--editorial-card .praxis-presentation,:host ::ng-deep [data-presentation-preset=editorial-card] .praxis-presentation{padding:10px 0;border-bottom:1px solid color-mix(in srgb,var(--md-sys-color-outline-variant, #e0e2ec) 35%,transparent)}:host ::ng-deep .praxis-dynamic-form--editorial-card .form-row:last-child .praxis-presentation,:host ::ng-deep .praxis-dynamic-form--editorial-card .praxis-presentation:last-child,:host ::ng-deep .form-section--editorial-card .form-row:last-child .praxis-presentation,:host ::ng-deep .form-section--editorial-card .praxis-presentation:last-child,:host ::ng-deep [data-presentation-preset=editorial-card] .form-row:last-child .praxis-presentation,:host ::ng-deep [data-presentation-preset=editorial-card] .praxis-presentation:last-child{border-bottom:none}:host ::ng-deep .praxis-dynamic-form--editorial-card .praxis-presentation__label,:host ::ng-deep .form-section--editorial-card .praxis-presentation__label,:host ::ng-deep [data-presentation-preset=editorial-card] .praxis-presentation__label{font-size:.8rem;font-weight:500;color:var(--pfx-editorial-form-text-muted, var(--md-sys-color-on-surface-variant, #44474f));margin-bottom:4px}:host ::ng-deep .praxis-dynamic-form--editorial-card .praxis-presentation__value,:host ::ng-deep .form-section--editorial-card .praxis-presentation__value,:host ::ng-deep [data-presentation-preset=editorial-card] .praxis-presentation__value{font-size:1rem;font-weight:600;color:var(--pfx-editorial-form-text, var(--md-sys-color-on-surface, #1a1c1e));line-height:1.5}.praxis-dynamic-form.praxis-dynamic-form--compact-presentation .form-section:not(.section-appearance-plain),.praxis-dynamic-form .form-section.form-section--compact-presentation:not(.section-appearance-plain),.praxis-dynamic-form .form-section[data-presentation-preset=compact-presentation]:not(.section-appearance-plain){background:transparent;border:1px solid color-mix(in srgb,var(--md-sys-color-outline-variant, #e0e2ec) 50%,transparent);border-radius:8px;padding:10px 14px;box-shadow:none}.praxis-dynamic-form.praxis-dynamic-form--compact-presentation .form-section .section-heading,.praxis-dynamic-form .form-section.form-section--compact-presentation .section-heading,.praxis-dynamic-form .form-section[data-presentation-preset=compact-presentation] .section-heading{margin-bottom:8px;padding-bottom:4px;border-bottom:1px solid color-mix(in srgb,var(--md-sys-color-outline-variant, #e0e2ec) 25%,transparent)}.praxis-dynamic-form.praxis-dynamic-form--compact-presentation .form-section .section-title,.praxis-dynamic-form .form-section.form-section--compact-presentation .section-title,.praxis-dynamic-form .form-section[data-presentation-preset=compact-presentation] .section-title{font-size:.82rem;font-weight:700;letter-spacing:.03em;text-transform:uppercase;color:var(--md-sys-color-on-surface-variant, #44474f)}:host ::ng-deep .praxis-dynamic-form--compact-presentation .praxis-presentation,:host ::ng-deep .form-section--compact-presentation .praxis-presentation,:host ::ng-deep [data-presentation-preset=compact-presentation] .praxis-presentation{padding:4px 0;border-bottom:none}:host ::ng-deep .praxis-dynamic-form--compact-presentation .praxis-presentation__label,:host ::ng-deep .form-section--compact-presentation .praxis-presentation__label,:host ::ng-deep [data-presentation-preset=compact-presentation] .praxis-presentation__label{font-size:.72rem;font-weight:600;color:var(--md-sys-color-on-surface-variant, #44474f);margin-bottom:2px}:host ::ng-deep .praxis-dynamic-form--compact-presentation .praxis-presentation__value,:host ::ng-deep .form-section--compact-presentation .praxis-presentation__value,:host ::ng-deep [data-presentation-preset=compact-presentation] .praxis-presentation__value{font-size:.88rem;font-weight:500;color:var(--md-sys-color-on-surface, #1a1c1e);line-height:1.35}:host-context(.mdc-theme-dark) .praxis-dynamic-form.praxis-dynamic-form--corporate-dossier .form-section:not(.section-appearance-plain),:host-context(.mdc-theme-dark) .praxis-dynamic-form .form-section.form-section--corporate-dossier:not(.section-appearance-plain),:host-context(.mdc-theme-dark) .praxis-dynamic-form .form-section[data-presentation-preset=corporate-dossier]:not(.section-appearance-plain),:host-context(.theme-dark) .praxis-dynamic-form.praxis-dynamic-form--corporate-dossier .form-section:not(.section-appearance-plain),:host-context(.theme-dark) .praxis-dynamic-form .form-section.form-section--corporate-dossier:not(.section-appearance-plain),:host-context(.theme-dark) .praxis-dynamic-form .form-section[data-presentation-preset=corporate-dossier]:not(.section-appearance-plain){background:var(--md-sys-color-surface-container-low);border-color:color-mix(in srgb,var(--md-sys-color-outline-variant) 70%,transparent);box-shadow:0 2px 8px #0000004d}:host-context(.mdc-theme-dark) .praxis-dynamic-form.praxis-dynamic-form--editorial-card .form-section:not(.section-appearance-plain),:host-context(.mdc-theme-dark) .praxis-dynamic-form .form-section.form-section--editorial-card:not(.section-appearance-plain),:host-context(.mdc-theme-dark) .praxis-dynamic-form .form-section[data-presentation-preset=editorial-card]:not(.section-appearance-plain),:host-context(.theme-dark) .praxis-dynamic-form.praxis-dynamic-form--editorial-card .form-section:not(.section-appearance-plain),:host-context(.theme-dark) .praxis-dynamic-form .form-section.form-section--editorial-card:not(.section-appearance-plain),:host-context(.theme-dark) .praxis-dynamic-form .form-section[data-presentation-preset=editorial-card]:not(.section-appearance-plain){background:var(--pfx-editorial-form-surface, var(--md-sys-color-surface-container-low));border-color:color-mix(in srgb,var(--md-sys-color-outline-variant) 70%,transparent);box-shadow:0 4px 16px #0006}.form-section{border:1px solid var(--pfx-form-section-divider);border-radius:var(--pfx-editorial-form-radius);padding:var(--pfx-form-section-padding);max-width:100%;min-width:0;background:var(--pfx-form-section-surface-flat);box-shadow:none;transition:all .2s ease;position:relative}.praxis-dynamic-form.editorial-visual-context .form-section:not(.section-appearance-plain){border:var(--pfx-editorial-form-border-width) solid var(--pfx-editorial-form-border)!important;background:var(--pfx-editorial-form-surface)!important;color:var(--pfx-editorial-form-text);box-shadow:var(--editorial-card-shadow, none)}.praxis-dynamic-form.editorial-visual-context .form-section.section-appearance-step{background-color:var(--pfx-editorial-form-surface)!important;background-image:linear-gradient(180deg,color-mix(in srgb,var(--editorial-accent, var(--md-sys-color-primary)) 6%,transparent) 0%,transparent 132px)!important;background-repeat:no-repeat!important}.section-drop-wrapper>.form-section{margin-bottom:var(--pfx-section-gap, 20px)}.section-drop-wrapper:last-of-type>.form-section{margin-bottom:0}.praxis-dynamic-form>praxis-form-actions[data-actions-placement=afterSections]{margin-top:var(--pfx-actions-gap-top, var(--pfx-section-gap, 20px))}.section-title{margin:0 0 var(--pfx-section-title-mb, 12px) 0;font-family:var(--editorial-title-font-family, var(--editorial-body-font-family, inherit));font-size:var(--editorial-step-title-size, 1.12rem);font-weight:700;color:var(--pfx-form-label-strong)}.section-heading{position:relative;display:flex;align-items:flex-start;gap:12px;margin-bottom:18px;padding-bottom:var(--pfx-form-section-heading-divider-gap, 18px)}.section-heading:after{content:\"\";position:absolute;right:0;bottom:0;left:0;height:2px;pointer-events:none;background:linear-gradient(90deg,transparent 0%,color-mix(in srgb,var(--pfx-form-section-divider) 18%,transparent) 8%,var(--pfx-form-section-divider) 46%,var(--pfx-form-section-divider) 54%,color-mix(in srgb,var(--pfx-form-section-divider) 18%,transparent) 92%,transparent 100%);border-radius:999px;-webkit-mask-image:linear-gradient(90deg,transparent 0%,black 18%,black 82%,transparent 100%);mask-image:linear-gradient(90deg,transparent 0%,black 18%,black 82%,transparent 100%)}.section-heading.title-only{padding-bottom:var(--pfx-form-section-heading-title-only-divider-gap, 10px)}:host(.pfx-form-section-divider-inline-title) .section-heading.title-only{padding-bottom:var(--pfx-form-section-heading-title-only-inline-divider-gap, 0)}:host(.pfx-form-section-divider-inline-title) .section-heading.title-only:after{display:none}.section-heading.align-center{flex-direction:column;align-items:center;text-align:center}.section-heading.align-center .section-heading-text{display:grid;justify-items:center}.section-step-label{display:inline-flex;align-items:center;min-height:24px;padding:0 10px;margin:0 0 8px;border-radius:999px;background:color-mix(in srgb,var(--pfx-editorial-form-accent) 10%,transparent);color:color-mix(in srgb,var(--pfx-editorial-form-accent) 84%,var(--pfx-form-label-strong) 16%);font-size:.72rem;font-weight:800;font-family:var(--editorial-title-font-family, var(--editorial-body-font-family, inherit));letter-spacing:.08em;text-transform:uppercase}.section-heading-text{flex:1 1 auto;min-width:0}.section-heading-actions{display:inline-flex;align-items:center;align-self:flex-start;flex-wrap:wrap;gap:4px;margin-left:auto}.section-heading-actions.align-center{align-self:center;margin-left:0}.section-heading-action-btn{color:var(--pfx-form-label-muted)}.section-heading-action-btn.tone-primary{color:var(--md-sys-color-primary)}.section-heading-action-btn.tone-accent,.section-heading-action-btn.tone-secondary{color:var(--md-sys-color-tertiary)}.section-heading-action-btn.tone-warn,.section-heading-action-btn.tone-danger,.section-heading-action-btn.tone-error{color:var(--md-sys-color-error)}.section-heading-action-btn .mat-mdc-progress-spinner,.section-heading-action-btn mat-progress-spinner{--mdc-circular-progress-active-indicator-color: currentColor}.section-heading-action-btn.loading{opacity:.72;pointer-events:none}.section-heading-action-sr-only{position:absolute;width:1px;height:1px;padding:0;margin:-1px;overflow:hidden;clip:rect(0,0,0,0);white-space:nowrap;border:0}.section-collapse-btn{margin-left:4px;color:var(--pfx-form-label-muted)}.section-title.title-large{font:var(--mdc-typography-title-large, 500 22px/28px system-ui)}.section-title.title-medium{font:var(--mdc-typography-title-medium, 500 16px/24px system-ui)}.section-title.title-small{font:var(--mdc-typography-title-small, 500 14px/20px system-ui)}.section-title.headline-small{font:var(--mdc-typography-headline-small, 600 24px/32px system-ui)}.section-title.title-large,.section-title.title-medium,.section-title.title-small,.section-title.headline-small{font-family:var(--editorial-title-font-family, var(--editorial-body-font-family, inherit));font-weight:var(--editorial-title-weight, 600)}.section-description{margin:0;font-family:var(--editorial-body-font-family, inherit);font-size:.93rem;color:var(--pfx-form-label-muted);line-height:1.6}.section-description.body-large{font:var(--mdc-typography-body-large, 400 16px/24px system-ui)}.section-description.body-medium{font:var(--mdc-typography-body-medium, 400 14px/20px system-ui)}.section-description.body-small{font:var(--mdc-typography-body-small, 400 12px/16px system-ui)}.section-description.body-large,.section-description.body-medium,.section-description.body-small{font-family:var(--editorial-body-font-family, inherit);font-weight:var(--editorial-body-weight, 400)}.section-title.align-center,.section-description.align-center,.section-step-label.align-center{text-align:center}.praxis-dynamic-form .form-section.section-appearance-plain{border-color:transparent;border-width:0;border-radius:0;padding:0;background:transparent;box-shadow:none}.praxis-dynamic-form .form-section.section-appearance-plain.section-has-divider{padding-bottom:16px;border-bottom:1px solid var(--pfx-form-section-divider, var(--md-sys-color-outline-variant, #e0e2ec))}.praxis-dynamic-form .section-drop-wrapper:last-of-type>.form-section.section-appearance-plain.section-has-divider,.praxis-dynamic-form>.form-section.section-appearance-plain.section-has-divider:last-of-type{border-bottom:none;padding-bottom:0}.form-section.section-appearance-plain .section-heading{margin-bottom:14px}.form-section.section-appearance-step{border-radius:var(--pfx-editorial-form-radius);padding:var(--pfx-form-section-padding);background:var(--pfx-form-section-surface-flat);border-color:var(--pfx-form-section-divider);box-shadow:none}.praxis-dynamic-form.editorial-visual-context .form-section.section-appearance-step{border-radius:var(--editorial-card-radius, 20px);box-shadow:none}.form-section.section-appearance-step .section-heading{margin-bottom:22px;padding-bottom:var(--pfx-form-section-heading-divider-gap, 16px)}.form-section.section-appearance-step .section-heading.title-only{padding-bottom:var(--pfx-form-section-heading-title-only-divider-gap, 16px)}:host(.pfx-form-section-divider-inline-title) .form-section.section-appearance-step .section-heading.title-only{padding-bottom:var(--pfx-form-section-heading-title-only-inline-divider-gap, 0)}.form-section.section-appearance-step .section-title{font:var(--mdc-typography-title-large, 700 22px/28px system-ui);color:var(--pfx-form-label-strong);margin-bottom:8px}.form-section.section-appearance-step .section-description{color:var(--pfx-form-label-muted);max-width:60ch}.form-section.section-appearance-step .section-step-label{min-height:24px;padding:0 10px;margin-bottom:10px;box-shadow:none}.form-section.section-appearance-step .section-heading.align-center .section-description{max-width:52ch}.form-section.section-appearance-step .section-body{display:grid;gap:8px;padding-top:0}.form-section.section-appearance-step .form-row{margin-bottom:var(--pfx-field-gap, 1rem)}.form-section.section-appearance-step .form-column{gap:var(--pfx-field-gap, 12px)}.form-section .form-editorial-blocks{display:grid;gap:16px}.form-section .form-editorial-blocks[data-editorial-placement=beforeActions]{margin-top:24px;padding-top:18px;border-top:1px solid var(--pfx-form-section-divider)}.form-section.section-appearance-step .form-editorial-blocks[data-editorial-placement=beforeActions]{gap:18px}.form-section.section-appearance-step .form-editorial-blocks[data-editorial-placement=beforeActions]>*+*{margin-top:2px}.praxis-dynamic-form:not(.canvas-mode-enabled)>praxis-form-actions[data-actions-placement=afterSections]{margin-top:18px}.praxis-dynamic-form>.form-editorial-blocks[data-editorial-placement=after]{margin-top:6px}:host-context(.mdc-theme-dark) .form-section.section-appearance-step,:host-context(.theme-dark) .form-section.section-appearance-step{border-color:color-mix(in srgb,var(--pfx-editorial-form-border) 82%,transparent);box-shadow:none}:host-context(.mdc-theme-dark) .form-section.section-appearance-step .section-title,:host-context(.theme-dark) .form-section.section-appearance-step .section-title{color:color-mix(in srgb,var(--pfx-editorial-form-text) 96%,white)}:host-context(.mdc-theme-dark) .form-section.section-appearance-step .section-description,:host-context(.theme-dark) .form-section.section-appearance-step .section-description{color:color-mix(in srgb,var(--pfx-editorial-form-text-muted) 86%,var(--pfx-editorial-form-text) 14%)}:host-context(.mdc-theme-dark) .section-step-label,:host-context(.theme-dark) .section-step-label{background:color-mix(in srgb,var(--md-sys-color-primary-container) 54%,transparent);color:color-mix(in srgb,var(--md-sys-color-primary) 88%,white)}:host-context(.mdc-theme-dark) .form-section .form-editorial-blocks[data-editorial-placement=beforeActions],:host-context(.theme-dark) .form-section .form-editorial-blocks[data-editorial-placement=beforeActions]{border-top-color:color-mix(in srgb,var(--md-sys-color-outline-variant) 90%,transparent)}.inline-edit-btn{margin-left:6px;vertical-align:middle}.section-body.collapsed{border:1px dashed var(--md-sys-color-outline-variant);background:var(--md-sys-color-surface-container-low);border-radius:6px;padding:8px 10px}.section-collapsed-placeholder{display:flex;align-items:center;gap:8px;color:var(--md-sys-color-on-surface-variant);font-size:.95rem}.section-collapsed-placeholder mat-icon{font-size:20px;width:20px;height:20px}.form-row{display:flex;gap:1.1rem;margin-bottom:var(--pfx-field-gap, 1.1rem);max-width:100%;min-width:0;transition:all .2s ease;border-radius:6px;position:relative}.praxis-dynamic-form.pfx-mounting .form-row{opacity:0;transform:translateY(var(--pdx-form-mount-offset, 6px));animation:pdxFormMount var(--pdx-form-mount-duration, .16s) ease-out both;animation-delay:calc(var(--pfx-mount-index, 0) * var(--pdx-form-mount-stagger, 20ms))}@media(prefers-reduced-motion:reduce){.praxis-dynamic-form.pfx-mounting .form-row{animation:none;opacity:1;transform:none}}@keyframes pdxFormMount{to{opacity:1;transform:translateY(0)}}.praxis-dynamic-form .mat-mdc-form-field{width:100%;margin-bottom:var(--pfx-field-gap, 10px);font-family:inherit;--mdc-filled-text-field-container-color: var(--pfx-form-field-surface-rest);--mdc-filled-text-field-focus-active-indicator-color: var(--pfx-editorial-form-accent);--mdc-filled-text-field-active-indicator-color: var(--pfx-editorial-form-field-outline);--mdc-filled-text-field-hover-active-indicator-color: var(--pfx-editorial-form-accent);--mdc-filled-text-field-focus-label-text-color: var(--pfx-editorial-form-accent);--mdc-filled-text-field-label-text-color: var(--pfx-form-label-muted);--mdc-filled-text-field-input-text-color: var(--pfx-editorial-form-text);--mdc-filled-text-field-caret-color: var(--pfx-editorial-form-accent);--mdc-filled-text-field-input-text-placeholder-color: color-mix( in srgb, var(--pfx-editorial-form-text-muted) 82%, transparent );--mdc-outlined-text-field-outline-color: var(--pfx-editorial-form-field-outline);--mdc-outlined-text-field-hover-outline-color: var(--pfx-editorial-form-accent);--mdc-outlined-text-field-focus-outline-color: var(--pfx-editorial-form-accent);--mdc-outlined-text-field-focus-label-text-color: var(--pfx-editorial-form-accent);--mdc-outlined-text-field-label-text-color: var(--pfx-form-label-muted);--mdc-outlined-text-field-input-text-color: var(--pfx-editorial-form-text);--mdc-filled-text-field-container-shape: var(--pfx-editorial-form-field-radius);--mdc-outlined-text-field-container-shape: var(--pfx-editorial-form-field-radius);--mdc-filled-text-field-active-indicator-height: var(--pfx-editorial-form-field-border-width);--mdc-filled-text-field-focus-active-indicator-height: var(--pfx-editorial-form-field-border-width);--mdc-outlined-text-field-outline-width: var(--pfx-editorial-form-field-border-width);--mdc-outlined-text-field-focus-outline-width: var(--pfx-editorial-form-field-border-width);--mat-select-enabled-trigger-text-color: var(--pfx-editorial-form-text);--mat-select-enabled-arrow-color: var(--pfx-form-label-muted);--mat-form-field-enabled-select-arrow-color: var(--pfx-form-label-muted);--mat-form-field-focus-select-arrow-color: var(--pfx-editorial-form-accent);--mat-form-field-hover-state-layer-opacity: 0;--mat-form-field-focus-state-layer-opacity: 0}.praxis-dynamic-form.editorial-visual-context .mat-mdc-form-field{font-family:var(--editorial-body-font-family, inherit)}.praxis-dynamic-form .mat-mdc-text-field-wrapper,.praxis-dynamic-form .mdc-text-field{background:var(--pfx-form-field-surface-rest);border-radius:var(--pfx-editorial-form-field-radius);min-height:var(--pfx-form-field-min-height);transition:background-color .16s ease,box-shadow .16s ease,border-color .16s ease}.praxis-dynamic-form.editorial-visual-context .mat-mdc-text-field-wrapper,.praxis-dynamic-form.editorial-visual-context .mdc-text-field,.praxis-dynamic-form.editorial-visual-context .mdc-text-field--filled,.praxis-dynamic-form.editorial-visual-context .mdc-text-field--outlined{background-color:var(--pfx-form-field-surface-rest)!important;background:var(--pfx-form-field-surface-rest)!important}.praxis-dynamic-form .mat-mdc-form-field .mdc-floating-label,.praxis-dynamic-form .mat-mdc-form-field .mat-mdc-form-field-hint,.praxis-dynamic-form .mat-mdc-form-field .mat-mdc-form-field-error,.praxis-dynamic-form .mat-mdc-form-field .mat-mdc-form-field-required-marker,.praxis-dynamic-form .mat-mdc-form-field .mat-mdc-select-arrow,.praxis-dynamic-form .mat-mdc-form-field .mat-mdc-select-placeholder,.praxis-dynamic-form .mat-mdc-form-field .mat-mdc-form-field-icon-suffix,.praxis-dynamic-form .mat-mdc-form-field .mat-mdc-form-field-icon-prefix{color:var(--pfx-form-label-muted)}.praxis-dynamic-form .mat-mdc-input-element,.praxis-dynamic-form .mat-mdc-select-value-text,.praxis-dynamic-form .mat-mdc-form-field-infix,.praxis-dynamic-form .mat-mdc-select-min-line{color:var(--pfx-editorial-form-text)}.praxis-dynamic-form .mat-mdc-form-field:hover .mat-mdc-text-field-wrapper,.praxis-dynamic-form .mat-mdc-form-field:hover .mdc-text-field,.praxis-dynamic-form .mat-mdc-form-field.mat-focused .mat-mdc-text-field-wrapper,.praxis-dynamic-form .mat-mdc-form-field.mat-focused .mdc-text-field{background:var(--pfx-form-field-surface-focus)}.praxis-dynamic-form.editorial-visual-context .mat-mdc-input-element,.praxis-dynamic-form.editorial-visual-context .mat-mdc-select-value-text,.praxis-dynamic-form.editorial-visual-context .mat-mdc-form-field-infix,.praxis-dynamic-form.editorial-visual-context .mat-mdc-select-min-line,.praxis-dynamic-form.editorial-visual-context .mdc-text-field__input{color:var(--pfx-editorial-form-text)!important;-webkit-text-fill-color:var(--pfx-editorial-form-text)!important}.praxis-dynamic-form.editorial-visual-context .mat-mdc-form-field .mdc-floating-label,.praxis-dynamic-form.editorial-visual-context .mat-mdc-form-field .mat-mdc-form-field-hint,.praxis-dynamic-form.editorial-visual-context .mat-mdc-form-field .mat-mdc-form-field-error,.praxis-dynamic-form.editorial-visual-context .mat-mdc-form-field .mat-mdc-form-field-required-marker,.praxis-dynamic-form.editorial-visual-context .mat-mdc-form-field .mat-mdc-select-arrow,.praxis-dynamic-form.editorial-visual-context .mat-mdc-form-field .mat-mdc-select-placeholder,.praxis-dynamic-form.editorial-visual-context .mat-mdc-form-field .mat-mdc-form-field-icon-suffix,.praxis-dynamic-form.editorial-visual-context .mat-mdc-form-field .mat-mdc-form-field-icon-prefix{color:var(--pfx-editorial-form-text-muted)!important}.praxis-dynamic-form.editorial-visual-context .mat-mdc-floating-label,.praxis-dynamic-form.editorial-visual-context .mdc-floating-label,.praxis-dynamic-form.editorial-visual-context .mdc-text-field__input::placeholder{color:color-mix(in srgb,var(--pfx-editorial-form-text) 68%,transparent)!important}.praxis-dynamic-form.editorial-visual-context .mat-mdc-input-element::placeholder,.praxis-dynamic-form.editorial-visual-context textarea.mat-mdc-input-element::placeholder{color:color-mix(in srgb,var(--pfx-editorial-form-text) 58%,transparent)!important}.praxis-dynamic-form .mat-mdc-radio-button,.praxis-dynamic-form .mat-mdc-checkbox,.praxis-dynamic-form .mat-mdc-slide-toggle{--mdc-radio-selected-icon-color: var(--pfx-editorial-form-accent);--mdc-radio-selected-hover-icon-color: var(--pfx-editorial-form-accent);--mdc-radio-selected-focus-icon-color: var(--pfx-editorial-form-accent);--mdc-checkbox-selected-checkmark-color: var(--pfx-editorial-form-accent-text);--mdc-checkbox-selected-focus-icon-color: var(--pfx-editorial-form-accent);--mdc-checkbox-selected-hover-icon-color: var(--pfx-editorial-form-accent);--mdc-checkbox-selected-icon-color: var(--pfx-editorial-form-accent);--mdc-switch-selected-focus-state-layer-color: var(--pfx-editorial-form-accent);--mdc-switch-selected-handle-color: var(--pfx-editorial-form-accent);--mdc-switch-selected-track-color: color-mix(in srgb, var(--pfx-editorial-form-accent) 45%, #fff)}.praxis-dynamic-form [data-field-type=input],.praxis-dynamic-form [data-field-type=textarea],.praxis-dynamic-form [data-field-type=email],.praxis-dynamic-form [data-field-type=password],.praxis-dynamic-form [data-field-type=url],.praxis-dynamic-form [data-field-type=search],.praxis-dynamic-form [data-field-type=phone],.praxis-dynamic-form [data-field-type=numericTextBox],.praxis-dynamic-form [data-field-type=currency],.praxis-dynamic-form [data-field-type=cpfCnpj],.praxis-dynamic-form [data-field-type=date],.praxis-dynamic-form [data-field-type=dateInput],.praxis-dynamic-form [data-field-type=dateRange],.praxis-dynamic-form [data-field-type=dateTimeLocal],.praxis-dynamic-form [data-field-type=time],.praxis-dynamic-form [data-field-type=timePicker],.praxis-dynamic-form [data-field-type=timeRange],.praxis-dynamic-form [data-field-type=month],.praxis-dynamic-form [data-field-type=week],.praxis-dynamic-form [data-field-type=yearInput],.praxis-dynamic-form [data-field-type=select],.praxis-dynamic-form [data-field-type=multi-select],.praxis-dynamic-form [data-field-type=searchable-select],.praxis-dynamic-form [data-field-type=async-select],.praxis-dynamic-form [data-field-type=autocomplete],.praxis-dynamic-form [data-field-type=entityLookup],.praxis-dynamic-form [data-field-type=tree-select],.praxis-dynamic-form [data-field-type=multi-select-tree],.praxis-dynamic-form [data-field-type=priceRange],.praxis-dynamic-form [data-field-type=file-upload]{display:block;width:100%;min-width:0}.praxis-dynamic-form .mat-mdc-form-field-subscript-wrapper{min-height:var(--pfx-subscript-min-h, 22px)}.form-row:last-child{margin-bottom:0}.form-column{display:grid;grid-template-columns:minmax(0,1fr);align-content:start;gap:var(--pfx-field-gap, 10px);flex:1;max-width:100%;min-width:0;transition:all .2s ease;border-radius:4px;position:relative}.form-layout-rich-content{display:block;width:100%;max-width:100%;min-width:0;margin-bottom:var(--pfx-field-gap, 10px);color:var(--pfx-editorial-form-text-muted, var(--md-sys-color-on-surface-variant));font:var(--mdc-typography-body-medium, 400 14px/20px system-ui);overflow-wrap:anywhere}:host ::ng-deep .form-layout-rich-content .prx-rich-content-root{display:grid;gap:8px;min-width:0;max-width:100%}:host ::ng-deep .form-layout-rich-content .prx-rich-node{min-width:0;max-width:100%}:host ::ng-deep .form-layout-rich-content .prx-rich-text{color:inherit;line-height:20px}:host ::ng-deep .form-layout-rich-content .praxis-form-visual-block--note,:host ::ng-deep .form-layout-rich-content .praxis-rich-content-notice{border:1px solid color-mix(in srgb,var(--pfx-editorial-form-accent) 12%,var(--pfx-editorial-form-border) 88%);border-left:3px solid var(--pfx-editorial-form-accent);border-radius:8px;background:color-mix(in srgb,var(--pfx-editorial-form-accent-container) 12%,var(--pfx-editorial-form-surface-muted) 88%)}:host ::ng-deep .form-layout-rich-content .praxis-form-visual-block--note{display:grid;grid-template-columns:20px minmax(0,1fr);gap:10px;align-items:flex-start;padding:11px 12px}:host ::ng-deep .form-layout-rich-content .praxis-form-visual-block--note:before{content:\"info\";display:inline-flex;align-items:center;justify-content:center;width:20px;height:20px;color:var(--pfx-editorial-form-accent);font-family:Material Symbols Outlined;font-size:20px;font-weight:400;line-height:20px}:host ::ng-deep .form-layout-rich-content .praxis-form-visual-block--note .prx-rich-text{color:var(--pfx-editorial-form-text-muted)}:host ::ng-deep .form-layout-rich-content .praxis-rich-content-notice{padding:10px 12px;color:var(--pfx-editorial-form-text)}:host ::ng-deep .form-layout-rich-content .praxis-rich-content-notice .prx-rich-compose{align-items:flex-start;gap:10px}:host ::ng-deep .form-layout-rich-content .praxis-rich-content-notice .prx-rich-icon{color:var(--pfx-editorial-form-accent);font-size:20px;line-height:20px;margin-top:1px}:host ::ng-deep .form-layout-rich-content .praxis-rich-content-divider{display:grid;grid-template-columns:minmax(24px,1fr) auto minmax(24px,1fr);align-items:center;gap:10px;color:var(--pfx-editorial-form-text-muted);font:var(--mdc-typography-label-small, 600 12px/16px system-ui);text-transform:uppercase}:host ::ng-deep .form-layout-rich-content .praxis-rich-content-divider:before,:host ::ng-deep .form-layout-rich-content .praxis-rich-content-divider:after{content:\"\";height:1px;background:var(--pfx-editorial-form-border)}:host ::ng-deep .form-layout-rich-content .prx-rich-card{gap:6px;padding:12px 14px;border-color:var(--pfx-editorial-form-border);border-radius:8px;background:var(--pfx-editorial-form-surface-muted);color:var(--pfx-editorial-form-text);box-shadow:none}:host ::ng-deep .form-layout-rich-content .prx-rich-card-title{color:var(--pfx-editorial-form-text);font:var(--mdc-typography-title-small, 600 14px/20px system-ui)}:host ::ng-deep .form-layout-rich-content .prx-rich-card-subtitle,:host ::ng-deep .form-layout-rich-content .prx-rich-metric-caption{color:var(--pfx-editorial-form-text-muted)}:host ::ng-deep .form-layout-rich-content .prx-rich-card .prx-rich-text{color:var(--pfx-editorial-form-text-muted)}:host ::ng-deep .form-layout-rich-content .prx-rich-badge{background:var(--pfx-editorial-form-accent-container);color:var(--pfx-editorial-form-accent-container-text)}.form-row.grid-12{container-type:inline-size;container-name:praxis-form-row;display:grid;grid-template-columns:repeat(12,minmax(0,1fr));gap:var(--pfx-grid-gap, 16px)}.align-start{align-self:flex-start}.align-center{align-self:center}.align-end{align-self:flex-end}.align-stretch{align-self:stretch}.form-blocking-overlay{position:absolute;inset:0;background:transparent;color:var(--md-sys-color-on-surface);backdrop-filter:blur(2px) saturate(103%);-webkit-backdrop-filter:blur(2px) saturate(103%);display:flex;align-items:center;justify-content:center;flex-direction:column;gap:12px;z-index:10;pointer-events:all}@media(max-width:768px){.column-drop-wrapper,.row-drop-wrapper,.form-layout-rich-content,.praxis-dynamic-form .mat-mdc-form-field,.praxis-dynamic-form .mat-mdc-text-field-wrapper,.praxis-dynamic-form .mdc-text-field{max-width:100%;min-width:0}:host ::ng-deep .praxis-dynamic-form .pfx-field-shell,:host ::ng-deep .praxis-dynamic-form .pfx-field-shell-wrapper,:host ::ng-deep .praxis-dynamic-form .pfx-field-shell-host,:host ::ng-deep .praxis-dynamic-form .mat-mdc-form-field,:host ::ng-deep .praxis-dynamic-form .mat-mdc-text-field-wrapper,:host ::ng-deep .praxis-dynamic-form .mdc-text-field{width:100%;max-width:100%;min-width:0}.form-section{padding:clamp(.75rem,4vw,1rem)}.section-heading{gap:10px;margin-bottom:16px;padding-bottom:var(--pfx-form-section-heading-divider-gap, 14px)}.section-heading.title-only{padding-bottom:var(--pfx-form-section-heading-title-only-divider-gap, 8px)}}.section-title{display:flex;align-items:center;gap:8px}:host(.pfx-form-section-divider-inline-title) .section-heading.title-only .section-title{width:100%;min-width:0}:host(.pfx-form-section-divider-inline-title) .section-heading.title-only .section-title:after{content:\"\";display:block;flex:1 1 auto;min-width:var(--pfx-form-section-title-inline-divider-min-width, 48px);height:2px;margin-left:var(--pfx-form-section-title-inline-divider-gap, 12px);pointer-events:none;background:linear-gradient(90deg,var(--pfx-form-section-divider) 0%,var(--pfx-form-section-divider) 62%,color-mix(in srgb,var(--pfx-form-section-divider) 18%,transparent) 88%,transparent 100%);border-radius:999px;-webkit-mask-image:linear-gradient(90deg,black 0%,black 72%,transparent 100%);mask-image:linear-gradient(90deg,black 0%,black 72%,transparent 100%)}:host(.pfx-form-section-divider-inline-title) .section-heading.align-center .section-title:after{display:none}@media(max-width:640px){:host(.pfx-form-section-divider-inline-title) .section-heading.title-only{padding-bottom:var(--pfx-form-section-heading-title-only-divider-gap, 8px)}:host(.pfx-form-section-divider-inline-title) .section-heading.title-only:after{display:block}:host(.pfx-form-section-divider-inline-title) .section-heading.title-only .section-title{width:auto}:host(.pfx-form-section-divider-inline-title) .section-heading.title-only .section-title:after{display:none}}.section-title .section-title-icon{font-size:1.25em;line-height:1}.section-title-avatar{--_pfx-form-section-avatar-size: var(--pfx-form-section-avatar-size-md, var(--pfx-form-section-avatar-size, 32px));display:inline-flex;align-items:center;justify-content:center;width:var(--_pfx-form-section-avatar-size);height:var(--_pfx-form-section-avatar-size);border-radius:999px;flex:0 0 var(--_pfx-form-section-avatar-size);overflow:hidden}.section-title-avatar.size-sm{--_pfx-form-section-avatar-size: var(--pfx-form-section-avatar-size-sm, 24px)}.section-title-avatar.size-md{--_pfx-form-section-avatar-size: var(--pfx-form-section-avatar-size-md, var(--pfx-form-section-avatar-size, 32px))}.section-title-avatar.size-lg{--_pfx-form-section-avatar-size: var(--pfx-form-section-avatar-size-lg, 40px)}.section-title-avatar-image{object-fit:cover;border:1px solid color-mix(in srgb,var(--pfx-form-section-divider) 72%,transparent);background:var(--pfx-form-section-surface-flat)}.section-title-avatar-text,.section-title-avatar-placeholder{background:color-mix(in srgb,var(--pfx-editorial-form-accent) 14%,var(--pfx-form-section-surface-flat));color:color-mix(in srgb,var(--pfx-editorial-form-accent) 82%,var(--pfx-form-label-strong) 18%);font-size:calc(var(--_pfx-form-section-avatar-size) * .41);font-weight:800;letter-spacing:.04em;text-transform:uppercase}.section-title-avatar-placeholder mat-icon{font-size:calc(var(--_pfx-form-section-avatar-size) * .5625);width:calc(var(--_pfx-form-section-avatar-size) * .5625);height:calc(var(--_pfx-form-section-avatar-size) * .5625);line-height:calc(var(--_pfx-form-section-avatar-size) * .5625)}.section-title-avatar-sr-only{position:absolute;width:1px;height:1px;padding:0;margin:-1px;overflow:hidden;clip:rect(0,0,0,0);white-space:nowrap;border:0}.form-context-empty-state{display:grid;min-height:var(--pdx-form-context-empty-min-height, 0);place-items:center;padding:var(--pdx-form-context-empty-padding, 0)}.form-context-empty-state praxis-empty-state-card{display:block;width:min(100%,var(--pdx-form-context-empty-max-width, 32rem))}.prx-form-tabs{display:block;margin-bottom:16px;max-width:100%}.prx-form-tabs__tablist{display:flex;flex-wrap:wrap;align-items:center;gap:8px;max-width:100%}.prx-form-tabs__tablist--scrollable{flex-wrap:nowrap;overflow-x:auto;overflow-y:hidden;scrollbar-width:none;-webkit-overflow-scrolling:touch;padding:4px 2px}.prx-form-tabs__tablist--scrollable::-webkit-scrollbar{display:none}.prx-form-tabs__tab{display:inline-flex;align-items:center;gap:8px;min-width:0;padding:8px 14px;border-radius:999px;border:1px solid var(--md-sys-color-outline-variant, rgba(0, 0, 0, .12));background:color-mix(in srgb,var(--md-sys-color-surface, transparent) 40%,transparent);color:var(--md-sys-color-on-surface, #1d1b20);font-family:inherit;font-size:.84rem;font-weight:500;cursor:pointer;white-space:nowrap;flex-shrink:0;-webkit-user-select:none;user-select:none;transition:all .2s cubic-bezier(.2,0,0,1)}.prx-form-tabs__tab:hover:not(:disabled):not(.prx-form-tabs__tab--active){background:var(--md-sys-color-surface-container-high, rgba(0, 0, 0, .05));border-color:var(--md-sys-color-outline, rgba(0, 0, 0, .24));color:var(--md-sys-color-on-surface)}.prx-form-tabs__tab:focus-visible{outline:2px solid var(--md-sys-color-primary, #005ac1);outline-offset:2px}.prx-form-tabs__tab:disabled{cursor:not-allowed;opacity:.45}.prx-form-tabs__tab--active{background:var(--md-sys-color-primary-container, color-mix(in srgb, var(--md-sys-color-primary, #005ac1) 16%, var(--md-sys-color-surface-container-high, #2b2930)));color:var(--md-sys-color-on-primary-container, var(--md-sys-color-primary, #005ac1));border-color:transparent;font-weight:600;box-shadow:0 1px 3px #00000014}.prx-form-tabs__tab-icon{font-size:18px;width:18px;height:18px;display:inline-flex;align-items:center;justify-content:center}.prx-form-tabs__tab-badge{display:inline-flex;align-items:center;justify-content:center;padding:1px 7px;font-size:.72rem;font-weight:600;border-radius:999px;background:color-mix(in srgb,currentColor 14%,transparent)}.prx-form-tabs__tab-error-badge{display:inline-flex;align-items:center;justify-content:center;min-width:18px;height:18px;padding:0 5px;border-radius:999px;font-size:.7rem;font-weight:700;background:var(--md-sys-color-error, #ba1a1a);color:var(--md-sys-color-on-error, #ffffff);box-shadow:0 1px 2px #0003}.prx-form-tabs[data-appearance=underline]{border-bottom:1px solid var(--md-sys-color-outline-variant, #cac4d0)}.prx-form-tabs[data-appearance=underline] .prx-form-tabs__tablist{gap:16px;padding-bottom:0}.prx-form-tabs[data-appearance=underline] .prx-form-tabs__tab{border:none;border-radius:0;border-bottom:2px solid transparent;background:transparent;padding:8px 4px 10px;margin-bottom:-1px}.prx-form-tabs[data-appearance=underline] .prx-form-tabs__tab:hover:not(:disabled):not(.prx-form-tabs__tab--active){background:transparent;border-bottom-color:var(--md-sys-color-outline-variant, #cac4d0)}.prx-form-tabs[data-appearance=underline] .prx-form-tabs__tab--active{background:transparent;box-shadow:none;border-bottom-color:var(--md-sys-color-primary, #005ac1);color:var(--md-sys-color-primary, #005ac1)}.prx-form-tabs[data-appearance=buttons] .prx-form-tabs__tablist{background:var(--md-sys-color-surface-container, rgba(0, 0, 0, .04));border-radius:12px;padding:4px;gap:4px;border:1px solid var(--md-sys-color-outline-variant, rgba(0, 0, 0, .08))}.prx-form-tabs[data-appearance=buttons] .prx-form-tabs__tab{border:none;border-radius:8px;padding:6px 12px;background:transparent}.prx-form-tabs[data-appearance=buttons] .prx-form-tabs__tab:hover:not(:disabled):not(.prx-form-tabs__tab--active){background:color-mix(in srgb,currentColor 8%,transparent)}.prx-form-tabs[data-appearance=buttons] .prx-form-tabs__tab--active{background:var(--md-sys-color-surface, var(--mat-sys-surface));color:var(--md-sys-color-primary, #005ac1);box-shadow:0 1px 3px #0000001f}.section-drop-wrapper[hidden]{display:none!important}\n"], dependencies: [{ kind: "ngmodule", type: CommonModule }, { kind: "directive", type: i1$2.NgClass, selector: "[ngClass]", inputs: ["class", "ngClass"] }, { kind: "directive", type: i1$2.NgStyle, selector: "[ngStyle]", inputs: ["ngStyle"] }, { kind: "ngmodule", type: ReactiveFormsModule }, { kind: "directive", type: i1$3.ɵNgNoValidate, selector: "form:not([ngNoForm]):not([ngNativeValidate])" }, { kind: "directive", type: i1$3.NgControlStatusGroup, selector: "[formGroupName],[formArrayName],[ngModelGroup],[formGroup],[formArray],form:not([ngNoForm]),[ngForm]" }, { kind: "directive", type: i1$3.FormGroupDirective, selector: "[formGroup]", inputs: ["formGroup"], outputs: ["ngSubmit"], exportAs: ["ngForm"] }, { kind: "directive", type: DynamicFieldLoaderDirective, selector: "[dynamicFieldLoader]", inputs: ["fields", "formGroup", "enableExternalControlBinding", "itemTemplate", "debugTrace", "debugTraceLabel", "readonlyMode", "disabledMode", "presentationMode", "visible", "canvasMode"], outputs: ["componentsCreated", "fieldCreated", "fieldDestroyed", "renderError", "canvasMouseEnter", "canvasMouseLeave", "canvasClick", "canvasFocus"] }, { kind: "ngmodule", type: MatIconModule }, { kind: "component", type: i4.MatIcon, selector: "mat-icon", inputs: ["color", "inline", "svgIcon", "fontSet", "fontIcon"], exportAs: ["matIcon"] }, { kind: "ngmodule", type: MatButtonModule }, { kind: "component", type: i3.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: i3.MatFabButton, selector: "button[mat-fab], a[mat-fab], button[matFab], a[matFab]", inputs: ["extended"], exportAs: ["matButton", "matAnchor"] }, { kind: "ngmodule", type: MatProgressSpinnerModule }, { kind: "component", type: i17.MatProgressSpinner, selector: "mat-progress-spinner, mat-spinner", inputs: ["color", "mode", "value", "diameter", "strokeWidth"], exportAs: ["matProgressSpinner"] }, { kind: "ngmodule", type: MatTooltipModule }, { kind: "directive", type: i5.MatTooltip, selector: "[matTooltip]", inputs: ["matTooltipPosition", "matTooltipPositionAtOrigin", "matTooltipDisabled", "matTooltipShowDelay", "matTooltipHideDelay", "matTooltipTouchGestures", "matTooltip", "matTooltipClass"], exportAs: ["matTooltip"] }, { kind: "ngmodule", type: MatDialogModule }, { kind: "ngmodule", type: MatSnackBarModule }, { kind: "ngmodule", type: MatBadgeModule }, { kind: "directive", type: i19.MatBadge, selector: "[matBadge]", inputs: ["matBadgeColor", "matBadgeOverlap", "matBadgeDisabled", "matBadgePosition", "matBadge", "matBadgeDescription", "matBadgeSize", "matBadgeHidden"] }, { kind: "component", type: PraxisIconButtonComponent, selector: "button[praxisIconButton]", inputs: ["praxisIconButton", "size", "appearance", "presentation", "pressed", "busy"] }, { kind: "directive", type: PraxisIconDirective, selector: "mat-icon[praxisIcon]", inputs: ["praxisIcon"] }, { kind: "component", type: CanvasToolbarComponent, selector: "praxis-canvas-toolbar", inputs: ["selectedElement"], outputs: ["editMetadata", "delete", "moveUp", "moveDown", "selectPath", "requestClose", "toggleReadonly", "toggleRequired", "toggleHidden", "toggleDisabled"] }, { kind: "component", type: PraxisFormActionsComponent, selector: "praxis-form-actions", inputs: ["actions", "editorialVisualContext", "isSubmitting", "formIsValid", "submitError", "invalidRequiredFieldLabels", "suppressInvalidSubmitHint", "formId", "actionOverrides"], outputs: ["action"] }, { kind: "component", type: EmptyStateCardComponent, selector: "praxis-empty-state-card", inputs: ["icon", "title", "description", "primaryAction", "secondaryActions", "inline", "tone", "variant", "alignment", "density", "iconContainer"] }, { kind: "component", type: PraxisAiAssistantShellComponent, selector: "praxis-ai-assistant-shell", inputs: ["labels", "mode", "state", "contextItems", "attachments", "messages", "quickReplies", "recommendedIntents", "prompt", "statusText", "errorText", "testIdPrefix", "panelTestId", "submitTestId", "applyTestId", "primaryAction", "secondaryActions", "governanceActions", "busy", "canSubmit", "canApply", "submitOnEnter", "showAttachAction", "enablePastedAttachments", "enableFileAttachments", "attachmentAccept", "attachmentMultiple", "voiceInputMode", "voiceLanguage", "draggable", "resizable", "minWidth", "minHeight", "margin", "layout"], outputs: ["promptChange", "submitPrompt", "apply", "retryTurn", "cancelTurn", "shellAction", "close", "attach", "attachmentsPasted", "attachmentsSelected", "removeAttachment", "messageAction", "editMessage", "resendMessage", "quickReply", "recommendedIntent", "layoutChange"] }, { kind: "component", type: PraxisRichContent, selector: "praxis-rich-content", inputs: ["document", "nodes", "context", "hostCapabilities", "layout", "rootClassName"], outputs: ["nodeAction"] }] });
|
|
21744
21979
|
}
|
|
21745
21980
|
i0.ɵɵngDeclareClassMetadata({ minVersion: "12.0.0", version: "21.2.14", ngImport: i0, type: PraxisDynamicForm, decorators: [{
|
|
21746
21981
|
type: Component,
|
|
@@ -21762,7 +21997,7 @@ i0.ɵɵngDeclareClassMetadata({ minVersion: "12.0.0", version: "21.2.14", ngImpo
|
|
|
21762
21997
|
EmptyStateCardComponent,
|
|
21763
21998
|
PraxisAiAssistantShellComponent,
|
|
21764
21999
|
PraxisRichContent,
|
|
21765
|
-
], template: "@if (isLoading) {\n <!-- Loading State -->\n <div class=\"form-loading\" role=\"status\" aria-live=\"polite\" aria-label=\"Carregando formul\u00E1rio\">\n <div class=\"form-loading-header\">\n <mat-progress-spinner diameter=\"32\" aria-label=\"Carregando formul\u00E1rio\"></mat-progress-spinner>\n <div class=\"form-loading-copy\">\n <p class=\"form-loading-title\">Carregando formul\u00E1rio...</p>\n <p class=\"form-loading-subtitle\">Preparando campos e op\u00E7\u00F5es do cadastro.</p>\n </div>\n </div>\n <div class=\"form-loading-skeleton\" aria-hidden=\"true\">\n <span class=\"form-loading-line form-loading-line-title\"></span>\n <span class=\"form-loading-line\"></span>\n <span class=\"form-loading-line form-loading-line-short\"></span>\n <span class=\"form-loading-field\"></span>\n <span class=\"form-loading-field form-loading-field-wide\"></span>\n </div>\n </div>\n} @else if (initializationStatus === 'error') {\n <!-- Error State -->\n <div class=\"form-error\">\n <mat-icon color=\"warn\" [praxisIcon]=\"'error'\"></mat-icon>\n <h3>{{ getErrorTitle() }}</h3>\n <p>{{ currentErrorMessage }}</p>\n @if (isRecoverable) {\n <button mat-stroked-button (click)=\"retryInitialization()\">\n <mat-icon [praxisIcon]=\"'refresh'\"></mat-icon>\n Tentar Novamente\n </button>\n }\n <button mat-button (click)=\"showDetailedError()\" class=\"show-details\">\n Ver Detalhes T\u00E9cnicos\n </button>\n <!-- Permitir corre\u00E7\u00E3o do resourcePath diretamente do estado de erro -->\n <button mat-flat-button color=\"primary\" (click)=\"openQuickConnect()\" class=\"connect-action\">\n <mat-icon [praxisIcon]=\"'bolt'\"></mat-icon>\n Conectar a recurso\n </button>\n </div>\n} @else if (initializationStatus === 'success') {\n <!-- Inline banner for schema change (only when customization is enabled) -->\n @if (shouldShowOutdatedInline()) {\n <div class=\"pfx-form-info-banner\" role=\"status\" aria-live=\"polite\">\n <div class=\"text\">O schema do servidor mudou. Reconciliar agora?</div>\n <div class=\"actions\">\n <button mat-stroked-button color=\"primary\" (click)=\"openConfigEditor()\">\n <mat-icon [praxisIcon]=\"'sync'\"></mat-icon>\n Reconciliar\n </button>\n <button mat-button (click)=\"onSnoozeOutdated()\">Lembrar depois</button>\n <button mat-button (click)=\"onIgnoreOutdated()\">Ignorar</button>\n </div>\n </div>\n }\n\n <!-- Configuration Controls -->\n @if (shouldShowConfigControls && enableCustomization) {\n <div class=\"form-config-controls\">\n @if (showAiAssistant) {\n <button type=\"button\" praxisIconButton=\"auto_awesome\" size=\"dense\" (click)=\"openAiAssistant()\" [disabled]=\"isLoading\"\n [attr.data-testid]=\"aiAssistantTriggerTestId('config-controls')\"\n aria-label=\"Abrir copiloto semantico Praxis do formulario\"\n matTooltip=\"Abrir copiloto sem\u00E2ntico do formul\u00E1rio\">\n </button>\n }\n <button type=\"button\" praxisIconButton=\"settings\" size=\"dense\" (click)=\"openConfigEditor()\" [disabled]=\"isLoading\" class=\"config-button\"\n [matBadge]=\"schemaOutdated ? '!' : ''\" [matBadgeHidden]=\"!schemaOutdated\" matBadgeColor=\"warn\" matBadgeSize=\"small\"\n matBadgePosition=\"above after\"\n [attr.aria-label]=\"configControlLabel\" [matTooltip]=\"configControlLabel\">\n </button>\n <button type=\"button\" praxisIconButton=\"link_off\" size=\"dense\" (click)=\"disconnect()\"\n [attr.aria-label]=\"disconnectControlLabel\" [matTooltip]=\"disconnectControlLabel\"\n [disabled]=\"isLoading\">\n </button>\n </div>\n }\n\n <!-- Form Content -->\n @if (!resourcePath && !hasExplicitSchemaUrl() && !hasRenderableConfig()) {\n <praxis-empty-state-card icon=\"link\" [title]=\"'Conecte o formul\u00E1rio \u00E0 fonte de dados'\"\n [description]=\"'Informe a rota do recurso da API para gerar automaticamente os campos do formul\u00E1rio.'\"\n [primaryAction]=\"{ label: 'Conectar \u00E0 fonte de dados', icon: 'bolt', action: openQuickConnect.bind(this) }\"></praxis-empty-state-card>\n }\n @if (shouldShowContextEmptyState()) {\n <div class=\"form-context-empty-state\" role=\"status\" aria-live=\"polite\">\n <praxis-empty-state-card\n [icon]=\"emptyState?.icon || 'touch_app'\"\n [title]=\"emptyState!.title\"\n [description]=\"emptyState?.description\"\n [tone]=\"emptyState?.tone || 'primary'\"\n [variant]=\"emptyState?.variant || 'transparent'\"\n [alignment]=\"emptyState?.alignment || 'center'\"\n [density]=\"emptyState?.density || 'compact'\"\n [iconContainer]=\"emptyState?.iconContainer || 'circle'\"\n [inline]=\"true\"\n />\n </div>\n } @else {\n <div #entityReadRegion class=\"entity-read-region\" tabindex=\"-1\" role=\"region\" [attr.aria-label]=\"entityReadText('region')\">\n <span class=\"cdk-visually-hidden\" role=\"status\" aria-live=\"polite\" aria-atomic=\"true\">{{ entityReadStatusText() }}</span>\n @if (entityHydrationPending || entityReadFailed) {\n <div class=\"entity-read-feedback\" data-testid=\"form-entity-read-feedback\">\n @if (entityHydrationPending) {\n <mat-progress-spinner diameter=\"28\" mode=\"indeterminate\" aria-hidden=\"true\"></mat-progress-spinner>\n <p aria-hidden=\"true\">{{ entityReadText('loading') }}</p>\n } @else {\n <mat-icon [praxisIcon]=\"'error_outline'\" aria-hidden=\"true\"></mat-icon>\n <p aria-hidden=\"true\">{{ entityReadText('error') }}</p>\n <button mat-stroked-button type=\"button\" (click)=\"retryEntityRead(entityReadRegion)\">{{ entityReadText('retry') }}</button>\n }\n </div>\n }\n <form #formHost (ngSubmit)=\"onSubmit()\" [attr.aria-busy]=\"submitting || entityHydrationPending ? 'true' : null\"\n [style.opacity]=\"entityHydrationPending || entityReadFailed ? '0' : null\"\n [style.transition]=\"entityHydrationPending || entityReadFailed ? 'none' : null\"\n [attr.inert]=\"entityHydrationPending || entityReadFailed ? '' : null\"\n [attr.aria-hidden]=\"entityHydrationPending || entityReadFailed ? 'true' : null\"\n [attr.aria-label]=\"'Formul\u00E1rio ' + (config.metadata?.version || '')\" [class.canvas-mode-enabled]=\"enableCustomization\"\n [class.presentation-mode]=\"effectivePresentation\"\n [class.praxis-dynamic-form--presentation]=\"effectivePresentation\"\n [class.readonly-mode]=\"effectiveReadonly\"\n [attr.data-presentation-preset]=\"effectivePresentation ? effectivePresentationPreset : null\"\n [class.praxis-dynamic-form--corporate-dossier]=\"isCorporateDossierPreset()\"\n [class.praxis-dynamic-form--editorial-card]=\"isEditorialCardPreset()\"\n [class.praxis-dynamic-form--compact-presentation]=\"isCompactPresentationPreset()\"\n [class.editorial-visual-context]=\"hasEditorialVisualContext()\"\n [class.pfx-mounting]=\"isMounting\" [formGroup]=\"form\"\n [ngClass]=\"{\n 'pres-compact': presentationVars.compact,\n 'pres-label-left': presentationVars.labelPosition === 'left',\n 'pres-label-above': presentationVars.labelPosition === 'above'\n }\" [style.--pfx-pres-label-align]=\"presentationVars.labelAlign\"\n [style.--pfx-pres-label-size]=\"presentationVars.labelSize\"\n [style.--pfx-pres-label-width]=\"presentationVars.labelWidth\"\n [style.--pfx-pres-row-gap]=\"presentationVars.density === 'compact' ? '6px' : (presentationVars.density === 'cozy' ? '8px' : '10px')\"\n [style.--pfx-pres-row-padding]=\"presentationVars.density === 'compact' ? '2px 0' : (presentationVars.density === 'cozy' ? '6px 0' : '8px 0')\"\n [style.--pfx-pres-value-align]=\"presentationVars.valueAlign\"\n [style.--pfx-pres-value-size]=\"presentationVars.valueSize\"\n [style.--pdx-form-mount-duration]=\"getMountDurationVar()\"\n [style.--pdx-form-mount-offset]=\"getMountOffsetVar()\"\n [style.--pdx-form-mount-stagger]=\"getMountStaggerVar()\"\n class=\"praxis-dynamic-form\">\n @if (enableCustomization && selectedElement) {\n <praxis-canvas-toolbar (editMetadata)=\"openSelectedElementEditor()\" (selectPath)=\"onSelectPath($event)\"\n (moveUp)=\"onToolbarMove('up')\" (moveDown)=\"onToolbarMove('down')\" (toggleReadonly)=\"onToolbarToggleReadonly()\"\n (toggleRequired)=\"onToolbarToggleRequired()\" (toggleHidden)=\"onToolbarToggleHidden()\"\n (toggleDisabled)=\"onToolbarToggleDisabled()\" (requestClose)=\"onToolbarRequestClose()\"\n [selectedElement]=\"selectedElement\"\n [style.transform]=\"toolbarTransform\"></praxis-canvas-toolbar>\n }\n\n @if (formBlocksBefore?.nodes?.length) {\n <section class=\"form-editorial-blocks form-editorial-blocks-before\" data-editorial-placement=\"before\">\n <praxis-rich-content\n [document]=\"formBlocksBeforeDocument\"\n [context]=\"getEditorialRichContentContext()\"\n [hostCapabilities]=\"richContentHostCapabilities\"\n ></praxis-rich-content>\n </section>\n }\n\n @if (actionPlacement === 'top' && !(effectivePresentation || effectiveReadonly)) {\n <praxis-form-actions data-actions-placement=\"top\" [actions]=\"effectiveActions\" [isSubmitting]=\"submitting\"\n [formIsValid]=\"effectiveFormIsValid\" [submitError]=\"submitError\" [formId]=\"formId\" [actionOverrides]=\"actionRuleProps\"\n [invalidRequiredFieldLabels]=\"invalidRequiredFieldLabels\"\n [suppressInvalidSubmitHint]=\"entityHydrationPending\"\n [editorialVisualContext]=\"hasEditorialVisualContext()\"\n (action)=\"onFormAction($event)\"></praxis-form-actions>\n }\n\n <!-- Tab Layout Navigation Bar -->\n @if (effectiveLayoutMode === 'tabs' && effectiveTabs.length > 1) {\n <nav class=\"prx-form-tabs\" [attr.data-appearance]=\"effectiveTabsAppearance\" role=\"tablist\" aria-label=\"Navega\u00E7\u00E3o em abas do formul\u00E1rio\">\n <div class=\"prx-form-tabs__tablist prx-form-tabs__tablist--scrollable\">\n @for (tab of effectiveTabs; track tab.id) {\n <button\n type=\"button\"\n role=\"tab\"\n class=\"prx-form-tabs__tab\"\n [class.prx-form-tabs__tab--active]=\"activeTabId === tab.id\"\n [attr.aria-selected]=\"activeTabId === tab.id\"\n [attr.aria-controls]=\"getTabAriaControls(tab)\"\n [attr.id]=\"'tab-' + tab.id\"\n [disabled]=\"tab.disabled\"\n [matTooltip]=\"tab.tooltip || null\"\n [matTooltipDisabled]=\"!tab.tooltip\"\n (click)=\"selectTab(tab.id)\"\n >\n @if (tab.icon) {\n <mat-icon class=\"prx-form-tabs__tab-icon\" [praxisIcon]=\"tab.icon\" aria-hidden=\"true\"></mat-icon>\n }\n <span class=\"prx-form-tabs__tab-label\">{{ tab.label }}</span>\n @if (tab.badge != null) {\n <span class=\"prx-form-tabs__tab-badge\">{{ tab.badge }}</span>\n }\n @if (getTabErrorCount(tab) > 0) {\n <span class=\"prx-form-tabs__tab-error-badge\" [attr.aria-label]=\"getTabErrorCount(tab) + ' erros na aba'\">\n {{ getTabErrorCount(tab) }}\n </span>\n }\n </button>\n }\n </div>\n </nav>\n }\n\n @for (section of (config.sections || []); track (section.id ?? $index); let sectionIndex = $index) {\n <div class=\"section-drop-wrapper\" [attr.data-section-id]=\"section.id\" [hidden]=\"!isSectionInActiveTab(section)\"\n [attr.role]=\"effectiveLayoutMode === 'tabs' ? 'tabpanel' : null\"\n [attr.id]=\"effectiveLayoutMode === 'tabs' ? ('section-tabpanel-' + section.id) : null\"\n [attr.aria-labelledby]=\"effectiveLayoutMode === 'tabs' ? ('tab-' + (getTabIdForSection(section) || section.id)) : null\">\n @if (isSectionVisible(section)) {\n <div #sectionEl class=\"form-section canvas-element\" data-canvas-type=\"section\" [attr.data-section-id]=\"section.id\"\n [attr.data-section-index]=\"sectionIndex\" (mouseenter)=\"onElementMouseEnter($event, 'section', section, sectionEl)\"\n (mouseleave)=\"onElementMouseLeave($event)\" (click)=\"onElementClick($event, 'section', section, sectionEl)\"\n [class.selected]=\"selectedElement?.domElement === sectionEl\"\n [class.hovered]=\"hoveredElement?.domElement === sectionEl && selectedElement?.domElement !== sectionEl\"\n [attr.data-section-appearance]=\"getSectionAppearance(section) || null\"\n [attr.data-section-divider]=\"isSectionDividerEnabled(section) ? 'true' : null\"\n [attr.data-presentation-preset]=\"effectivePresentation ? getSectionPresentationPreset(section) : null\"\n [class.form-section--corporate-dossier]=\"isSectionCorporateDossier(section)\"\n [class.form-section--editorial-card]=\"isSectionEditorialCard(section)\"\n [class.form-section--compact-presentation]=\"isSectionCompactPresentation(section)\"\n [style.marginBottom.px]=\"!isLastVisibleSection(section) ? getSectionGapBottom(section) : null\" [ngClass]=\"getSectionClasses(section)\"\n [ngStyle]=\"getSectionStyles(section)\">\n @if (!shouldHideSectionHeader(section)) {\n <div\n class=\"section-heading\"\n [class.align-center]=\"getSectionHeaderAlign(section) === 'center'\"\n [class.step-appearance]=\"getSectionAppearance(section) === 'step'\"\n [class.title-only]=\"isSectionHeaderTitleOnly(section)\"\n >\n <div class=\"section-heading-text\" [matTooltip]=\"getSectionHeaderTooltip(section) || null\"\n [matTooltipDisabled]=\"!getSectionHeaderTooltip(section)\">\n @if (getSectionStepLabel(section)) {\n <div class=\"section-step-label\" [class.align-center]=\"getSectionHeaderAlign(section) === 'center'\">\n {{ getSectionStepLabel(section) }}\n </div>\n }\n @if (getSectionTitle(section)) {\n <h3 class=\"section-title\" [class.title-large]=\"getSectionTitleStyle(section) === 'titleLarge'\"\n [class.title-medium]=\"getSectionTitleStyle(section) === 'titleMedium'\"\n [class.title-small]=\"getSectionTitleStyle(section) === 'titleSmall'\"\n [class.headline-small]=\"getSectionTitleStyle(section) === 'headlineSmall'\"\n [style.marginBottom.px]=\"getEffectiveSectionTitleGapBottom(section)\" [style.color]=\"getSectionTitleColor(section) || null\"\n [class.align-center]=\"getSectionHeaderAlign(section) === 'center'\"\n [attr.id]=\"sectionPanelId(section, sectionIndex) + '-title'\">\n @let sectionHeaderVisual = getSectionHeaderVisual(section);\n @let sectionHeaderAvatarSize = getSectionHeaderAvatarSize(section);\n @if (sectionHeaderVisual.kind === 'icon') {\n <mat-icon class=\"section-title-icon\" aria-hidden=\"true\" [praxisIcon]=\"sectionHeaderVisual.icon\"></mat-icon>\n }\n @if (sectionHeaderVisual.kind === 'image') {\n <img class=\"section-title-avatar section-title-avatar-image\" [class.size-sm]=\"sectionHeaderAvatarSize === 'sm'\"\n [class.size-md]=\"sectionHeaderAvatarSize === 'md'\" [class.size-lg]=\"sectionHeaderAvatarSize === 'lg'\"\n [src]=\"sectionHeaderVisual.src\" [alt]=\"sectionHeaderVisual.alt\" />\n }\n @if (sectionHeaderVisual.kind === 'initials') {\n <span class=\"section-title-avatar section-title-avatar-text\" [class.size-sm]=\"sectionHeaderAvatarSize === 'sm'\"\n [class.size-md]=\"sectionHeaderAvatarSize === 'md'\" [class.size-lg]=\"sectionHeaderAvatarSize === 'lg'\" aria-hidden=\"true\">\n {{ sectionHeaderVisual.text }}\n </span>\n @if (sectionHeaderVisual.ariaLabel) {\n <span class=\"section-title-avatar-sr-only\">{{ sectionHeaderVisual.ariaLabel }}</span>\n }\n }\n @if (sectionHeaderVisual.kind === 'placeholder') {\n <span class=\"section-title-avatar section-title-avatar-placeholder\" [class.size-sm]=\"sectionHeaderAvatarSize === 'sm'\"\n [class.size-md]=\"sectionHeaderAvatarSize === 'md'\" [class.size-lg]=\"sectionHeaderAvatarSize === 'lg'\" aria-hidden=\"true\">\n @if (sectionHeaderVisual.icon) {\n <mat-icon aria-hidden=\"true\" [praxisIcon]=\"sectionHeaderVisual.icon\"></mat-icon>\n }\n @if (sectionHeaderVisual.text) {\n <span>{{ sectionHeaderVisual.text }}</span>\n }\n </span>\n @if (sectionHeaderVisual.ariaLabel) {\n <span class=\"section-title-avatar-sr-only\">{{ sectionHeaderVisual.ariaLabel }}</span>\n }\n }\n {{ getSectionTitle(section) }}\n @if (enableCustomization) {\n <button type=\"button\" class=\"inline-edit-btn\" praxisIconButton=\"edit\" size=\"dense\" (click)=\"openSectionEditor(section, 'title')\"\n aria-label=\"Editar t\u00EDtulo da se\u00E7\u00E3o\" matTooltip=\"Editar t\u00EDtulo\">\n </button>\n }\n </h3>\n }\n @if (getSectionDescription(section)) {\n <p class=\"section-description\" [class.body-large]=\"getSectionDescriptionStyle(section) === 'bodyLarge'\"\n [class.body-medium]=\"getSectionDescriptionStyle(section) === 'bodyMedium'\"\n [class.body-small]=\"getSectionDescriptionStyle(section) === 'bodySmall'\"\n [style.marginBottom.px]=\"getSectionDescriptionGapBottom(section) ?? 8\" [style.color]=\"getSectionDescriptionColor(section) || null\"\n [class.align-center]=\"getSectionHeaderAlign(section) === 'center'\">\n {{ getSectionDescription(section) }}\n @if (enableCustomization) {\n <button type=\"button\" class=\"inline-edit-btn\" praxisIconButton=\"edit\" size=\"dense\"\n (click)=\"openSectionEditor(section, 'description')\" aria-label=\"Editar descri\u00E7\u00E3o da se\u00E7\u00E3o\"\n matTooltip=\"Editar descri\u00E7\u00E3o\">\n </button>\n }\n </p>\n }\n </div>\n @if (getSectionHeaderActions(section).length) {\n <div class=\"section-heading-actions\" [class.align-center]=\"getSectionHeaderAlign(section) === 'center'\">\n @for (action of getSectionHeaderActions(section); track action.id) {\n <button\n type=\"button\"\n class=\"section-heading-action-btn\"\n [praxisIconButton]=\"action.icon\"\n size=\"compact\"\n [busy]=\"action.loading\"\n [disabled]=\"isSectionHeaderActionDisabled(action)\"\n [matTooltip]=\"getSectionHeaderActionTooltip(action)\"\n [attr.aria-label]=\"action.label\"\n [attr.aria-busy]=\"action.loading ? 'true' : null\"\n [ngClass]=\"getSectionHeaderActionNgClass(action)\"\n [ngStyle]=\"getSectionHeaderActionStyles(action)\"\n (click)=\"onSectionHeaderActionClick(section, action, $event)\"\n >\n @if (action.loading) {\n <span class=\"section-heading-action-sr-only\">{{ getSectionHeaderActionLoadingLabel(action) }}</span>\n }\n </button>\n }\n </div>\n }\n @if (isSectionCollapsible(section)) {\n <button type=\"button\" class=\"section-collapse-btn\" [praxisIconButton]=\"isSectionCollapsed(section) ? 'expand_more' : 'expand_less'\" size=\"compact\"\n (click)=\"toggleSectionCollapse($event, section)\" [attr.aria-expanded]=\"!isSectionCollapsed(section)\"\n [attr.aria-controls]=\"sectionPanelId(section, sectionIndex)\"\n [attr.aria-label]=\"isSectionCollapsed(section) ? 'Expandir se\u00E7\u00E3o' : 'Recolher se\u00E7\u00E3o'\">\n </button>\n }\n </div>\n }\n\n <div class=\"section-body\" [class.collapsed]=\"isSectionCollapsed(section)\"\n [attr.id]=\"sectionPanelId(section, sectionIndex)\"\n [attr.role]=\"getSectionTitle(section) ? 'region' : null\"\n [attr.aria-labelledby]=\"getSectionTitle(section) ? sectionPanelId(section, sectionIndex) + '-title' : null\">\n @if (!isSectionCollapsed(section)) {\n @for (row of section.rows; track (row.id ?? $index); let rowIndex = $index) {\n @if (isRowVisible(row)) {\n <div class=\"row-drop-wrapper\" [attr.data-section-id]=\"section.id\">\n <div #rowEl class=\"form-row grid-12 canvas-element\" data-canvas-type=\"row\" [attr.data-row-index]=\"rowIndex\"\n [attr.data-section-id]=\"section.id\" [attr.data-row-id]=\"row.id\" [style.--pfx-grid-gap.px]=\"getRowGap(row)\"\n [style.--pfx-field-gap.px]=\"getRowRowGap(row)\"\n [style.--pfx-mount-index]=\"rowIndex\"\n [style.marginBottom.px]=\"rowIndex < section.rows.length - 1 ? (getRowRowGap(row) ?? null) : null\"\n [ngClass]=\"getRowClasses(row)\" [ngStyle]=\"getRowStyles(row)\"\n (mouseenter)=\"onElementMouseEnter($event, 'row', row, rowEl)\" (mouseleave)=\"onElementMouseLeave($event)\"\n (click)=\"onElementClick($event, 'row', row, rowEl)\" [class.selected]=\"selectedElement?.domElement === rowEl\"\n [class.hovered]=\"hoveredElement?.domElement === rowEl && selectedElement?.domElement !== rowEl\">\n @for (column of row.columns; track (column.id ?? $index); let colIndex = $index) {\n @if (isColumnVisible(column)) {\n <div class=\"column-drop-wrapper\" [attr.data-section-id]=\"section.id\" [attr.data-row-id]=\"row.id\">\n <div #colEl class=\"form-column canvas-element\" [ngClass]=\"getColumnClasses(column, row)\"\n [style.padding.px]=\"getColumnPadding(column)\" [style.--pfx-field-gap.px]=\"getRowRowGap(row)\"\n [ngStyle]=\"getColumnStyles(column)\" [attr.data-testid]=\"column.testId || null\"\n [attr.data-row-gap]=\"getRowRowGap(row)\" data-canvas-type=\"column\" [attr.data-column-index]=\"colIndex\"\n [attr.data-row-index]=\"rowIndex\" [attr.data-section-id]=\"section.id\" [attr.data-row-id]=\"row.id\"\n [attr.data-column-id]=\"column.id\" (mouseenter)=\"onElementMouseEnter($event, 'column', column, colEl)\"\n (mouseleave)=\"onElementMouseLeave($event)\" (click)=\"onElementClick($event, 'column', column, colEl)\"\n [class.selected]=\"selectedElement?.domElement === colEl\"\n [class.hovered]=\"hoveredElement?.domElement === colEl && selectedElement?.domElement !== colEl\">\n @for (renderItem of getColumnRenderItems(column); track renderItem.id) {\n @if (renderItem.kind === 'fields') {\n <ng-container dynamicFieldLoader [fields]=\"getRenderableFieldsForLoader(renderItem.fields)\" [formGroup]=\"form\"\n [enableExternalControlBinding]=\"true\"\n [readonlyMode]=\"effectiveReadonly\"\n [disabledMode]=\"effectiveDisabledMode\"\n [presentationMode]=\"presentationForLoader\" [visible]=\"visibleGlobal === null ? null : visibleGlobal\"\n [canvasMode]=\"enableCustomization\" (canvasMouseEnter)=\"onFieldMouseEnter($event)\"\n (canvasMouseLeave)=\"onFieldMouseLeave($event)\" (canvasClick)=\"onFieldClick($event)\"\n (canvasFocus)=\"onFieldFocus($event)\"\n (renderError)=\"onFieldRenderError($event)\">\n </ng-container>\n } @else {\n <praxis-rich-content\n class=\"form-layout-rich-content\"\n [ngClass]=\"renderItem.className || null\"\n [ngStyle]=\"renderItem.style || null\"\n [document]=\"renderItem.document\"\n [layout]=\"renderItem.layout\"\n [rootClassName]=\"renderItem.rootClassName || ''\"\n [context]=\"getEditorialRichContentContext()\"\n [hostCapabilities]=\"richContentHostCapabilities\"\n ></praxis-rich-content>\n }\n }\n </div>\n </div>\n } }\n </div>\n </div>\n }\n }\n } @else {\n <div class=\"section-collapsed-placeholder\">\n <mat-icon aria-hidden=\"true\" [praxisIcon]=\"'unfold_more'\"></mat-icon>\n <span>{{ getSectionCollapsedSummary(section) }}</span>\n </div>\n }\n @if (isLastVisibleSection(section) && beforeActionsPlacement === 'insideLastSection' && formBlocksBeforeActions?.nodes?.length) {\n <section class=\"form-editorial-blocks form-editorial-blocks-before-actions\" data-editorial-placement=\"beforeActions\">\n <praxis-rich-content\n [document]=\"formBlocksBeforeActionsDocument\"\n [context]=\"getEditorialRichContentContext()\"\n [hostCapabilities]=\"richContentHostCapabilities\"\n ></praxis-rich-content>\n </section>\n }\n @if (actionPlacement === 'insideLastSection' && isLastVisibleSection(section) && !(effectivePresentation\n || effectiveReadonly)) {\n <praxis-form-actions data-actions-placement=\"insideLastSection\" [actions]=\"effectiveActions\"\n [isSubmitting]=\"submitting\" [formIsValid]=\"effectiveFormIsValid\" [submitError]=\"submitError\" [formId]=\"formId\"\n [actionOverrides]=\"actionRuleProps\" [invalidRequiredFieldLabels]=\"invalidRequiredFieldLabels\"\n [suppressInvalidSubmitHint]=\"entityHydrationPending\"\n [editorialVisualContext]=\"hasEditorialVisualContext()\"\n (action)=\"onFormAction($event)\"></praxis-form-actions>\n }\n </div>\n <!-- Overlay de bloqueio durante submiss\u00E3o -->\n @if (submitting) {\n <div class=\"form-blocking-overlay\" aria-live=\"polite\">\n <mat-progress-spinner\n diameter=\"40\"\n color=\"primary\"\n [attr.aria-label]=\"config.messages?.loading?.submit || 'Salvando formul\u00E1rio'\"\n ></mat-progress-spinner>\n <p>{{ config.messages?.loading?.submit || 'Salvando...' }}</p>\n </div>\n }\n </div>\n\n @if (enableCustomization && selectedElement?.domElement === sectionEl) {\n <div class=\"add-section-container\">\n <div class=\"add-section-line\"></div>\n <button mat-fab color=\"primary\" aria-label=\"Adicionar nova se\u00E7\u00E3o\" (click)=\"addNewSectionAfter(sectionIndex)\"\n matTooltip=\"Adicionar nova se\u00E7\u00E3o aqui\">\n <mat-icon [praxisIcon]=\"'add'\"></mat-icon>\n </button>\n <div class=\"add-section-line\"></div>\n </div>\n }\n }\n </div>\n }\n\n @if (beforeActionsPlacement !== 'insideLastSection' && formBlocksBeforeActions?.nodes?.length) {\n <section class=\"form-editorial-blocks form-editorial-blocks-before-actions\" data-editorial-placement=\"beforeActions\">\n <praxis-rich-content\n [document]=\"formBlocksBeforeActionsDocument\"\n [context]=\"getEditorialRichContentContext()\"\n [hostCapabilities]=\"richContentHostCapabilities\"\n ></praxis-rich-content>\n </section>\n }\n\n @if (actionPlacement === 'afterSections' && !(effectivePresentation || effectiveReadonly)) {\n <praxis-form-actions data-actions-placement=\"afterSections\" [actions]=\"effectiveActions\" [isSubmitting]=\"submitting\"\n [formIsValid]=\"effectiveFormIsValid\" [submitError]=\"submitError\" [formId]=\"formId\"\n [actionOverrides]=\"actionRuleProps\" [invalidRequiredFieldLabels]=\"invalidRequiredFieldLabels\"\n [suppressInvalidSubmitHint]=\"entityHydrationPending\"\n [editorialVisualContext]=\"hasEditorialVisualContext()\"\n (action)=\"onFormAction($event)\"></praxis-form-actions>\n }\n\n @if (formBlocksAfter?.nodes?.length) {\n <section class=\"form-editorial-blocks form-editorial-blocks-after\" data-editorial-placement=\"after\">\n <praxis-rich-content\n [document]=\"formBlocksAfterDocument\"\n [context]=\"getEditorialRichContentContext()\"\n [hostCapabilities]=\"richContentHostCapabilities\"\n ></praxis-rich-content>\n </section>\n }\n </form>\n </div>\n }\n @if (showAiAssistant && !enableCustomization && (mode === 'view' || mode === 'presentation' || mode === 'dossier') && !shouldShowContextEmptyState()) {\n <div class=\"ai-floating-assistant\">\n <button type=\"button\" praxisIconButton=\"auto_awesome\" size=\"compact\" (click)=\"openAiAssistant()\" [disabled]=\"isLoading || entityHydrationPending || entityReadFailed\"\n [attr.data-testid]=\"aiAssistantTriggerTestId('view-floating')\"\n aria-label=\"Abrir copiloto semantico Praxis do formulario\"\n matTooltip=\"Pedir ajuda sobre este formul\u00E1rio\">\n </button>\n </div>\n }\n @if (showAiAssistant && aiAssistantOpen && aiAssistantViewState) {\n <praxis-ai-assistant-shell\n [labels]=\"aiAssistantLabels\"\n [mode]=\"aiAssistantViewState.mode\"\n [state]=\"aiAssistantViewState.state\"\n [contextItems]=\"aiAssistantViewState.contextItems\"\n [attachments]=\"aiAssistantViewState.attachments\"\n [messages]=\"aiAssistantViewState.messages\"\n [quickReplies]=\"aiAssistantViewState.quickReplies\"\n [prompt]=\"aiAssistantPrompt\"\n [statusText]=\"aiAssistantViewState.statusText\"\n [errorText]=\"aiAssistantViewState.errorText\"\n [busy]=\"aiAssistantViewState.state === 'processing' || aiAssistantViewState.state === 'applying'\"\n [canApply]=\"aiAssistantViewState.canApply\"\n [layout]=\"aiAssistantLayout\"\n testIdPrefix=\"dynamic-form-ai-assistant\"\n panelTestId=\"dynamic-form-ai-assistant-panel\"\n submitTestId=\"dynamic-form-ai-assistant-submit\"\n applyTestId=\"dynamic-form-ai-assistant-apply\"\n (promptChange)=\"onAiAssistantPromptChange($event)\"\n (submitPrompt)=\"onAiAssistantSubmit($event)\"\n (apply)=\"onAiAssistantApply()\"\n (retryTurn)=\"onAiAssistantRetry()\"\n (cancelTurn)=\"onAiAssistantCancel()\"\n (quickReply)=\"onAiAssistantQuickReply($event)\"\n (editMessage)=\"onAiAssistantEditMessage($event)\"\n (resendMessage)=\"onAiAssistantResendMessage($event)\"\n (layoutChange)=\"onAiAssistantLayoutChange($event)\"\n (close)=\"closeAiAssistant()\"\n ></praxis-ai-assistant-shell>\n }\n }\n", styles: ["@charset \"UTF-8\";.span-xs-1{grid-column:span 1}.span-xs-2{grid-column:span 2}.span-xs-3{grid-column:span 3}.span-xs-4{grid-column:span 4}.span-xs-5{grid-column:span 5}.span-xs-6{grid-column:span 6}.span-xs-7{grid-column:span 7}.span-xs-8{grid-column:span 8}.span-xs-9{grid-column:span 9}.span-xs-10{grid-column:span 10}.span-xs-11{grid-column:span 11}.span-xs-12{grid-column:span 12}.offset-xs-0{margin-left:0%}.offset-xs-1{margin-left:calc(1 / 12 * 100%)}.offset-xs-2{margin-left:calc(2 / 12 * 100%)}.offset-xs-3{margin-left:25%}.offset-xs-4{margin-left:calc(4 / 12 * 100%)}.offset-xs-5{margin-left:calc(5 / 12 * 100%)}.offset-xs-6{margin-left:50%}.offset-xs-7{margin-left:calc(7 / 12 * 100%)}.offset-xs-8{margin-left:calc(8 / 12 * 100%)}.offset-xs-9{margin-left:75%}.offset-xs-10{margin-left:calc(10 / 12 * 100%)}.offset-xs-11{margin-left:calc(11 / 12 * 100%)}.order-xs--12{order:-12}.order-xs--11{order:-11}.order-xs--10{order:-10}.order-xs--9{order:-9}.order-xs--8{order:-8}.order-xs--7{order:-7}.order-xs--6{order:-6}.order-xs--5{order:-5}.order-xs--4{order:-4}.order-xs--3{order:-3}.order-xs--2{order:-2}.order-xs--1{order:-1}.order-xs-0{order:0}.order-xs-1{order:1}.order-xs-2{order:2}.order-xs-3{order:3}.order-xs-4{order:4}.order-xs-5{order:5}.order-xs-6{order:6}.order-xs-7{order:7}.order-xs-8{order:8}.order-xs-9{order:9}.order-xs-10{order:10}.order-xs-11{order:11}.order-xs-12{order:12}.hidden-xs{display:none}@container praxis-form-row (min-width: 600px){.span-sm-1{grid-column:span 1}.span-sm-2{grid-column:span 2}.span-sm-3{grid-column:span 3}.span-sm-4{grid-column:span 4}.span-sm-5{grid-column:span 5}.span-sm-6{grid-column:span 6}.span-sm-7{grid-column:span 7}.span-sm-8{grid-column:span 8}.span-sm-9{grid-column:span 9}.span-sm-10{grid-column:span 10}.span-sm-11{grid-column:span 11}.span-sm-12{grid-column:span 12}.offset-sm-0{margin-left:0%}.offset-sm-1{margin-left:calc(1 / 12 * 100%)}.offset-sm-2{margin-left:calc(2 / 12 * 100%)}.offset-sm-3{margin-left:25%}.offset-sm-4{margin-left:calc(4 / 12 * 100%)}.offset-sm-5{margin-left:calc(5 / 12 * 100%)}.offset-sm-6{margin-left:50%}.offset-sm-7{margin-left:calc(7 / 12 * 100%)}.offset-sm-8{margin-left:calc(8 / 12 * 100%)}.offset-sm-9{margin-left:75%}.offset-sm-10{margin-left:calc(10 / 12 * 100%)}.offset-sm-11{margin-left:calc(11 / 12 * 100%)}.order-sm--12{order:-12}.order-sm--11{order:-11}.order-sm--10{order:-10}.order-sm--9{order:-9}.order-sm--8{order:-8}.order-sm--7{order:-7}.order-sm--6{order:-6}.order-sm--5{order:-5}.order-sm--4{order:-4}.order-sm--3{order:-3}.order-sm--2{order:-2}.order-sm--1{order:-1}.order-sm-0{order:0}.order-sm-1{order:1}.order-sm-2{order:2}.order-sm-3{order:3}.order-sm-4{order:4}.order-sm-5{order:5}.order-sm-6{order:6}.order-sm-7{order:7}.order-sm-8{order:8}.order-sm-9{order:9}.order-sm-10{order:10}.order-sm-11{order:11}.order-sm-12{order:12}.hidden-sm{display:none}}@container praxis-form-row (min-width: 900px){.span-md-1{grid-column:span 1}.span-md-2{grid-column:span 2}.span-md-3{grid-column:span 3}.span-md-4{grid-column:span 4}.span-md-5{grid-column:span 5}.span-md-6{grid-column:span 6}.span-md-7{grid-column:span 7}.span-md-8{grid-column:span 8}.span-md-9{grid-column:span 9}.span-md-10{grid-column:span 10}.span-md-11{grid-column:span 11}.span-md-12{grid-column:span 12}.offset-md-0{margin-left:0%}.offset-md-1{margin-left:calc(1 / 12 * 100%)}.offset-md-2{margin-left:calc(2 / 12 * 100%)}.offset-md-3{margin-left:25%}.offset-md-4{margin-left:calc(4 / 12 * 100%)}.offset-md-5{margin-left:calc(5 / 12 * 100%)}.offset-md-6{margin-left:50%}.offset-md-7{margin-left:calc(7 / 12 * 100%)}.offset-md-8{margin-left:calc(8 / 12 * 100%)}.offset-md-9{margin-left:75%}.offset-md-10{margin-left:calc(10 / 12 * 100%)}.offset-md-11{margin-left:calc(11 / 12 * 100%)}.order-md--12{order:-12}.order-md--11{order:-11}.order-md--10{order:-10}.order-md--9{order:-9}.order-md--8{order:-8}.order-md--7{order:-7}.order-md--6{order:-6}.order-md--5{order:-5}.order-md--4{order:-4}.order-md--3{order:-3}.order-md--2{order:-2}.order-md--1{order:-1}.order-md-0{order:0}.order-md-1{order:1}.order-md-2{order:2}.order-md-3{order:3}.order-md-4{order:4}.order-md-5{order:5}.order-md-6{order:6}.order-md-7{order:7}.order-md-8{order:8}.order-md-9{order:9}.order-md-10{order:10}.order-md-11{order:11}.order-md-12{order:12}.hidden-md{display:none}}@container praxis-form-row (min-width: 1200px){.span-lg-1{grid-column:span 1}.span-lg-2{grid-column:span 2}.span-lg-3{grid-column:span 3}.span-lg-4{grid-column:span 4}.span-lg-5{grid-column:span 5}.span-lg-6{grid-column:span 6}.span-lg-7{grid-column:span 7}.span-lg-8{grid-column:span 8}.span-lg-9{grid-column:span 9}.span-lg-10{grid-column:span 10}.span-lg-11{grid-column:span 11}.span-lg-12{grid-column:span 12}.offset-lg-0{margin-left:0%}.offset-lg-1{margin-left:calc(1 / 12 * 100%)}.offset-lg-2{margin-left:calc(2 / 12 * 100%)}.offset-lg-3{margin-left:25%}.offset-lg-4{margin-left:calc(4 / 12 * 100%)}.offset-lg-5{margin-left:calc(5 / 12 * 100%)}.offset-lg-6{margin-left:50%}.offset-lg-7{margin-left:calc(7 / 12 * 100%)}.offset-lg-8{margin-left:calc(8 / 12 * 100%)}.offset-lg-9{margin-left:75%}.offset-lg-10{margin-left:calc(10 / 12 * 100%)}.offset-lg-11{margin-left:calc(11 / 12 * 100%)}.order-lg--12{order:-12}.order-lg--11{order:-11}.order-lg--10{order:-10}.order-lg--9{order:-9}.order-lg--8{order:-8}.order-lg--7{order:-7}.order-lg--6{order:-6}.order-lg--5{order:-5}.order-lg--4{order:-4}.order-lg--3{order:-3}.order-lg--2{order:-2}.order-lg--1{order:-1}.order-lg-0{order:0}.order-lg-1{order:1}.order-lg-2{order:2}.order-lg-3{order:3}.order-lg-4{order:4}.order-lg-5{order:5}.order-lg-6{order:6}.order-lg-7{order:7}.order-lg-8{order:8}.order-lg-9{order:9}.order-lg-10{order:10}.order-lg-11{order:11}.order-lg-12{order:12}.hidden-lg{display:none}}@container praxis-form-row (min-width: 1536px){.span-xl-1{grid-column:span 1}.span-xl-2{grid-column:span 2}.span-xl-3{grid-column:span 3}.span-xl-4{grid-column:span 4}.span-xl-5{grid-column:span 5}.span-xl-6{grid-column:span 6}.span-xl-7{grid-column:span 7}.span-xl-8{grid-column:span 8}.span-xl-9{grid-column:span 9}.span-xl-10{grid-column:span 10}.span-xl-11{grid-column:span 11}.span-xl-12{grid-column:span 12}.offset-xl-0{margin-left:0%}.offset-xl-1{margin-left:calc(1 / 12 * 100%)}.offset-xl-2{margin-left:calc(2 / 12 * 100%)}.offset-xl-3{margin-left:25%}.offset-xl-4{margin-left:calc(4 / 12 * 100%)}.offset-xl-5{margin-left:calc(5 / 12 * 100%)}.offset-xl-6{margin-left:50%}.offset-xl-7{margin-left:calc(7 / 12 * 100%)}.offset-xl-8{margin-left:calc(8 / 12 * 100%)}.offset-xl-9{margin-left:75%}.offset-xl-10{margin-left:calc(10 / 12 * 100%)}.offset-xl-11{margin-left:calc(11 / 12 * 100%)}.order-xl--12{order:-12}.order-xl--11{order:-11}.order-xl--10{order:-10}.order-xl--9{order:-9}.order-xl--8{order:-8}.order-xl--7{order:-7}.order-xl--6{order:-6}.order-xl--5{order:-5}.order-xl--4{order:-4}.order-xl--3{order:-3}.order-xl--2{order:-2}.order-xl--1{order:-1}.order-xl-0{order:0}.order-xl-1{order:1}.order-xl-2{order:2}.order-xl-3{order:3}.order-xl-4{order:4}.order-xl-5{order:5}.order-xl-6{order:6}.order-xl-7{order:7}.order-xl-8{order:8}.order-xl-9{order:9}.order-xl-10{order:10}.order-xl-11{order:11}.order-xl-12{order:12}.hidden-xl{display:none}}.canvas-mode-enabled{--canvas-hit: 14px}.canvas-mode-enabled .canvas-element{position:relative;z-index:0;border-radius:8px;outline:2px solid transparent;outline-offset:2px;transition:outline-color .2s ease,outline-style .2s ease}.canvas-mode-enabled .canvas-element:before{content:\"\";position:absolute;inset:calc(-1 * var(--canvas-hit));pointer-events:none;border-radius:inherit;background:transparent}.canvas-mode-enabled .canvas-element[data-canvas-type=section]{--outline-color: var(--md-sys-color-primary)}.canvas-mode-enabled .canvas-element[data-canvas-type=row]{--outline-color: var(--md-sys-color-secondary)}.canvas-mode-enabled .canvas-element[data-canvas-type=column],.canvas-mode-enabled .canvas-element[data-canvas-type=field]{--outline-color: var(--md-sys-color-tertiary)}.canvas-mode-enabled .canvas-element[data-canvas-type=actions]{--outline-color: var(--md-sys-color-primary)}.canvas-mode-enabled .canvas-element.hovered:not(.selected){outline-color:var(--outline-color, var(--md-sys-color-primary));outline-style:dashed}.canvas-mode-enabled .canvas-element.selected{outline-color:var(--outline-color, var(--md-sys-color-primary));outline-style:solid;box-shadow:0 0 0 2px var(--outline-color, var(--md-sys-color-primary))}.canvas-mode-enabled .canvas-element.hovered{z-index:var(--praxis-layer-authoring-hover, 300)}.canvas-mode-enabled .canvas-element.selected{z-index:var(--praxis-layer-authoring-selected, 320)}.section-drop-wrapper,.row-drop-wrapper,.column-drop-wrapper{display:contents}.add-section-container{display:flex;align-items:center;justify-content:center;padding:.5rem 0;margin:-.5rem 0;position:relative;z-index:var(--praxis-layer-authoring-insert, 280)}.add-section-container .add-section-line{flex-grow:1;height:1px;background:repeating-linear-gradient(90deg,var(--md-sys-color-outline-variant),var(--md-sys-color-outline-variant) 4px,transparent 4px,transparent 8px)}.add-section-container button{margin:0 1rem;transform:scale(.85)}:host{display:block;position:relative;--pfx-editorial-form-radius: var(--pfx-form-section-radius, 8px);--pfx-editorial-form-border: var( --pfx-form-stroke, var(--pdx-color-border-subtle, var(--md-sys-color-outline-variant)) );--pfx-editorial-form-surface: var( --pfx-form-section-surface, var(--pdx-color-surface, var(--md-sys-color-surface-container)) );--pfx-editorial-form-surface-muted: var( --pdx-color-surface-muted, var(--md-sys-color-surface-container-low) );--pfx-form-shell-surface: color-mix( in srgb, var(--pfx-editorial-form-surface) 36%, transparent );--pfx-form-section-divider: color-mix( in srgb, var(--pfx-editorial-form-border) 68%, transparent );--pfx-form-footer-surface: color-mix( in srgb, var(--pfx-editorial-form-surface) 70%, var(--pfx-editorial-form-surface-muted) 30% );--pfx-form-footer-border: color-mix( in srgb, var(--pfx-editorial-form-border) 76%, transparent );--pfx-form-shell-padding: clamp(.9rem, 1.4vw, 1.2rem)}.form-config-controls{position:relative;top:auto;margin:0;display:flex;align-items:center;gap:.35rem;z-index:60;background:color-mix(in srgb,var(--pfx-form-shell-surface) 88%,var(--md-sys-color-surface) 12%);padding:8px var(--pfx-form-shell-padding);border:1px solid var(--pfx-form-footer-border);border-bottom-color:color-mix(in srgb,var(--pfx-form-footer-border) 72%,transparent);border-radius:var(--pfx-editorial-form-radius) var(--pfx-editorial-form-radius) 0 0;-webkit-backdrop-filter:blur(12px);backdrop-filter:blur(12px);box-shadow:none;min-width:0;justify-content:flex-end;pointer-events:none;opacity:.96;transition:opacity .16s ease,border-color .16s ease}.form-config-controls>*{pointer-events:auto}.form-config-controls:hover,.form-config-controls:focus-within{opacity:1;border-color:color-mix(in srgb,var(--md-sys-color-primary) 26%,var(--md-sys-color-outline-variant) 74%)}.form-config-controls .praxis-icon-button{color:var(--md-sys-color-on-surface-variant)}.form-config-controls .praxis-icon-button:hover{color:var(--md-sys-color-primary)}.ai-floating-assistant{position:sticky;right:0;bottom:12px;margin-top:14px;margin-left:auto;width:fit-content;z-index:70;pointer-events:none}.ai-floating-assistant button{pointer-events:auto;display:inline-flex}.ai-floating-assistant .ai-trigger-btn{box-shadow:0 12px 28px #0f172a24}.config-button{color:var(--md-sys-color-primary)}.form-loading{display:flex;flex-direction:column;align-items:stretch;justify-content:center;padding:1.25rem;text-align:left;color:var(--md-sys-color-on-surface);gap:1rem;min-height:220px;border:1px solid color-mix(in srgb,var(--md-sys-color-primary) 14%,var(--md-sys-color-outline-variant) 86%);border-radius:8px;background:linear-gradient(135deg,color-mix(in srgb,var(--md-sys-color-primary) 8%,transparent),transparent 42%),color-mix(in srgb,var(--md-sys-color-surface-container-low) 78%,var(--md-sys-color-surface) 22%);box-shadow:0 12px 28px #0f172a14}.entity-read-region{position:relative;min-width:0}.entity-read-feedback{position:absolute;inset:0;display:flex;flex-direction:column;align-items:center;justify-content:flex-start;gap:1rem;padding:2rem 1rem;box-sizing:border-box;text-align:center;color:var(--md-sys-color-on-surface)}.entity-read-feedback p{margin:0;max-width:40ch}.form-loading-header{display:flex;align-items:center;gap:.85rem}.form-loading-copy{min-width:0}.form-loading p{margin:0}.form-loading-title{font-weight:700;color:var(--md-sys-color-on-surface)}.form-loading-subtitle{margin-top:.2rem;font-size:.875rem;color:var(--md-sys-color-on-surface-variant)}.form-loading-skeleton{display:grid;gap:.7rem}.form-loading-line,.form-loading-field{display:block;overflow:hidden;position:relative;border-radius:6px;background:color-mix(in srgb,var(--md-sys-color-surface-container-high) 74%,var(--md-sys-color-primary) 6%)}.form-loading-line:after,.form-loading-field:after{content:\"\";position:absolute;inset:0;transform:translate(-100%);background:linear-gradient(90deg,transparent,color-mix(in srgb,var(--md-sys-color-primary) 16%,white 18%),transparent);animation:form-loading-shimmer 1.4s ease-in-out infinite}.form-loading-line{height:12px}.form-loading-line-title{width:min(42%,240px)}.form-loading-line-short{width:min(64%,360px)}.form-loading-field{height:44px}.form-loading-field-wide{height:72px}@keyframes form-loading-shimmer{to{transform:translate(100%)}}@media(prefers-reduced-motion:reduce){.form-loading-line:after,.form-loading-field:after{animation:none;transform:none;opacity:.28}}.form-error{display:flex;flex-direction:column;align-items:center;justify-content:center;padding:3rem;text-align:center;color:var(--md-sys-color-error);gap:1rem;border:1px solid var(--md-sys-color-error);border-radius:8px;background-color:var(--md-sys-color-error-container);margin:1rem;box-shadow:0 12px 30px #7f1d1d1f}.form-error h3{margin:0;color:var(--md-sys-color-on-error-container)}.form-error p{margin:0;color:var(--md-sys-color-on-error-container);opacity:.8}.form-error button{margin-top:.5rem}.pfx-form-info-banner{margin-bottom:14px;padding:12px 14px;border-radius:16px;border:1px solid color-mix(in srgb,var(--md-sys-color-primary) 18%,var(--md-sys-color-outline-variant) 82%);background:color-mix(in srgb,var(--md-sys-color-primary-container) 24%,var(--md-sys-color-surface) 76%);color:var(--md-sys-color-on-surface);display:flex;align-items:flex-start;justify-content:space-between;gap:14px}.pfx-form-info-banner .text{font-size:.92rem;line-height:1.5;font-weight:600}.pfx-form-info-banner .actions{display:flex;flex-wrap:wrap;justify-content:flex-end;gap:8px}.praxis-dynamic-form{display:flex;flex-direction:column;max-width:100%;min-width:0;transition:all .3s ease;position:relative;font-family:inherit;font-size:inherit;color:inherit;--pfx-editorial-form-surface: var( --pfx-form-section-surface, var(--md-sys-color-surface-container) );--pfx-editorial-form-surface-muted: var( --pdx-color-surface-muted, var(--md-sys-color-surface-container-low) );--pfx-editorial-form-border: var( --pfx-form-stroke, var(--pdx-color-border-subtle, var(--md-sys-color-outline-variant)) );--pfx-editorial-form-text: var( --pdx-color-text-primary, var(--md-sys-color-on-surface) );--pfx-editorial-form-text-muted: var( --pdx-color-text-secondary, var(--md-sys-color-on-surface-variant) );--pfx-editorial-form-field-surface: color-mix( in srgb, var(--pfx-editorial-form-surface-muted) 76%, var(--pfx-editorial-form-surface) 24% );--pfx-editorial-form-field-outline: color-mix( in srgb, var(--pfx-editorial-form-border) 88%, transparent );--pfx-editorial-form-accent: var( --pdx-color-primary, var(--md-sys-color-primary) );--pfx-editorial-form-accent-text: var(--md-sys-color-on-primary);--pfx-editorial-form-radius: var(--pfx-form-section-radius, 8px);--pfx-editorial-form-field-radius: var(--pfx-form-field-radius, 4px);--pfx-editorial-form-border-width: 1px;--pfx-editorial-form-field-border-width: 1px;--pfx-editorial-form-shadow: none;--pfx-form-shell-surface: color-mix( in srgb, var(--pfx-editorial-form-surface) 36%, transparent );--pfx-form-section-surface-flat: color-mix( in srgb, var(--pfx-editorial-form-surface) 78%, var(--pfx-editorial-form-surface-muted) 22% );--pfx-form-section-divider: color-mix( in srgb, var(--pfx-editorial-form-border) 68%, transparent );--pfx-form-label-strong: color-mix( in srgb, var(--pfx-editorial-form-text) 96%, white 4% );--pfx-form-label-muted: color-mix( in srgb, var(--pfx-editorial-form-text-muted) 92%, var(--pfx-editorial-form-text) 8% );--pfx-form-field-surface-rest: color-mix( in srgb, var(--pfx-editorial-form-field-surface) 82%, var(--pfx-editorial-form-surface) 18% );--pfx-form-field-surface-focus: color-mix( in srgb, var(--pfx-editorial-form-accent) 4%, var(--pfx-form-field-surface-rest) 96% );--pfx-form-field-min-height: 48px;--pfx-form-section-padding: clamp(1.1rem, 1.8vw, 1.5rem);--pfx-form-section-gap: 22px;--pdx-presentation-label-size: var(--pfx-pres-compact-label-size, .78rem);--pdx-presentation-value-size: var(--pfx-pres-compact-value-size, 1rem);--pdx-presentation-icon-size: var(--pfx-pres-icon-size, 18px);--pdx-presentation-row-gap: var(--pfx-pres-row-gap, .5rem);--pdx-presentation-column-gap: var(--pfx-pres-column-gap, .5rem);--pdx-presentation-section-gap: var(--pfx-pres-section-gap, .75rem);--pdx-presentation-label-width: var(--pfx-pres-label-width, 220px);--pdx-presentation-flag-height: var(--pfx-pres-boolean-min-height, 22px);--pdx-presentation-flag-radius: var(--pfx-pres-boolean-radius, 999px);--pdx-presentation-flag-padding: var(--pfx-pres-boolean-padding, 0 8px);--pdx-presentation-flag-active-color: var( --pfx-pres-boolean-active-color, var(--md-sys-color-primary) );--pdx-presentation-flag-active-bg: var( --pfx-pres-boolean-active-bg, color-mix(in srgb, var(--md-sys-color-primary) 14%, transparent) );--pdx-presentation-flag-inactive-color: var( --pfx-pres-boolean-inactive-color, var(--md-sys-color-on-surface-variant) );--pdx-presentation-flag-inactive-bg: var( --pfx-pres-boolean-inactive-bg, color-mix(in srgb, var(--md-sys-color-outline-variant) 34%, transparent) );--pfx-form-footer-surface: color-mix( in srgb, var(--pfx-editorial-form-surface) 70%, var(--pfx-editorial-form-surface-muted) 30% );--pfx-form-footer-border: color-mix( in srgb, var(--pfx-editorial-form-border) 76%, transparent )}.praxis-dynamic-form.canvas-mode-enabled{border:1px solid var(--pfx-form-footer-border);border-radius:var(--pfx-editorial-form-radius);background:linear-gradient(180deg,color-mix(in srgb,var(--pfx-form-shell-surface) 86%,transparent),color-mix(in srgb,var(--pfx-editorial-form-surface-muted) 42%,transparent));overflow:visible}.form-config-controls+.praxis-dynamic-form.canvas-mode-enabled{border-top:0;border-top-left-radius:0;border-top-right-radius:0}.praxis-dynamic-form.canvas-mode-enabled>.section-drop-wrapper,.praxis-dynamic-form.canvas-mode-enabled>.form-editorial-blocks{margin-inline:var(--pfx-form-shell-padding)}.praxis-dynamic-form.canvas-mode-enabled>.section-drop-wrapper:first-of-type,.praxis-dynamic-form.canvas-mode-enabled>.form-editorial-blocks:first-child{margin-top:var(--pfx-form-shell-padding)}.praxis-dynamic-form.canvas-mode-enabled>praxis-form-actions[data-actions-placement=afterSections]{display:block;margin-top:var(--pfx-form-shell-padding)}.praxis-dynamic-form.editorial-visual-context{--_pfx-editorial-host-text: var( --editorial-text-primary, var(--foreground, var(--mat-sys-on-surface, #1d1b20)) );--_pfx-editorial-host-text-muted: var( --editorial-text-secondary, var( --muted-foreground, color-mix(in srgb, var(--_pfx-editorial-host-text) 64%, transparent) ) );--_pfx-editorial-host-surface: var( --editorial-surface-primary, var(--card, var(--mat-sys-surface-container, #ffffff)) );--_pfx-editorial-host-surface-muted: var( --editorial-surface-secondary, var(--surface-dim, var(--muted, var(--mat-sys-surface-container-low, #f7f2fa))) );--_pfx-editorial-host-border: var( --editorial-border-color, var(--border, var(--mat-sys-outline-variant, #cac4d0)) );--_pfx-editorial-host-accent: var( --editorial-cta-primary, var(--editorial-accent, var(--primary, var(--mat-sys-primary, #6750a4))) );--_pfx-editorial-host-accent-text: var( --editorial-cta-primary-text, var( --editorial-accent-contrast, var(--primary-foreground, var(--mat-sys-on-primary, #ffffff)) ) );--_pfx-editorial-host-accent-container: var( --primary-container, color-mix(in srgb, var(--_pfx-editorial-host-accent) 16%, var(--_pfx-editorial-host-surface) 84%) );--_pfx-editorial-host-accent-container-text: var( --primary-container-fg, var(--_pfx-editorial-host-accent) );font-family:var(--editorial-body-font-family, inherit);font-size:var(--editorial-body-size, 1rem);color:var(--_pfx-editorial-host-text);--pfx-editorial-form-surface: var( --editorial-surface-primary, var(--pfx-form-section-surface, var(--_pfx-editorial-host-surface)) );--pfx-editorial-form-surface-muted: var( --editorial-surface-secondary, var(--_pfx-editorial-host-surface-muted) );--pfx-editorial-form-border: var( --editorial-border-color, var(--pfx-form-stroke, var(--_pfx-editorial-host-border)) );--pfx-editorial-form-text: var( --editorial-text-primary, var(--_pfx-editorial-host-text) );--pfx-editorial-form-text-muted: var( --editorial-text-secondary, color-mix( in srgb, var(--_pfx-editorial-host-text-muted) 86%, var(--_pfx-editorial-host-text) 14% ) );--pfx-editorial-form-accent: var( --editorial-cta-primary, var(--editorial-accent, var(--_pfx-editorial-host-accent)) );--pfx-editorial-form-accent-text: var( --editorial-cta-primary-text, var(--editorial-accent-contrast, var(--_pfx-editorial-host-accent-text)) );--pfx-editorial-form-accent-container: var(--_pfx-editorial-host-accent-container);--pfx-editorial-form-accent-container-text: var(--_pfx-editorial-host-accent-container-text);--pfx-editorial-form-radius: var(--editorial-card-radius, 18px);--pfx-editorial-form-field-radius: var( --editorial-field-radius, var(--editorial-card-radius, 14px) );--pfx-editorial-form-border-width: var(--editorial-card-border-width, 1px);--pfx-editorial-form-field-border-width: var(--editorial-field-border-width, 1px);--pfx-editorial-form-shadow: var(--editorial-card-shadow, none);--md-sys-color-surface: var( --pfx-editorial-form-surface, var(--md-sys-color-surface) );--md-sys-color-surface-container: var( --pfx-editorial-form-surface, var(--md-sys-color-surface-container) );--md-sys-color-surface-container-low: var( --pfx-editorial-form-surface-muted, var(--md-sys-color-surface-container-low) );--md-sys-color-surface-variant: var( --pfx-editorial-form-field-surface, var(--md-sys-color-surface-variant) );--md-sys-color-outline: var( --pfx-editorial-form-field-outline, var(--md-sys-color-outline) );--md-sys-color-outline-variant: var( --pfx-editorial-form-border, var(--md-sys-color-outline-variant) );--md-sys-color-on-surface: var( --editorial-text-primary, inherit );--md-sys-color-on-surface-variant: var( --editorial-text-secondary, inherit );--md-sys-color-primary: var( --pfx-editorial-form-accent, var(--md-sys-color-primary) );--md-sys-color-primary-container: var( --pfx-editorial-form-accent-container, var(--md-sys-color-primary-container) );--md-sys-color-on-primary-container: var( --pfx-editorial-form-accent-container-text, var(--md-sys-color-on-primary-container) );--md-sys-color-on-primary: var( --pfx-editorial-form-accent-text, var(--md-sys-color-on-primary) );--md-sys-color-on-surface-rgb: var( --editorial-text-primary-rgb, inherit );--mat-sys-on-surface: var( --editorial-text-primary, inherit );--mat-sys-on-surface-variant: var( --editorial-text-secondary, inherit );--mat-sys-on-surface-rgb: var( --editorial-text-primary-rgb, inherit );color:inherit;color-scheme:light}.praxis-dynamic-form.presentation-mode .form-row,.praxis-dynamic-form.readonly-mode .form-row{gap:var(--pdx-presentation-column-gap);margin-bottom:var(--pdx-presentation-row-gap)}.praxis-dynamic-form.presentation-mode{--pfx-pres-on-surface: var( --pdx-color-text-primary, var(--pfx-editorial-form-text, var(--pfx-form-label-strong, currentColor)) );--pfx-pres-on-surface-variant: var( --pdx-color-text-secondary, var( --pfx-editorial-form-text-muted, var( --pfx-form-label-muted, color-mix(in srgb, var(--pfx-pres-on-surface) 78%, transparent) ) ) )}.praxis-dynamic-form.presentation-mode .form-section,.praxis-dynamic-form.readonly-mode .form-section{padding:var(--pdx-presentation-section-gap) .875rem}.praxis-dynamic-form.pres-compact .form-row{gap:var(--pdx-presentation-column-gap, .35rem);margin-bottom:var(--pdx-presentation-row-gap, .35rem)}.praxis-dynamic-form.pres-compact .form-section{padding:var(--pdx-presentation-section-gap, .5rem) .75rem}.praxis-dynamic-form.pres-label-left .praxis-presentation{display:grid;grid-template-columns:minmax(0,var(--pfx-presentation-label-w, var(--pdx-presentation-label-width))) minmax(0,1fr);align-items:baseline;column-gap:var(--pdx-presentation-column-gap, 10px)}.praxis-dynamic-form.pres-label-left .praxis-presentation__label{text-align:right;margin-bottom:0}@media(max-width:480px){.praxis-dynamic-form.pres-label-left .praxis-presentation{grid-template-columns:minmax(0,1fr);row-gap:4px}.praxis-dynamic-form.pres-label-left .praxis-presentation__label{text-align:start}}.praxis-dynamic-form.praxis-dynamic-form--corporate-dossier .form-section:not(.section-appearance-plain),.praxis-dynamic-form .form-section.form-section--corporate-dossier:not(.section-appearance-plain),.praxis-dynamic-form .form-section[data-presentation-preset=corporate-dossier]:not(.section-appearance-plain){background:var(--md-sys-color-surface-container-low, #f8f9fa);border:1px solid var(--md-sys-color-outline-variant, #e0e2ec);border-radius:16px;padding:16px 20px;box-shadow:0 1px 3px #0000000a}.praxis-dynamic-form.praxis-dynamic-form--corporate-dossier .form-section .section-heading,.praxis-dynamic-form .form-section.form-section--corporate-dossier .section-heading,.praxis-dynamic-form .form-section[data-presentation-preset=corporate-dossier] .section-heading{margin-bottom:12px;padding-bottom:8px;border-bottom:1px solid var(--md-sys-color-outline-variant, #e0e2ec)}.praxis-dynamic-form.praxis-dynamic-form--corporate-dossier .form-section .section-title,.praxis-dynamic-form .form-section.form-section--corporate-dossier .section-title,.praxis-dynamic-form .form-section[data-presentation-preset=corporate-dossier] .section-title{font-size:.88rem;font-weight:700;letter-spacing:.05em;text-transform:uppercase;color:var(--md-sys-color-primary, #005ac1)}:host ::ng-deep .praxis-dynamic-form--corporate-dossier .praxis-presentation,:host ::ng-deep .form-section--corporate-dossier .praxis-presentation,:host ::ng-deep [data-presentation-preset=corporate-dossier] .praxis-presentation{padding:8px 0;border-bottom:1px dashed var(--md-sys-color-outline-variant, rgba(0, 0, 0, .08))}:host ::ng-deep .praxis-dynamic-form--corporate-dossier .form-row:last-child .praxis-presentation,:host ::ng-deep .praxis-dynamic-form--corporate-dossier .praxis-presentation:last-child,:host ::ng-deep .form-section--corporate-dossier .form-row:last-child .praxis-presentation,:host ::ng-deep .form-section--corporate-dossier .praxis-presentation:last-child,:host ::ng-deep [data-presentation-preset=corporate-dossier] .form-row:last-child .praxis-presentation,:host ::ng-deep [data-presentation-preset=corporate-dossier] .praxis-presentation:last-child{border-bottom:none}:host ::ng-deep .praxis-dynamic-form--corporate-dossier .praxis-presentation__label,:host ::ng-deep .form-section--corporate-dossier .praxis-presentation__label,:host ::ng-deep [data-presentation-preset=corporate-dossier] .praxis-presentation__label{font-size:.74rem;font-weight:600;text-transform:uppercase;letter-spacing:.05em;color:var(--md-sys-color-on-surface-variant, #44474f);margin-bottom:3px}:host ::ng-deep .praxis-dynamic-form--corporate-dossier .praxis-presentation__value,:host ::ng-deep .form-section--corporate-dossier .praxis-presentation__value,:host ::ng-deep [data-presentation-preset=corporate-dossier] .praxis-presentation__value{font-size:.95rem;font-weight:600;color:var(--md-sys-color-on-surface, #1a1c1e);line-height:1.4}.praxis-dynamic-form.praxis-dynamic-form--editorial-card .form-section:not(.section-appearance-plain),.praxis-dynamic-form .form-section.form-section--editorial-card:not(.section-appearance-plain),.praxis-dynamic-form .form-section[data-presentation-preset=editorial-card]:not(.section-appearance-plain){background:var(--pfx-editorial-form-surface, var(--md-sys-color-surface-container-low, #ffffff));border:1px solid var(--pfx-editorial-form-border, var(--md-sys-color-outline-variant, #e0e2ec));border-radius:20px;padding:24px;box-shadow:0 2px 8px #0000000d}.praxis-dynamic-form.praxis-dynamic-form--editorial-card .form-section .section-heading,.praxis-dynamic-form .form-section.form-section--editorial-card .section-heading,.praxis-dynamic-form .form-section[data-presentation-preset=editorial-card] .section-heading{margin-bottom:16px;padding-bottom:10px;border-bottom:1px solid color-mix(in srgb,var(--md-sys-color-outline-variant, #e0e2ec) 40%,transparent)}.praxis-dynamic-form.praxis-dynamic-form--editorial-card .form-section .section-title,.praxis-dynamic-form .form-section.form-section--editorial-card .section-title,.praxis-dynamic-form .form-section[data-presentation-preset=editorial-card] .section-title{font-size:1.15rem;font-weight:700;color:var(--pfx-editorial-form-accent, var(--md-sys-color-primary, #005ac1))}:host ::ng-deep .praxis-dynamic-form--editorial-card .praxis-presentation,:host ::ng-deep .form-section--editorial-card .praxis-presentation,:host ::ng-deep [data-presentation-preset=editorial-card] .praxis-presentation{padding:10px 0;border-bottom:1px solid color-mix(in srgb,var(--md-sys-color-outline-variant, #e0e2ec) 35%,transparent)}:host ::ng-deep .praxis-dynamic-form--editorial-card .form-row:last-child .praxis-presentation,:host ::ng-deep .praxis-dynamic-form--editorial-card .praxis-presentation:last-child,:host ::ng-deep .form-section--editorial-card .form-row:last-child .praxis-presentation,:host ::ng-deep .form-section--editorial-card .praxis-presentation:last-child,:host ::ng-deep [data-presentation-preset=editorial-card] .form-row:last-child .praxis-presentation,:host ::ng-deep [data-presentation-preset=editorial-card] .praxis-presentation:last-child{border-bottom:none}:host ::ng-deep .praxis-dynamic-form--editorial-card .praxis-presentation__label,:host ::ng-deep .form-section--editorial-card .praxis-presentation__label,:host ::ng-deep [data-presentation-preset=editorial-card] .praxis-presentation__label{font-size:.8rem;font-weight:500;color:var(--pfx-editorial-form-text-muted, var(--md-sys-color-on-surface-variant, #44474f));margin-bottom:4px}:host ::ng-deep .praxis-dynamic-form--editorial-card .praxis-presentation__value,:host ::ng-deep .form-section--editorial-card .praxis-presentation__value,:host ::ng-deep [data-presentation-preset=editorial-card] .praxis-presentation__value{font-size:1rem;font-weight:600;color:var(--pfx-editorial-form-text, var(--md-sys-color-on-surface, #1a1c1e));line-height:1.5}.praxis-dynamic-form.praxis-dynamic-form--compact-presentation .form-section:not(.section-appearance-plain),.praxis-dynamic-form .form-section.form-section--compact-presentation:not(.section-appearance-plain),.praxis-dynamic-form .form-section[data-presentation-preset=compact-presentation]:not(.section-appearance-plain){background:transparent;border:1px solid color-mix(in srgb,var(--md-sys-color-outline-variant, #e0e2ec) 50%,transparent);border-radius:8px;padding:10px 14px;box-shadow:none}.praxis-dynamic-form.praxis-dynamic-form--compact-presentation .form-section .section-heading,.praxis-dynamic-form .form-section.form-section--compact-presentation .section-heading,.praxis-dynamic-form .form-section[data-presentation-preset=compact-presentation] .section-heading{margin-bottom:8px;padding-bottom:4px;border-bottom:1px solid color-mix(in srgb,var(--md-sys-color-outline-variant, #e0e2ec) 25%,transparent)}.praxis-dynamic-form.praxis-dynamic-form--compact-presentation .form-section .section-title,.praxis-dynamic-form .form-section.form-section--compact-presentation .section-title,.praxis-dynamic-form .form-section[data-presentation-preset=compact-presentation] .section-title{font-size:.82rem;font-weight:700;letter-spacing:.03em;text-transform:uppercase;color:var(--md-sys-color-on-surface-variant, #44474f)}:host ::ng-deep .praxis-dynamic-form--compact-presentation .praxis-presentation,:host ::ng-deep .form-section--compact-presentation .praxis-presentation,:host ::ng-deep [data-presentation-preset=compact-presentation] .praxis-presentation{padding:4px 0;border-bottom:none}:host ::ng-deep .praxis-dynamic-form--compact-presentation .praxis-presentation__label,:host ::ng-deep .form-section--compact-presentation .praxis-presentation__label,:host ::ng-deep [data-presentation-preset=compact-presentation] .praxis-presentation__label{font-size:.72rem;font-weight:600;color:var(--md-sys-color-on-surface-variant, #44474f);margin-bottom:2px}:host ::ng-deep .praxis-dynamic-form--compact-presentation .praxis-presentation__value,:host ::ng-deep .form-section--compact-presentation .praxis-presentation__value,:host ::ng-deep [data-presentation-preset=compact-presentation] .praxis-presentation__value{font-size:.88rem;font-weight:500;color:var(--md-sys-color-on-surface, #1a1c1e);line-height:1.35}:host-context(.mdc-theme-dark) .praxis-dynamic-form.praxis-dynamic-form--corporate-dossier .form-section:not(.section-appearance-plain),:host-context(.mdc-theme-dark) .praxis-dynamic-form .form-section.form-section--corporate-dossier:not(.section-appearance-plain),:host-context(.mdc-theme-dark) .praxis-dynamic-form .form-section[data-presentation-preset=corporate-dossier]:not(.section-appearance-plain),:host-context(.theme-dark) .praxis-dynamic-form.praxis-dynamic-form--corporate-dossier .form-section:not(.section-appearance-plain),:host-context(.theme-dark) .praxis-dynamic-form .form-section.form-section--corporate-dossier:not(.section-appearance-plain),:host-context(.theme-dark) .praxis-dynamic-form .form-section[data-presentation-preset=corporate-dossier]:not(.section-appearance-plain){background:var(--md-sys-color-surface-container-low);border-color:color-mix(in srgb,var(--md-sys-color-outline-variant) 70%,transparent);box-shadow:0 2px 8px #0000004d}:host-context(.mdc-theme-dark) .praxis-dynamic-form.praxis-dynamic-form--editorial-card .form-section:not(.section-appearance-plain),:host-context(.mdc-theme-dark) .praxis-dynamic-form .form-section.form-section--editorial-card:not(.section-appearance-plain),:host-context(.mdc-theme-dark) .praxis-dynamic-form .form-section[data-presentation-preset=editorial-card]:not(.section-appearance-plain),:host-context(.theme-dark) .praxis-dynamic-form.praxis-dynamic-form--editorial-card .form-section:not(.section-appearance-plain),:host-context(.theme-dark) .praxis-dynamic-form .form-section.form-section--editorial-card:not(.section-appearance-plain),:host-context(.theme-dark) .praxis-dynamic-form .form-section[data-presentation-preset=editorial-card]:not(.section-appearance-plain){background:var(--pfx-editorial-form-surface, var(--md-sys-color-surface-container-low));border-color:color-mix(in srgb,var(--md-sys-color-outline-variant) 70%,transparent);box-shadow:0 4px 16px #0006}.form-section{border:1px solid var(--pfx-form-section-divider);border-radius:var(--pfx-editorial-form-radius);padding:var(--pfx-form-section-padding);max-width:100%;min-width:0;background:var(--pfx-form-section-surface-flat);box-shadow:none;transition:all .2s ease;position:relative}.praxis-dynamic-form.editorial-visual-context .form-section:not(.section-appearance-plain){border:var(--pfx-editorial-form-border-width) solid var(--pfx-editorial-form-border)!important;background:var(--pfx-editorial-form-surface)!important;color:var(--pfx-editorial-form-text);box-shadow:var(--editorial-card-shadow, none)}.praxis-dynamic-form.editorial-visual-context .form-section.section-appearance-step{background-color:var(--pfx-editorial-form-surface)!important;background-image:linear-gradient(180deg,color-mix(in srgb,var(--editorial-accent, var(--md-sys-color-primary)) 6%,transparent) 0%,transparent 132px)!important;background-repeat:no-repeat!important}.section-drop-wrapper>.form-section{margin-bottom:var(--pfx-section-gap, 20px)}.section-drop-wrapper:last-of-type>.form-section{margin-bottom:0}.praxis-dynamic-form>praxis-form-actions[data-actions-placement=afterSections]{margin-top:var(--pfx-actions-gap-top, var(--pfx-section-gap, 20px))}.section-title{margin:0 0 var(--pfx-section-title-mb, 12px) 0;font-family:var(--editorial-title-font-family, var(--editorial-body-font-family, inherit));font-size:var(--editorial-step-title-size, 1.12rem);font-weight:700;color:var(--pfx-form-label-strong)}.section-heading{position:relative;display:flex;align-items:flex-start;gap:12px;margin-bottom:18px;padding-bottom:var(--pfx-form-section-heading-divider-gap, 18px)}.section-heading:after{content:\"\";position:absolute;right:0;bottom:0;left:0;height:2px;pointer-events:none;background:linear-gradient(90deg,transparent 0%,color-mix(in srgb,var(--pfx-form-section-divider) 18%,transparent) 8%,var(--pfx-form-section-divider) 46%,var(--pfx-form-section-divider) 54%,color-mix(in srgb,var(--pfx-form-section-divider) 18%,transparent) 92%,transparent 100%);border-radius:999px;-webkit-mask-image:linear-gradient(90deg,transparent 0%,black 18%,black 82%,transparent 100%);mask-image:linear-gradient(90deg,transparent 0%,black 18%,black 82%,transparent 100%)}.section-heading.title-only{padding-bottom:var(--pfx-form-section-heading-title-only-divider-gap, 10px)}:host(.pfx-form-section-divider-inline-title) .section-heading.title-only{padding-bottom:var(--pfx-form-section-heading-title-only-inline-divider-gap, 0)}:host(.pfx-form-section-divider-inline-title) .section-heading.title-only:after{display:none}.section-heading.align-center{flex-direction:column;align-items:center;text-align:center}.section-heading.align-center .section-heading-text{display:grid;justify-items:center}.section-step-label{display:inline-flex;align-items:center;min-height:24px;padding:0 10px;margin:0 0 8px;border-radius:999px;background:color-mix(in srgb,var(--pfx-editorial-form-accent) 10%,transparent);color:color-mix(in srgb,var(--pfx-editorial-form-accent) 84%,var(--pfx-form-label-strong) 16%);font-size:.72rem;font-weight:800;font-family:var(--editorial-title-font-family, var(--editorial-body-font-family, inherit));letter-spacing:.08em;text-transform:uppercase}.section-heading-text{flex:1 1 auto;min-width:0}.section-heading-actions{display:inline-flex;align-items:center;align-self:flex-start;flex-wrap:wrap;gap:4px;margin-left:auto}.section-heading-actions.align-center{align-self:center;margin-left:0}.section-heading-action-btn{color:var(--pfx-form-label-muted)}.section-heading-action-btn.tone-primary{color:var(--md-sys-color-primary)}.section-heading-action-btn.tone-accent,.section-heading-action-btn.tone-secondary{color:var(--md-sys-color-tertiary)}.section-heading-action-btn.tone-warn,.section-heading-action-btn.tone-danger,.section-heading-action-btn.tone-error{color:var(--md-sys-color-error)}.section-heading-action-btn .mat-mdc-progress-spinner,.section-heading-action-btn mat-progress-spinner{--mdc-circular-progress-active-indicator-color: currentColor}.section-heading-action-btn.loading{opacity:.72;pointer-events:none}.section-heading-action-sr-only{position:absolute;width:1px;height:1px;padding:0;margin:-1px;overflow:hidden;clip:rect(0,0,0,0);white-space:nowrap;border:0}.section-collapse-btn{margin-left:4px;color:var(--pfx-form-label-muted)}.section-title.title-large{font:var(--mdc-typography-title-large, 500 22px/28px system-ui)}.section-title.title-medium{font:var(--mdc-typography-title-medium, 500 16px/24px system-ui)}.section-title.title-small{font:var(--mdc-typography-title-small, 500 14px/20px system-ui)}.section-title.headline-small{font:var(--mdc-typography-headline-small, 600 24px/32px system-ui)}.section-title.title-large,.section-title.title-medium,.section-title.title-small,.section-title.headline-small{font-family:var(--editorial-title-font-family, var(--editorial-body-font-family, inherit));font-weight:var(--editorial-title-weight, 600)}.section-description{margin:0;font-family:var(--editorial-body-font-family, inherit);font-size:.93rem;color:var(--pfx-form-label-muted);line-height:1.6}.section-description.body-large{font:var(--mdc-typography-body-large, 400 16px/24px system-ui)}.section-description.body-medium{font:var(--mdc-typography-body-medium, 400 14px/20px system-ui)}.section-description.body-small{font:var(--mdc-typography-body-small, 400 12px/16px system-ui)}.section-description.body-large,.section-description.body-medium,.section-description.body-small{font-family:var(--editorial-body-font-family, inherit);font-weight:var(--editorial-body-weight, 400)}.section-title.align-center,.section-description.align-center,.section-step-label.align-center{text-align:center}.praxis-dynamic-form .form-section.section-appearance-plain{border-color:transparent;border-width:0;border-radius:0;padding:0;background:transparent;box-shadow:none}.praxis-dynamic-form .form-section.section-appearance-plain.section-has-divider{padding-bottom:16px;border-bottom:1px solid var(--pfx-form-section-divider, var(--md-sys-color-outline-variant, #e0e2ec))}.praxis-dynamic-form .section-drop-wrapper:last-of-type>.form-section.section-appearance-plain.section-has-divider,.praxis-dynamic-form>.form-section.section-appearance-plain.section-has-divider:last-of-type{border-bottom:none;padding-bottom:0}.form-section.section-appearance-plain .section-heading{margin-bottom:14px}.form-section.section-appearance-step{border-radius:var(--pfx-editorial-form-radius);padding:var(--pfx-form-section-padding);background:var(--pfx-form-section-surface-flat);border-color:var(--pfx-form-section-divider);box-shadow:none}.praxis-dynamic-form.editorial-visual-context .form-section.section-appearance-step{border-radius:var(--editorial-card-radius, 20px);box-shadow:none}.form-section.section-appearance-step .section-heading{margin-bottom:22px;padding-bottom:var(--pfx-form-section-heading-divider-gap, 16px)}.form-section.section-appearance-step .section-heading.title-only{padding-bottom:var(--pfx-form-section-heading-title-only-divider-gap, 16px)}:host(.pfx-form-section-divider-inline-title) .form-section.section-appearance-step .section-heading.title-only{padding-bottom:var(--pfx-form-section-heading-title-only-inline-divider-gap, 0)}.form-section.section-appearance-step .section-title{font:var(--mdc-typography-title-large, 700 22px/28px system-ui);color:var(--pfx-form-label-strong);margin-bottom:8px}.form-section.section-appearance-step .section-description{color:var(--pfx-form-label-muted);max-width:60ch}.form-section.section-appearance-step .section-step-label{min-height:24px;padding:0 10px;margin-bottom:10px;box-shadow:none}.form-section.section-appearance-step .section-heading.align-center .section-description{max-width:52ch}.form-section.section-appearance-step .section-body{display:grid;gap:8px;padding-top:0}.form-section.section-appearance-step .form-row{margin-bottom:var(--pfx-field-gap, 1rem)}.form-section.section-appearance-step .form-column{gap:var(--pfx-field-gap, 12px)}.form-section .form-editorial-blocks{display:grid;gap:16px}.form-section .form-editorial-blocks[data-editorial-placement=beforeActions]{margin-top:24px;padding-top:18px;border-top:1px solid var(--pfx-form-section-divider)}.form-section.section-appearance-step .form-editorial-blocks[data-editorial-placement=beforeActions]{gap:18px}.form-section.section-appearance-step .form-editorial-blocks[data-editorial-placement=beforeActions]>*+*{margin-top:2px}.praxis-dynamic-form:not(.canvas-mode-enabled)>praxis-form-actions[data-actions-placement=afterSections]{margin-top:18px}.praxis-dynamic-form>.form-editorial-blocks[data-editorial-placement=after]{margin-top:6px}:host-context(.mdc-theme-dark) .form-section.section-appearance-step,:host-context(.theme-dark) .form-section.section-appearance-step{border-color:color-mix(in srgb,var(--pfx-editorial-form-border) 82%,transparent);box-shadow:none}:host-context(.mdc-theme-dark) .form-section.section-appearance-step .section-title,:host-context(.theme-dark) .form-section.section-appearance-step .section-title{color:color-mix(in srgb,var(--pfx-editorial-form-text) 96%,white)}:host-context(.mdc-theme-dark) .form-section.section-appearance-step .section-description,:host-context(.theme-dark) .form-section.section-appearance-step .section-description{color:color-mix(in srgb,var(--pfx-editorial-form-text-muted) 86%,var(--pfx-editorial-form-text) 14%)}:host-context(.mdc-theme-dark) .section-step-label,:host-context(.theme-dark) .section-step-label{background:color-mix(in srgb,var(--md-sys-color-primary-container) 54%,transparent);color:color-mix(in srgb,var(--md-sys-color-primary) 88%,white)}:host-context(.mdc-theme-dark) .form-section .form-editorial-blocks[data-editorial-placement=beforeActions],:host-context(.theme-dark) .form-section .form-editorial-blocks[data-editorial-placement=beforeActions]{border-top-color:color-mix(in srgb,var(--md-sys-color-outline-variant) 90%,transparent)}.inline-edit-btn{margin-left:6px;vertical-align:middle}.section-body.collapsed{border:1px dashed var(--md-sys-color-outline-variant);background:var(--md-sys-color-surface-container-low);border-radius:6px;padding:8px 10px}.section-collapsed-placeholder{display:flex;align-items:center;gap:8px;color:var(--md-sys-color-on-surface-variant);font-size:.95rem}.section-collapsed-placeholder mat-icon{font-size:20px;width:20px;height:20px}.form-row{display:flex;gap:1.1rem;margin-bottom:var(--pfx-field-gap, 1.1rem);max-width:100%;min-width:0;transition:all .2s ease;border-radius:6px;position:relative}.praxis-dynamic-form.pfx-mounting .form-row{opacity:0;transform:translateY(var(--pdx-form-mount-offset, 6px));animation:pdxFormMount var(--pdx-form-mount-duration, .16s) ease-out both;animation-delay:calc(var(--pfx-mount-index, 0) * var(--pdx-form-mount-stagger, 20ms))}@media(prefers-reduced-motion:reduce){.praxis-dynamic-form.pfx-mounting .form-row{animation:none;opacity:1;transform:none}}@keyframes pdxFormMount{to{opacity:1;transform:translateY(0)}}.praxis-dynamic-form .mat-mdc-form-field{width:100%;margin-bottom:var(--pfx-field-gap, 10px);font-family:inherit;--mdc-filled-text-field-container-color: var(--pfx-form-field-surface-rest);--mdc-filled-text-field-focus-active-indicator-color: var(--pfx-editorial-form-accent);--mdc-filled-text-field-active-indicator-color: var(--pfx-editorial-form-field-outline);--mdc-filled-text-field-hover-active-indicator-color: var(--pfx-editorial-form-accent);--mdc-filled-text-field-focus-label-text-color: var(--pfx-editorial-form-accent);--mdc-filled-text-field-label-text-color: var(--pfx-form-label-muted);--mdc-filled-text-field-input-text-color: var(--pfx-editorial-form-text);--mdc-filled-text-field-caret-color: var(--pfx-editorial-form-accent);--mdc-filled-text-field-input-text-placeholder-color: color-mix( in srgb, var(--pfx-editorial-form-text-muted) 82%, transparent );--mdc-outlined-text-field-outline-color: var(--pfx-editorial-form-field-outline);--mdc-outlined-text-field-hover-outline-color: var(--pfx-editorial-form-accent);--mdc-outlined-text-field-focus-outline-color: var(--pfx-editorial-form-accent);--mdc-outlined-text-field-focus-label-text-color: var(--pfx-editorial-form-accent);--mdc-outlined-text-field-label-text-color: var(--pfx-form-label-muted);--mdc-outlined-text-field-input-text-color: var(--pfx-editorial-form-text);--mdc-filled-text-field-container-shape: var(--pfx-editorial-form-field-radius);--mdc-outlined-text-field-container-shape: var(--pfx-editorial-form-field-radius);--mdc-filled-text-field-active-indicator-height: var(--pfx-editorial-form-field-border-width);--mdc-filled-text-field-focus-active-indicator-height: var(--pfx-editorial-form-field-border-width);--mdc-outlined-text-field-outline-width: var(--pfx-editorial-form-field-border-width);--mdc-outlined-text-field-focus-outline-width: var(--pfx-editorial-form-field-border-width);--mat-select-enabled-trigger-text-color: var(--pfx-editorial-form-text);--mat-select-enabled-arrow-color: var(--pfx-form-label-muted);--mat-form-field-enabled-select-arrow-color: var(--pfx-form-label-muted);--mat-form-field-focus-select-arrow-color: var(--pfx-editorial-form-accent);--mat-form-field-hover-state-layer-opacity: 0;--mat-form-field-focus-state-layer-opacity: 0}.praxis-dynamic-form.editorial-visual-context .mat-mdc-form-field{font-family:var(--editorial-body-font-family, inherit)}.praxis-dynamic-form .mat-mdc-text-field-wrapper,.praxis-dynamic-form .mdc-text-field{background:var(--pfx-form-field-surface-rest);border-radius:var(--pfx-editorial-form-field-radius);min-height:var(--pfx-form-field-min-height);transition:background-color .16s ease,box-shadow .16s ease,border-color .16s ease}.praxis-dynamic-form.editorial-visual-context .mat-mdc-text-field-wrapper,.praxis-dynamic-form.editorial-visual-context .mdc-text-field,.praxis-dynamic-form.editorial-visual-context .mdc-text-field--filled,.praxis-dynamic-form.editorial-visual-context .mdc-text-field--outlined{background-color:var(--pfx-form-field-surface-rest)!important;background:var(--pfx-form-field-surface-rest)!important}.praxis-dynamic-form .mat-mdc-form-field .mdc-floating-label,.praxis-dynamic-form .mat-mdc-form-field .mat-mdc-form-field-hint,.praxis-dynamic-form .mat-mdc-form-field .mat-mdc-form-field-error,.praxis-dynamic-form .mat-mdc-form-field .mat-mdc-form-field-required-marker,.praxis-dynamic-form .mat-mdc-form-field .mat-mdc-select-arrow,.praxis-dynamic-form .mat-mdc-form-field .mat-mdc-select-placeholder,.praxis-dynamic-form .mat-mdc-form-field .mat-mdc-form-field-icon-suffix,.praxis-dynamic-form .mat-mdc-form-field .mat-mdc-form-field-icon-prefix{color:var(--pfx-form-label-muted)}.praxis-dynamic-form .mat-mdc-input-element,.praxis-dynamic-form .mat-mdc-select-value-text,.praxis-dynamic-form .mat-mdc-form-field-infix,.praxis-dynamic-form .mat-mdc-select-min-line{color:var(--pfx-editorial-form-text)}.praxis-dynamic-form .mat-mdc-form-field:hover .mat-mdc-text-field-wrapper,.praxis-dynamic-form .mat-mdc-form-field:hover .mdc-text-field,.praxis-dynamic-form .mat-mdc-form-field.mat-focused .mat-mdc-text-field-wrapper,.praxis-dynamic-form .mat-mdc-form-field.mat-focused .mdc-text-field{background:var(--pfx-form-field-surface-focus)}.praxis-dynamic-form.editorial-visual-context .mat-mdc-input-element,.praxis-dynamic-form.editorial-visual-context .mat-mdc-select-value-text,.praxis-dynamic-form.editorial-visual-context .mat-mdc-form-field-infix,.praxis-dynamic-form.editorial-visual-context .mat-mdc-select-min-line,.praxis-dynamic-form.editorial-visual-context .mdc-text-field__input{color:var(--pfx-editorial-form-text)!important;-webkit-text-fill-color:var(--pfx-editorial-form-text)!important}.praxis-dynamic-form.editorial-visual-context .mat-mdc-form-field .mdc-floating-label,.praxis-dynamic-form.editorial-visual-context .mat-mdc-form-field .mat-mdc-form-field-hint,.praxis-dynamic-form.editorial-visual-context .mat-mdc-form-field .mat-mdc-form-field-error,.praxis-dynamic-form.editorial-visual-context .mat-mdc-form-field .mat-mdc-form-field-required-marker,.praxis-dynamic-form.editorial-visual-context .mat-mdc-form-field .mat-mdc-select-arrow,.praxis-dynamic-form.editorial-visual-context .mat-mdc-form-field .mat-mdc-select-placeholder,.praxis-dynamic-form.editorial-visual-context .mat-mdc-form-field .mat-mdc-form-field-icon-suffix,.praxis-dynamic-form.editorial-visual-context .mat-mdc-form-field .mat-mdc-form-field-icon-prefix{color:var(--pfx-editorial-form-text-muted)!important}.praxis-dynamic-form.editorial-visual-context .mat-mdc-floating-label,.praxis-dynamic-form.editorial-visual-context .mdc-floating-label,.praxis-dynamic-form.editorial-visual-context .mdc-text-field__input::placeholder{color:color-mix(in srgb,var(--pfx-editorial-form-text) 68%,transparent)!important}.praxis-dynamic-form.editorial-visual-context .mat-mdc-input-element::placeholder,.praxis-dynamic-form.editorial-visual-context textarea.mat-mdc-input-element::placeholder{color:color-mix(in srgb,var(--pfx-editorial-form-text) 58%,transparent)!important}.praxis-dynamic-form .mat-mdc-radio-button,.praxis-dynamic-form .mat-mdc-checkbox,.praxis-dynamic-form .mat-mdc-slide-toggle{--mdc-radio-selected-icon-color: var(--pfx-editorial-form-accent);--mdc-radio-selected-hover-icon-color: var(--pfx-editorial-form-accent);--mdc-radio-selected-focus-icon-color: var(--pfx-editorial-form-accent);--mdc-checkbox-selected-checkmark-color: var(--pfx-editorial-form-accent-text);--mdc-checkbox-selected-focus-icon-color: var(--pfx-editorial-form-accent);--mdc-checkbox-selected-hover-icon-color: var(--pfx-editorial-form-accent);--mdc-checkbox-selected-icon-color: var(--pfx-editorial-form-accent);--mdc-switch-selected-focus-state-layer-color: var(--pfx-editorial-form-accent);--mdc-switch-selected-handle-color: var(--pfx-editorial-form-accent);--mdc-switch-selected-track-color: color-mix(in srgb, var(--pfx-editorial-form-accent) 45%, #fff)}.praxis-dynamic-form [data-field-type=input],.praxis-dynamic-form [data-field-type=textarea],.praxis-dynamic-form [data-field-type=email],.praxis-dynamic-form [data-field-type=password],.praxis-dynamic-form [data-field-type=url],.praxis-dynamic-form [data-field-type=search],.praxis-dynamic-form [data-field-type=phone],.praxis-dynamic-form [data-field-type=numericTextBox],.praxis-dynamic-form [data-field-type=currency],.praxis-dynamic-form [data-field-type=cpfCnpj],.praxis-dynamic-form [data-field-type=date],.praxis-dynamic-form [data-field-type=dateInput],.praxis-dynamic-form [data-field-type=dateRange],.praxis-dynamic-form [data-field-type=dateTimeLocal],.praxis-dynamic-form [data-field-type=time],.praxis-dynamic-form [data-field-type=timePicker],.praxis-dynamic-form [data-field-type=timeRange],.praxis-dynamic-form [data-field-type=month],.praxis-dynamic-form [data-field-type=week],.praxis-dynamic-form [data-field-type=yearInput],.praxis-dynamic-form [data-field-type=select],.praxis-dynamic-form [data-field-type=multi-select],.praxis-dynamic-form [data-field-type=searchable-select],.praxis-dynamic-form [data-field-type=async-select],.praxis-dynamic-form [data-field-type=autocomplete],.praxis-dynamic-form [data-field-type=entityLookup],.praxis-dynamic-form [data-field-type=tree-select],.praxis-dynamic-form [data-field-type=multi-select-tree],.praxis-dynamic-form [data-field-type=priceRange],.praxis-dynamic-form [data-field-type=file-upload]{display:block;width:100%;min-width:0}.praxis-dynamic-form .mat-mdc-form-field-subscript-wrapper{min-height:var(--pfx-subscript-min-h, 22px)}.form-row:last-child{margin-bottom:0}.form-column{display:grid;grid-template-columns:minmax(0,1fr);align-content:start;gap:var(--pfx-field-gap, 10px);flex:1;max-width:100%;min-width:0;transition:all .2s ease;border-radius:4px;position:relative}.form-layout-rich-content{display:block;width:100%;max-width:100%;min-width:0;margin-bottom:var(--pfx-field-gap, 10px);color:var(--pfx-editorial-form-text-muted, var(--md-sys-color-on-surface-variant));font:var(--mdc-typography-body-medium, 400 14px/20px system-ui);overflow-wrap:anywhere}:host ::ng-deep .form-layout-rich-content .prx-rich-content-root{display:grid;gap:8px;min-width:0;max-width:100%}:host ::ng-deep .form-layout-rich-content .prx-rich-node{min-width:0;max-width:100%}:host ::ng-deep .form-layout-rich-content .prx-rich-text{color:inherit;line-height:20px}:host ::ng-deep .form-layout-rich-content .praxis-form-visual-block--note,:host ::ng-deep .form-layout-rich-content .praxis-rich-content-notice{border:1px solid color-mix(in srgb,var(--pfx-editorial-form-accent) 12%,var(--pfx-editorial-form-border) 88%);border-left:3px solid var(--pfx-editorial-form-accent);border-radius:8px;background:color-mix(in srgb,var(--pfx-editorial-form-accent-container) 12%,var(--pfx-editorial-form-surface-muted) 88%)}:host ::ng-deep .form-layout-rich-content .praxis-form-visual-block--note{display:grid;grid-template-columns:20px minmax(0,1fr);gap:10px;align-items:flex-start;padding:11px 12px}:host ::ng-deep .form-layout-rich-content .praxis-form-visual-block--note:before{content:\"info\";display:inline-flex;align-items:center;justify-content:center;width:20px;height:20px;color:var(--pfx-editorial-form-accent);font-family:Material Symbols Outlined;font-size:20px;font-weight:400;line-height:20px}:host ::ng-deep .form-layout-rich-content .praxis-form-visual-block--note .prx-rich-text{color:var(--pfx-editorial-form-text-muted)}:host ::ng-deep .form-layout-rich-content .praxis-rich-content-notice{padding:10px 12px;color:var(--pfx-editorial-form-text)}:host ::ng-deep .form-layout-rich-content .praxis-rich-content-notice .prx-rich-compose{align-items:flex-start;gap:10px}:host ::ng-deep .form-layout-rich-content .praxis-rich-content-notice .prx-rich-icon{color:var(--pfx-editorial-form-accent);font-size:20px;line-height:20px;margin-top:1px}:host ::ng-deep .form-layout-rich-content .praxis-rich-content-divider{display:grid;grid-template-columns:minmax(24px,1fr) auto minmax(24px,1fr);align-items:center;gap:10px;color:var(--pfx-editorial-form-text-muted);font:var(--mdc-typography-label-small, 600 12px/16px system-ui);text-transform:uppercase}:host ::ng-deep .form-layout-rich-content .praxis-rich-content-divider:before,:host ::ng-deep .form-layout-rich-content .praxis-rich-content-divider:after{content:\"\";height:1px;background:var(--pfx-editorial-form-border)}:host ::ng-deep .form-layout-rich-content .prx-rich-card{gap:6px;padding:12px 14px;border-color:var(--pfx-editorial-form-border);border-radius:8px;background:var(--pfx-editorial-form-surface-muted);color:var(--pfx-editorial-form-text);box-shadow:none}:host ::ng-deep .form-layout-rich-content .prx-rich-card-title{color:var(--pfx-editorial-form-text);font:var(--mdc-typography-title-small, 600 14px/20px system-ui)}:host ::ng-deep .form-layout-rich-content .prx-rich-card-subtitle,:host ::ng-deep .form-layout-rich-content .prx-rich-metric-caption{color:var(--pfx-editorial-form-text-muted)}:host ::ng-deep .form-layout-rich-content .prx-rich-card .prx-rich-text{color:var(--pfx-editorial-form-text-muted)}:host ::ng-deep .form-layout-rich-content .prx-rich-badge{background:var(--pfx-editorial-form-accent-container);color:var(--pfx-editorial-form-accent-container-text)}.form-row.grid-12{container-type:inline-size;container-name:praxis-form-row;display:grid;grid-template-columns:repeat(12,minmax(0,1fr));gap:var(--pfx-grid-gap, 16px)}.align-start{align-self:flex-start}.align-center{align-self:center}.align-end{align-self:flex-end}.align-stretch{align-self:stretch}.form-blocking-overlay{position:absolute;inset:0;background:transparent;color:var(--md-sys-color-on-surface);backdrop-filter:blur(2px) saturate(103%);-webkit-backdrop-filter:blur(2px) saturate(103%);display:flex;align-items:center;justify-content:center;flex-direction:column;gap:12px;z-index:10;pointer-events:all}@media(max-width:768px){.column-drop-wrapper,.row-drop-wrapper,.form-layout-rich-content,.praxis-dynamic-form .mat-mdc-form-field,.praxis-dynamic-form .mat-mdc-text-field-wrapper,.praxis-dynamic-form .mdc-text-field{max-width:100%;min-width:0}:host ::ng-deep .praxis-dynamic-form .pfx-field-shell,:host ::ng-deep .praxis-dynamic-form .pfx-field-shell-wrapper,:host ::ng-deep .praxis-dynamic-form .pfx-field-shell-host,:host ::ng-deep .praxis-dynamic-form .mat-mdc-form-field,:host ::ng-deep .praxis-dynamic-form .mat-mdc-text-field-wrapper,:host ::ng-deep .praxis-dynamic-form .mdc-text-field{width:100%;max-width:100%;min-width:0}.form-section{padding:clamp(.75rem,4vw,1rem)}.section-heading{gap:10px;margin-bottom:16px;padding-bottom:var(--pfx-form-section-heading-divider-gap, 14px)}.section-heading.title-only{padding-bottom:var(--pfx-form-section-heading-title-only-divider-gap, 8px)}}.section-title{display:flex;align-items:center;gap:8px}:host(.pfx-form-section-divider-inline-title) .section-heading.title-only .section-title{width:100%;min-width:0}:host(.pfx-form-section-divider-inline-title) .section-heading.title-only .section-title:after{content:\"\";display:block;flex:1 1 auto;min-width:var(--pfx-form-section-title-inline-divider-min-width, 48px);height:2px;margin-left:var(--pfx-form-section-title-inline-divider-gap, 12px);pointer-events:none;background:linear-gradient(90deg,var(--pfx-form-section-divider) 0%,var(--pfx-form-section-divider) 62%,color-mix(in srgb,var(--pfx-form-section-divider) 18%,transparent) 88%,transparent 100%);border-radius:999px;-webkit-mask-image:linear-gradient(90deg,black 0%,black 72%,transparent 100%);mask-image:linear-gradient(90deg,black 0%,black 72%,transparent 100%)}:host(.pfx-form-section-divider-inline-title) .section-heading.align-center .section-title:after{display:none}@media(max-width:640px){:host(.pfx-form-section-divider-inline-title) .section-heading.title-only{padding-bottom:var(--pfx-form-section-heading-title-only-divider-gap, 8px)}:host(.pfx-form-section-divider-inline-title) .section-heading.title-only:after{display:block}:host(.pfx-form-section-divider-inline-title) .section-heading.title-only .section-title{width:auto}:host(.pfx-form-section-divider-inline-title) .section-heading.title-only .section-title:after{display:none}}.section-title .section-title-icon{font-size:1.25em;line-height:1}.section-title-avatar{--_pfx-form-section-avatar-size: var(--pfx-form-section-avatar-size-md, var(--pfx-form-section-avatar-size, 32px));display:inline-flex;align-items:center;justify-content:center;width:var(--_pfx-form-section-avatar-size);height:var(--_pfx-form-section-avatar-size);border-radius:999px;flex:0 0 var(--_pfx-form-section-avatar-size);overflow:hidden}.section-title-avatar.size-sm{--_pfx-form-section-avatar-size: var(--pfx-form-section-avatar-size-sm, 24px)}.section-title-avatar.size-md{--_pfx-form-section-avatar-size: var(--pfx-form-section-avatar-size-md, var(--pfx-form-section-avatar-size, 32px))}.section-title-avatar.size-lg{--_pfx-form-section-avatar-size: var(--pfx-form-section-avatar-size-lg, 40px)}.section-title-avatar-image{object-fit:cover;border:1px solid color-mix(in srgb,var(--pfx-form-section-divider) 72%,transparent);background:var(--pfx-form-section-surface-flat)}.section-title-avatar-text,.section-title-avatar-placeholder{background:color-mix(in srgb,var(--pfx-editorial-form-accent) 14%,var(--pfx-form-section-surface-flat));color:color-mix(in srgb,var(--pfx-editorial-form-accent) 82%,var(--pfx-form-label-strong) 18%);font-size:calc(var(--_pfx-form-section-avatar-size) * .41);font-weight:800;letter-spacing:.04em;text-transform:uppercase}.section-title-avatar-placeholder mat-icon{font-size:calc(var(--_pfx-form-section-avatar-size) * .5625);width:calc(var(--_pfx-form-section-avatar-size) * .5625);height:calc(var(--_pfx-form-section-avatar-size) * .5625);line-height:calc(var(--_pfx-form-section-avatar-size) * .5625)}.section-title-avatar-sr-only{position:absolute;width:1px;height:1px;padding:0;margin:-1px;overflow:hidden;clip:rect(0,0,0,0);white-space:nowrap;border:0}.form-context-empty-state{display:grid;min-height:var(--pdx-form-context-empty-min-height, 0);place-items:center;padding:var(--pdx-form-context-empty-padding, 0)}.form-context-empty-state praxis-empty-state-card{display:block;width:min(100%,var(--pdx-form-context-empty-max-width, 32rem))}.prx-form-tabs{display:block;margin-bottom:16px;max-width:100%}.prx-form-tabs__tablist{display:flex;flex-wrap:wrap;align-items:center;gap:8px;max-width:100%}.prx-form-tabs__tablist--scrollable{flex-wrap:nowrap;overflow-x:auto;overflow-y:hidden;scrollbar-width:none;-webkit-overflow-scrolling:touch;padding:4px 2px}.prx-form-tabs__tablist--scrollable::-webkit-scrollbar{display:none}.prx-form-tabs__tab{display:inline-flex;align-items:center;gap:8px;min-width:0;padding:8px 14px;border-radius:999px;border:1px solid var(--md-sys-color-outline-variant, rgba(0, 0, 0, .12));background:color-mix(in srgb,var(--md-sys-color-surface, transparent) 40%,transparent);color:var(--md-sys-color-on-surface, #1d1b20);font-family:inherit;font-size:.84rem;font-weight:500;cursor:pointer;white-space:nowrap;flex-shrink:0;-webkit-user-select:none;user-select:none;transition:all .2s cubic-bezier(.2,0,0,1)}.prx-form-tabs__tab:hover:not(:disabled):not(.prx-form-tabs__tab--active){background:var(--md-sys-color-surface-container-high, rgba(0, 0, 0, .05));border-color:var(--md-sys-color-outline, rgba(0, 0, 0, .24));color:var(--md-sys-color-on-surface)}.prx-form-tabs__tab:focus-visible{outline:2px solid var(--md-sys-color-primary, #005ac1);outline-offset:2px}.prx-form-tabs__tab:disabled{cursor:not-allowed;opacity:.45}.prx-form-tabs__tab--active{background:var(--md-sys-color-primary-container, color-mix(in srgb, var(--md-sys-color-primary, #005ac1) 16%, var(--md-sys-color-surface-container-high, #2b2930)));color:var(--md-sys-color-on-primary-container, var(--md-sys-color-primary, #005ac1));border-color:transparent;font-weight:600;box-shadow:0 1px 3px #00000014}.prx-form-tabs__tab-icon{font-size:18px;width:18px;height:18px;display:inline-flex;align-items:center;justify-content:center}.prx-form-tabs__tab-badge{display:inline-flex;align-items:center;justify-content:center;padding:1px 7px;font-size:.72rem;font-weight:600;border-radius:999px;background:color-mix(in srgb,currentColor 14%,transparent)}.prx-form-tabs__tab-error-badge{display:inline-flex;align-items:center;justify-content:center;min-width:18px;height:18px;padding:0 5px;border-radius:999px;font-size:.7rem;font-weight:700;background:var(--md-sys-color-error, #ba1a1a);color:var(--md-sys-color-on-error, #ffffff);box-shadow:0 1px 2px #0003}.prx-form-tabs[data-appearance=underline]{border-bottom:1px solid var(--md-sys-color-outline-variant, #cac4d0)}.prx-form-tabs[data-appearance=underline] .prx-form-tabs__tablist{gap:16px;padding-bottom:0}.prx-form-tabs[data-appearance=underline] .prx-form-tabs__tab{border:none;border-radius:0;border-bottom:2px solid transparent;background:transparent;padding:8px 4px 10px;margin-bottom:-1px}.prx-form-tabs[data-appearance=underline] .prx-form-tabs__tab:hover:not(:disabled):not(.prx-form-tabs__tab--active){background:transparent;border-bottom-color:var(--md-sys-color-outline-variant, #cac4d0)}.prx-form-tabs[data-appearance=underline] .prx-form-tabs__tab--active{background:transparent;box-shadow:none;border-bottom-color:var(--md-sys-color-primary, #005ac1);color:var(--md-sys-color-primary, #005ac1)}.prx-form-tabs[data-appearance=buttons] .prx-form-tabs__tablist{background:var(--md-sys-color-surface-container, rgba(0, 0, 0, .04));border-radius:12px;padding:4px;gap:4px;border:1px solid var(--md-sys-color-outline-variant, rgba(0, 0, 0, .08))}.prx-form-tabs[data-appearance=buttons] .prx-form-tabs__tab{border:none;border-radius:8px;padding:6px 12px;background:transparent}.prx-form-tabs[data-appearance=buttons] .prx-form-tabs__tab:hover:not(:disabled):not(.prx-form-tabs__tab--active){background:color-mix(in srgb,currentColor 8%,transparent)}.prx-form-tabs[data-appearance=buttons] .prx-form-tabs__tab--active{background:var(--md-sys-color-surface, #ffffff);color:var(--md-sys-color-primary, #005ac1);box-shadow:0 1px 3px #0000001f}.section-drop-wrapper[hidden]{display:none!important}\n"] }]
|
|
22000
|
+
], template: "@if (isLoading) {\n <!-- Loading State -->\n <div class=\"form-loading\" role=\"status\" aria-live=\"polite\" aria-label=\"Carregando formul\u00E1rio\">\n <div class=\"form-loading-header\">\n <mat-progress-spinner diameter=\"32\" aria-label=\"Carregando formul\u00E1rio\"></mat-progress-spinner>\n <div class=\"form-loading-copy\">\n <p class=\"form-loading-title\">Carregando formul\u00E1rio...</p>\n <p class=\"form-loading-subtitle\">Preparando campos e op\u00E7\u00F5es do cadastro.</p>\n </div>\n </div>\n <div class=\"form-loading-skeleton\" aria-hidden=\"true\">\n <span class=\"form-loading-line form-loading-line-title\"></span>\n <span class=\"form-loading-line\"></span>\n <span class=\"form-loading-line form-loading-line-short\"></span>\n <span class=\"form-loading-field\"></span>\n <span class=\"form-loading-field form-loading-field-wide\"></span>\n </div>\n </div>\n} @else if (initializationStatus === 'error') {\n <!-- Error State -->\n <div class=\"form-error\">\n <mat-icon color=\"warn\" [praxisIcon]=\"'error'\"></mat-icon>\n <h3>{{ getErrorTitle() }}</h3>\n <p>{{ currentErrorMessage }}</p>\n @if (isRecoverable) {\n <button mat-stroked-button (click)=\"retryInitialization()\">\n <mat-icon [praxisIcon]=\"'refresh'\"></mat-icon>\n Tentar Novamente\n </button>\n }\n <button mat-button (click)=\"showDetailedError()\" class=\"show-details\">\n Ver Detalhes T\u00E9cnicos\n </button>\n <!-- Permitir corre\u00E7\u00E3o do resourcePath diretamente do estado de erro -->\n <button mat-flat-button color=\"primary\" (click)=\"openQuickConnect()\" class=\"connect-action\">\n <mat-icon [praxisIcon]=\"'bolt'\"></mat-icon>\n Conectar a recurso\n </button>\n </div>\n} @else if (initializationStatus === 'success') {\n <!-- Inline banner for schema change (only when customization is enabled) -->\n @if (shouldShowOutdatedInline()) {\n <div class=\"pfx-form-info-banner\" role=\"status\" aria-live=\"polite\">\n <div class=\"text\">O schema do servidor mudou. Reconciliar agora?</div>\n <div class=\"actions\">\n <button mat-stroked-button color=\"primary\" (click)=\"openConfigEditor()\">\n <mat-icon [praxisIcon]=\"'sync'\"></mat-icon>\n Reconciliar\n </button>\n <button mat-button (click)=\"onSnoozeOutdated()\">Lembrar depois</button>\n <button mat-button (click)=\"onIgnoreOutdated()\">Ignorar</button>\n </div>\n </div>\n }\n\n <!-- Configuration Controls -->\n @if (shouldShowConfigControls && enableCustomization) {\n <div class=\"form-config-controls\">\n @if (showAiAssistant) {\n <button type=\"button\" praxisIconButton=\"auto_awesome\" size=\"dense\" (click)=\"openAiAssistant()\" [disabled]=\"isLoading\"\n [attr.data-testid]=\"aiAssistantTriggerTestId('config-controls')\"\n aria-label=\"Abrir copiloto semantico Praxis do formulario\"\n matTooltip=\"Abrir copiloto sem\u00E2ntico do formul\u00E1rio\">\n </button>\n }\n <button type=\"button\" praxisIconButton=\"settings\" size=\"dense\" (click)=\"openConfigEditor()\" [disabled]=\"isLoading\" class=\"config-button\"\n [matBadge]=\"schemaOutdated ? '!' : ''\" [matBadgeHidden]=\"!schemaOutdated\" matBadgeColor=\"warn\" matBadgeSize=\"small\"\n matBadgePosition=\"above after\"\n [attr.aria-label]=\"configControlLabel\" [matTooltip]=\"configControlLabel\">\n </button>\n <button type=\"button\" praxisIconButton=\"link_off\" size=\"dense\" (click)=\"disconnect()\"\n [attr.aria-label]=\"disconnectControlLabel\" [matTooltip]=\"disconnectControlLabel\"\n [disabled]=\"isLoading\">\n </button>\n </div>\n }\n\n <!-- Form Content -->\n @if (!resourcePath && !hasExplicitSchemaUrl() && !hasRenderableConfig()) {\n <praxis-empty-state-card icon=\"link\" [title]=\"'Conecte o formul\u00E1rio \u00E0 fonte de dados'\"\n [description]=\"'Informe a rota do recurso da API para gerar automaticamente os campos do formul\u00E1rio.'\"\n [primaryAction]=\"{ label: 'Conectar \u00E0 fonte de dados', icon: 'bolt', action: openQuickConnect.bind(this) }\"></praxis-empty-state-card>\n }\n @if (shouldShowContextEmptyState()) {\n <div class=\"form-context-empty-state\" role=\"status\" aria-live=\"polite\">\n <praxis-empty-state-card\n [icon]=\"emptyState?.icon || 'touch_app'\"\n [title]=\"emptyState!.title\"\n [description]=\"emptyState?.description\"\n [tone]=\"emptyState?.tone || 'primary'\"\n [variant]=\"emptyState?.variant || 'transparent'\"\n [alignment]=\"emptyState?.alignment || 'center'\"\n [density]=\"emptyState?.density || 'compact'\"\n [iconContainer]=\"emptyState?.iconContainer || 'circle'\"\n [inline]=\"true\"\n />\n </div>\n } @else {\n <div #entityReadRegion class=\"entity-read-region\" tabindex=\"-1\" role=\"region\" [attr.aria-label]=\"entityReadText('region')\">\n <span class=\"cdk-visually-hidden\" role=\"status\" aria-live=\"polite\" aria-atomic=\"true\">{{ entityReadStatusText() }}</span>\n @if (entityHydrationPending || entityReadFailed) {\n <div class=\"entity-read-feedback\" data-testid=\"form-entity-read-feedback\">\n @if (entityHydrationPending) {\n <mat-progress-spinner diameter=\"28\" mode=\"indeterminate\" aria-hidden=\"true\"></mat-progress-spinner>\n <p aria-hidden=\"true\">{{ entityReadText('loading') }}</p>\n } @else {\n <mat-icon [praxisIcon]=\"'error_outline'\" aria-hidden=\"true\"></mat-icon>\n <p aria-hidden=\"true\">{{ entityReadText('error') }}</p>\n <button mat-stroked-button type=\"button\" (click)=\"retryEntityRead(entityReadRegion)\">{{ entityReadText('retry') }}</button>\n }\n </div>\n }\n <form #formHost (ngSubmit)=\"onSubmit()\" [attr.aria-busy]=\"submitting || entityHydrationPending ? 'true' : null\"\n [style.opacity]=\"entityHydrationPending || entityReadFailed ? '0' : null\"\n [style.transition]=\"entityHydrationPending || entityReadFailed ? 'none' : null\"\n [attr.inert]=\"entityHydrationPending || entityReadFailed ? '' : null\"\n [attr.aria-hidden]=\"entityHydrationPending || entityReadFailed ? 'true' : null\"\n [attr.aria-label]=\"'Formul\u00E1rio ' + (config.metadata?.version || '')\" [class.canvas-mode-enabled]=\"enableCustomization\"\n [class.presentation-mode]=\"effectivePresentation\"\n [class.praxis-dynamic-form--presentation]=\"effectivePresentation\"\n [class.readonly-mode]=\"effectiveReadonly\"\n [attr.data-presentation-preset]=\"effectivePresentation ? effectivePresentationPreset : null\"\n [class.praxis-dynamic-form--corporate-dossier]=\"isCorporateDossierPreset()\"\n [class.praxis-dynamic-form--editorial-card]=\"isEditorialCardPreset()\"\n [class.praxis-dynamic-form--compact-presentation]=\"isCompactPresentationPreset()\"\n [class.editorial-visual-context]=\"hasEditorialVisualContext()\"\n [class.pfx-mounting]=\"isMounting\" [formGroup]=\"form\"\n [ngClass]=\"{\n 'pres-compact': presentationVars.compact,\n 'pres-label-left': presentationVars.labelPosition === 'left',\n 'pres-label-above': presentationVars.labelPosition === 'above'\n }\" [style.--pfx-pres-label-align]=\"presentationVars.labelAlign\"\n [style.--pfx-pres-label-size]=\"presentationVars.labelSize\"\n [style.--pfx-pres-label-width]=\"presentationVars.labelWidth\"\n [style.--pfx-pres-row-gap]=\"presentationVars.density === 'compact' ? '6px' : (presentationVars.density === 'cozy' ? '8px' : '10px')\"\n [style.--pfx-pres-row-padding]=\"presentationVars.density === 'compact' ? '2px 0' : (presentationVars.density === 'cozy' ? '6px 0' : '8px 0')\"\n [style.--pfx-pres-value-align]=\"presentationVars.valueAlign\"\n [style.--pfx-pres-value-size]=\"presentationVars.valueSize\"\n [style.--pdx-form-mount-duration]=\"getMountDurationVar()\"\n [style.--pdx-form-mount-offset]=\"getMountOffsetVar()\"\n [style.--pdx-form-mount-stagger]=\"getMountStaggerVar()\"\n class=\"praxis-dynamic-form\">\n @if (enableCustomization && selectedElement) {\n <praxis-canvas-toolbar (editMetadata)=\"openSelectedElementEditor()\" (selectPath)=\"onSelectPath($event)\"\n (moveUp)=\"onToolbarMove('up')\" (moveDown)=\"onToolbarMove('down')\" (toggleReadonly)=\"onToolbarToggleReadonly()\"\n (toggleRequired)=\"onToolbarToggleRequired()\" (toggleHidden)=\"onToolbarToggleHidden()\"\n (toggleDisabled)=\"onToolbarToggleDisabled()\" (requestClose)=\"onToolbarRequestClose()\"\n [selectedElement]=\"selectedElement\"\n [style.transform]=\"toolbarTransform\"></praxis-canvas-toolbar>\n }\n\n @if (formBlocksBefore?.nodes?.length) {\n <section class=\"form-editorial-blocks form-editorial-blocks-before\" data-editorial-placement=\"before\">\n <praxis-rich-content\n [document]=\"formBlocksBeforeDocument\"\n [context]=\"getEditorialRichContentContext()\"\n [hostCapabilities]=\"richContentHostCapabilities\"\n ></praxis-rich-content>\n </section>\n }\n\n @if (actionPlacement === 'top' && !(effectivePresentation || effectiveReadonly)) {\n <praxis-form-actions data-actions-placement=\"top\" [actions]=\"effectiveActions\" [isSubmitting]=\"submitting\"\n [formIsValid]=\"effectiveFormIsValid\" [submitError]=\"submitError\" [formId]=\"formId\" [actionOverrides]=\"actionRuleProps\"\n [invalidRequiredFieldLabels]=\"invalidRequiredFieldLabels\"\n [suppressInvalidSubmitHint]=\"entityHydrationPending\"\n [editorialVisualContext]=\"hasEditorialVisualContext()\"\n (action)=\"onFormAction($event)\"></praxis-form-actions>\n }\n\n <!-- Tab Layout Navigation Bar -->\n @if (effectiveLayoutMode === 'tabs' && effectiveTabs.length > 1) {\n <nav class=\"prx-form-tabs\" [attr.data-appearance]=\"effectiveTabsAppearance\" role=\"tablist\" aria-label=\"Navega\u00E7\u00E3o em abas do formul\u00E1rio\">\n <div class=\"prx-form-tabs__tablist prx-form-tabs__tablist--scrollable\">\n @for (tab of effectiveTabs; track tab.id) {\n <button\n type=\"button\"\n role=\"tab\"\n class=\"prx-form-tabs__tab\"\n [class.prx-form-tabs__tab--active]=\"activeTabId === tab.id\"\n [attr.aria-selected]=\"activeTabId === tab.id\"\n [attr.aria-controls]=\"getTabAriaControls(tab)\"\n [attr.id]=\"'tab-' + tab.id\"\n [disabled]=\"tab.disabled\"\n [matTooltip]=\"tab.tooltip || null\"\n [matTooltipDisabled]=\"!tab.tooltip\"\n (click)=\"selectTab(tab.id)\"\n >\n @if (tab.icon) {\n <mat-icon class=\"prx-form-tabs__tab-icon\" [praxisIcon]=\"tab.icon\" aria-hidden=\"true\"></mat-icon>\n }\n <span class=\"prx-form-tabs__tab-label\">{{ tab.label }}</span>\n @if (tab.badge != null) {\n <span class=\"prx-form-tabs__tab-badge\">{{ tab.badge }}</span>\n }\n @if (getTabErrorCount(tab) > 0) {\n <span class=\"prx-form-tabs__tab-error-badge\" [attr.aria-label]=\"getTabErrorCount(tab) + ' erros na aba'\">\n {{ getTabErrorCount(tab) }}\n </span>\n }\n </button>\n }\n </div>\n </nav>\n }\n\n @for (section of (config.sections || []); track (section.id ?? $index); let sectionIndex = $index) {\n <div class=\"section-drop-wrapper\" [attr.data-section-id]=\"section.id\" [hidden]=\"!isSectionInActiveTab(section)\"\n [attr.role]=\"effectiveLayoutMode === 'tabs' ? 'tabpanel' : null\"\n [attr.id]=\"effectiveLayoutMode === 'tabs' ? ('section-tabpanel-' + section.id) : null\"\n [attr.aria-labelledby]=\"effectiveLayoutMode === 'tabs' ? ('tab-' + (getTabIdForSection(section) || section.id)) : null\">\n @if (isSectionVisible(section)) {\n <div #sectionEl class=\"form-section canvas-element\" data-canvas-type=\"section\" [attr.data-section-id]=\"section.id\"\n [attr.data-section-index]=\"sectionIndex\" (mouseenter)=\"onElementMouseEnter($event, 'section', section, sectionEl)\"\n (mouseleave)=\"onElementMouseLeave($event)\" (click)=\"onElementClick($event, 'section', section, sectionEl)\"\n [class.selected]=\"selectedElement?.domElement === sectionEl\"\n [class.hovered]=\"hoveredElement?.domElement === sectionEl && selectedElement?.domElement !== sectionEl\"\n [attr.data-section-appearance]=\"getSectionAppearance(section) || null\"\n [attr.data-section-divider]=\"isSectionDividerEnabled(section) ? 'true' : null\"\n [attr.data-presentation-preset]=\"effectivePresentation ? getSectionPresentationPreset(section) : null\"\n [class.form-section--corporate-dossier]=\"isSectionCorporateDossier(section)\"\n [class.form-section--editorial-card]=\"isSectionEditorialCard(section)\"\n [class.form-section--compact-presentation]=\"isSectionCompactPresentation(section)\"\n [style.marginBottom.px]=\"!isLastVisibleSection(section) ? getSectionGapBottom(section) : null\" [ngClass]=\"getSectionClasses(section)\"\n [ngStyle]=\"getSectionStyles(section)\">\n @if (!shouldHideSectionHeader(section)) {\n <div\n class=\"section-heading\"\n [class.align-center]=\"getSectionHeaderAlign(section) === 'center'\"\n [class.step-appearance]=\"getSectionAppearance(section) === 'step'\"\n [class.title-only]=\"isSectionHeaderTitleOnly(section)\"\n >\n <div class=\"section-heading-text\" [matTooltip]=\"getSectionHeaderTooltip(section) || null\"\n [matTooltipDisabled]=\"!getSectionHeaderTooltip(section)\">\n @if (getSectionStepLabel(section)) {\n <div class=\"section-step-label\" [class.align-center]=\"getSectionHeaderAlign(section) === 'center'\">\n {{ getSectionStepLabel(section) }}\n </div>\n }\n @if (getSectionTitle(section)) {\n <h3 class=\"section-title\" [class.title-large]=\"getSectionTitleStyle(section) === 'titleLarge'\"\n [class.title-medium]=\"getSectionTitleStyle(section) === 'titleMedium'\"\n [class.title-small]=\"getSectionTitleStyle(section) === 'titleSmall'\"\n [class.headline-small]=\"getSectionTitleStyle(section) === 'headlineSmall'\"\n [style.marginBottom.px]=\"getEffectiveSectionTitleGapBottom(section)\" [style.color]=\"getSectionTitleColor(section) || null\"\n [class.align-center]=\"getSectionHeaderAlign(section) === 'center'\"\n [attr.id]=\"sectionPanelId(section, sectionIndex) + '-title'\">\n @let sectionHeaderVisual = getSectionHeaderVisual(section);\n @let sectionHeaderAvatarSize = getSectionHeaderAvatarSize(section);\n @if (sectionHeaderVisual.kind === 'icon') {\n <mat-icon class=\"section-title-icon\" aria-hidden=\"true\" [praxisIcon]=\"sectionHeaderVisual.icon\"></mat-icon>\n }\n @if (sectionHeaderVisual.kind === 'image') {\n <img class=\"section-title-avatar section-title-avatar-image\" [class.size-sm]=\"sectionHeaderAvatarSize === 'sm'\"\n [class.size-md]=\"sectionHeaderAvatarSize === 'md'\" [class.size-lg]=\"sectionHeaderAvatarSize === 'lg'\"\n [src]=\"sectionHeaderVisual.src\" [alt]=\"sectionHeaderVisual.alt\" />\n }\n @if (sectionHeaderVisual.kind === 'initials') {\n <span class=\"section-title-avatar section-title-avatar-text\" [class.size-sm]=\"sectionHeaderAvatarSize === 'sm'\"\n [class.size-md]=\"sectionHeaderAvatarSize === 'md'\" [class.size-lg]=\"sectionHeaderAvatarSize === 'lg'\" aria-hidden=\"true\">\n {{ sectionHeaderVisual.text }}\n </span>\n @if (sectionHeaderVisual.ariaLabel) {\n <span class=\"section-title-avatar-sr-only\">{{ sectionHeaderVisual.ariaLabel }}</span>\n }\n }\n @if (sectionHeaderVisual.kind === 'placeholder') {\n <span class=\"section-title-avatar section-title-avatar-placeholder\" [class.size-sm]=\"sectionHeaderAvatarSize === 'sm'\"\n [class.size-md]=\"sectionHeaderAvatarSize === 'md'\" [class.size-lg]=\"sectionHeaderAvatarSize === 'lg'\" aria-hidden=\"true\">\n @if (sectionHeaderVisual.icon) {\n <mat-icon aria-hidden=\"true\" [praxisIcon]=\"sectionHeaderVisual.icon\"></mat-icon>\n }\n @if (sectionHeaderVisual.text) {\n <span>{{ sectionHeaderVisual.text }}</span>\n }\n </span>\n @if (sectionHeaderVisual.ariaLabel) {\n <span class=\"section-title-avatar-sr-only\">{{ sectionHeaderVisual.ariaLabel }}</span>\n }\n }\n {{ getSectionTitle(section) }}\n @if (enableCustomization) {\n <button type=\"button\" class=\"inline-edit-btn\" praxisIconButton=\"edit\" size=\"dense\" (click)=\"openSectionEditor(section, 'title')\"\n aria-label=\"Editar t\u00EDtulo da se\u00E7\u00E3o\" matTooltip=\"Editar t\u00EDtulo\">\n </button>\n }\n </h3>\n }\n @if (getSectionDescription(section)) {\n <p class=\"section-description\" [class.body-large]=\"getSectionDescriptionStyle(section) === 'bodyLarge'\"\n [class.body-medium]=\"getSectionDescriptionStyle(section) === 'bodyMedium'\"\n [class.body-small]=\"getSectionDescriptionStyle(section) === 'bodySmall'\"\n [style.marginBottom.px]=\"getSectionDescriptionGapBottom(section) ?? 8\" [style.color]=\"getSectionDescriptionColor(section) || null\"\n [class.align-center]=\"getSectionHeaderAlign(section) === 'center'\">\n {{ getSectionDescription(section) }}\n @if (enableCustomization) {\n <button type=\"button\" class=\"inline-edit-btn\" praxisIconButton=\"edit\" size=\"dense\"\n (click)=\"openSectionEditor(section, 'description')\" aria-label=\"Editar descri\u00E7\u00E3o da se\u00E7\u00E3o\"\n matTooltip=\"Editar descri\u00E7\u00E3o\">\n </button>\n }\n </p>\n }\n </div>\n @if (getSectionHeaderActions(section).length) {\n <div class=\"section-heading-actions\" [class.align-center]=\"getSectionHeaderAlign(section) === 'center'\">\n @for (action of getSectionHeaderActions(section); track action.id) {\n <button\n type=\"button\"\n class=\"section-heading-action-btn\"\n [praxisIconButton]=\"action.icon\"\n size=\"compact\"\n [busy]=\"action.loading\"\n [disabled]=\"isSectionHeaderActionDisabled(action)\"\n [matTooltip]=\"getSectionHeaderActionTooltip(action)\"\n [attr.aria-label]=\"action.label\"\n [attr.aria-busy]=\"action.loading ? 'true' : null\"\n [ngClass]=\"getSectionHeaderActionNgClass(action)\"\n [ngStyle]=\"getSectionHeaderActionStyles(action)\"\n (click)=\"onSectionHeaderActionClick(section, action, $event)\"\n >\n @if (action.loading) {\n <span class=\"section-heading-action-sr-only\">{{ getSectionHeaderActionLoadingLabel(action) }}</span>\n }\n </button>\n }\n </div>\n }\n @if (isSectionCollapsible(section)) {\n <button type=\"button\" class=\"section-collapse-btn\" [praxisIconButton]=\"isSectionCollapsed(section) ? 'expand_more' : 'expand_less'\" size=\"compact\"\n (click)=\"toggleSectionCollapse($event, section)\" [attr.aria-expanded]=\"!isSectionCollapsed(section)\"\n [attr.aria-controls]=\"sectionPanelId(section, sectionIndex)\"\n [attr.aria-label]=\"isSectionCollapsed(section) ? 'Expandir se\u00E7\u00E3o' : 'Recolher se\u00E7\u00E3o'\">\n </button>\n }\n </div>\n }\n\n <div class=\"section-body\" [class.collapsed]=\"isSectionCollapsed(section)\"\n [attr.id]=\"sectionPanelId(section, sectionIndex)\"\n [attr.role]=\"getSectionTitle(section) ? 'region' : null\"\n [attr.aria-labelledby]=\"getSectionTitle(section) ? sectionPanelId(section, sectionIndex) + '-title' : null\">\n @if (!isSectionCollapsed(section)) {\n @for (row of section.rows; track (row.id ?? $index); let rowIndex = $index) {\n @if (isRowVisible(row)) {\n <div class=\"row-drop-wrapper\" [attr.data-section-id]=\"section.id\">\n <div #rowEl class=\"form-row grid-12 canvas-element\" data-canvas-type=\"row\" [attr.data-row-index]=\"rowIndex\"\n [attr.data-section-id]=\"section.id\" [attr.data-row-id]=\"row.id\" [style.--pfx-grid-gap.px]=\"getRowGap(row)\"\n [style.--pfx-field-gap.px]=\"getRowRowGap(row)\"\n [style.--pfx-mount-index]=\"rowIndex\"\n [style.marginBottom.px]=\"rowIndex < section.rows.length - 1 ? (getRowRowGap(row) ?? null) : null\"\n [ngClass]=\"getRowClasses(row)\" [ngStyle]=\"getRowStyles(row)\"\n (mouseenter)=\"onElementMouseEnter($event, 'row', row, rowEl)\" (mouseleave)=\"onElementMouseLeave($event)\"\n (click)=\"onElementClick($event, 'row', row, rowEl)\" [class.selected]=\"selectedElement?.domElement === rowEl\"\n [class.hovered]=\"hoveredElement?.domElement === rowEl && selectedElement?.domElement !== rowEl\">\n @for (column of row.columns; track (column.id ?? $index); let colIndex = $index) {\n @if (isColumnVisible(column)) {\n <div class=\"column-drop-wrapper\" [attr.data-section-id]=\"section.id\" [attr.data-row-id]=\"row.id\">\n <div #colEl class=\"form-column canvas-element\" [ngClass]=\"getColumnClasses(column, row)\"\n [style.padding.px]=\"getColumnPadding(column)\" [style.--pfx-field-gap.px]=\"getRowRowGap(row)\"\n [ngStyle]=\"getColumnStyles(column)\" [attr.data-testid]=\"column.testId || null\"\n [attr.data-row-gap]=\"getRowRowGap(row)\" data-canvas-type=\"column\" [attr.data-column-index]=\"colIndex\"\n [attr.data-row-index]=\"rowIndex\" [attr.data-section-id]=\"section.id\" [attr.data-row-id]=\"row.id\"\n [attr.data-column-id]=\"column.id\" (mouseenter)=\"onElementMouseEnter($event, 'column', column, colEl)\"\n (mouseleave)=\"onElementMouseLeave($event)\" (click)=\"onElementClick($event, 'column', column, colEl)\"\n [class.selected]=\"selectedElement?.domElement === colEl\"\n [class.hovered]=\"hoveredElement?.domElement === colEl && selectedElement?.domElement !== colEl\">\n @for (renderItem of getColumnRenderItems(column); track renderItem.id) {\n @if (renderItem.kind === 'fields') {\n <ng-container dynamicFieldLoader [fields]=\"getRenderableFieldsForLoader(renderItem.fields)\" [formGroup]=\"form\"\n [enableExternalControlBinding]=\"true\"\n [readonlyMode]=\"effectiveReadonly\"\n [disabledMode]=\"effectiveDisabledMode\"\n [presentationMode]=\"presentationForLoader\" [visible]=\"visibleGlobal === null ? null : visibleGlobal\"\n [canvasMode]=\"enableCustomization\" (canvasMouseEnter)=\"onFieldMouseEnter($event)\"\n (canvasMouseLeave)=\"onFieldMouseLeave($event)\" (canvasClick)=\"onFieldClick($event)\"\n (canvasFocus)=\"onFieldFocus($event)\"\n (renderError)=\"onFieldRenderError($event)\">\n </ng-container>\n } @else {\n <praxis-rich-content\n class=\"form-layout-rich-content\"\n [ngClass]=\"renderItem.className || null\"\n [ngStyle]=\"renderItem.style || null\"\n [document]=\"renderItem.document\"\n [layout]=\"renderItem.layout\"\n [rootClassName]=\"renderItem.rootClassName || ''\"\n [context]=\"getEditorialRichContentContext()\"\n [hostCapabilities]=\"richContentHostCapabilities\"\n ></praxis-rich-content>\n }\n }\n </div>\n </div>\n } }\n </div>\n </div>\n }\n }\n } @else {\n <div class=\"section-collapsed-placeholder\">\n <mat-icon aria-hidden=\"true\" [praxisIcon]=\"'unfold_more'\"></mat-icon>\n <span>{{ getSectionCollapsedSummary(section) }}</span>\n </div>\n }\n @if (isLastVisibleSection(section) && beforeActionsPlacement === 'insideLastSection' && formBlocksBeforeActions?.nodes?.length) {\n <section class=\"form-editorial-blocks form-editorial-blocks-before-actions\" data-editorial-placement=\"beforeActions\">\n <praxis-rich-content\n [document]=\"formBlocksBeforeActionsDocument\"\n [context]=\"getEditorialRichContentContext()\"\n [hostCapabilities]=\"richContentHostCapabilities\"\n ></praxis-rich-content>\n </section>\n }\n @if (actionPlacement === 'insideLastSection' && isLastVisibleSection(section) && !(effectivePresentation\n || effectiveReadonly)) {\n <praxis-form-actions data-actions-placement=\"insideLastSection\" [actions]=\"effectiveActions\"\n [isSubmitting]=\"submitting\" [formIsValid]=\"effectiveFormIsValid\" [submitError]=\"submitError\" [formId]=\"formId\"\n [actionOverrides]=\"actionRuleProps\" [invalidRequiredFieldLabels]=\"invalidRequiredFieldLabels\"\n [suppressInvalidSubmitHint]=\"entityHydrationPending\"\n [editorialVisualContext]=\"hasEditorialVisualContext()\"\n (action)=\"onFormAction($event)\"></praxis-form-actions>\n }\n </div>\n <!-- Overlay de bloqueio durante submiss\u00E3o -->\n @if (submitting) {\n <div class=\"form-blocking-overlay\" aria-live=\"polite\">\n <mat-progress-spinner\n diameter=\"40\"\n color=\"primary\"\n [attr.aria-label]=\"config.messages?.loading?.submit || 'Salvando formul\u00E1rio'\"\n ></mat-progress-spinner>\n <p>{{ config.messages?.loading?.submit || 'Salvando...' }}</p>\n </div>\n }\n </div>\n\n @if (enableCustomization && selectedElement?.domElement === sectionEl) {\n <div class=\"add-section-container\">\n <div class=\"add-section-line\"></div>\n <button mat-fab color=\"primary\" aria-label=\"Adicionar nova se\u00E7\u00E3o\" (click)=\"addNewSectionAfter(sectionIndex)\"\n matTooltip=\"Adicionar nova se\u00E7\u00E3o aqui\">\n <mat-icon [praxisIcon]=\"'add'\"></mat-icon>\n </button>\n <div class=\"add-section-line\"></div>\n </div>\n }\n }\n </div>\n }\n\n @if (beforeActionsPlacement !== 'insideLastSection' && formBlocksBeforeActions?.nodes?.length) {\n <section class=\"form-editorial-blocks form-editorial-blocks-before-actions\" data-editorial-placement=\"beforeActions\">\n <praxis-rich-content\n [document]=\"formBlocksBeforeActionsDocument\"\n [context]=\"getEditorialRichContentContext()\"\n [hostCapabilities]=\"richContentHostCapabilities\"\n ></praxis-rich-content>\n </section>\n }\n\n @if (actionPlacement === 'afterSections' && !(effectivePresentation || effectiveReadonly)) {\n <praxis-form-actions data-actions-placement=\"afterSections\" [actions]=\"effectiveActions\" [isSubmitting]=\"submitting\"\n [formIsValid]=\"effectiveFormIsValid\" [submitError]=\"submitError\" [formId]=\"formId\"\n [actionOverrides]=\"actionRuleProps\" [invalidRequiredFieldLabels]=\"invalidRequiredFieldLabels\"\n [suppressInvalidSubmitHint]=\"entityHydrationPending\"\n [editorialVisualContext]=\"hasEditorialVisualContext()\"\n (action)=\"onFormAction($event)\"></praxis-form-actions>\n }\n\n @if (formBlocksAfter?.nodes?.length) {\n <section class=\"form-editorial-blocks form-editorial-blocks-after\" data-editorial-placement=\"after\">\n <praxis-rich-content\n [document]=\"formBlocksAfterDocument\"\n [context]=\"getEditorialRichContentContext()\"\n [hostCapabilities]=\"richContentHostCapabilities\"\n ></praxis-rich-content>\n </section>\n }\n </form>\n </div>\n }\n @if (showAiAssistant && !enableCustomization && (mode === 'view' || mode === 'presentation' || mode === 'dossier') && !shouldShowContextEmptyState()) {\n <div class=\"ai-floating-assistant\">\n <button type=\"button\" praxisIconButton=\"auto_awesome\" size=\"compact\" (click)=\"openAiAssistant()\" [disabled]=\"isLoading || entityHydrationPending || entityReadFailed\"\n [attr.data-testid]=\"aiAssistantTriggerTestId('view-floating')\"\n aria-label=\"Abrir copiloto semantico Praxis do formulario\"\n matTooltip=\"Pedir ajuda sobre este formul\u00E1rio\">\n </button>\n </div>\n }\n @if (showAiAssistant && aiAssistantOpen && aiAssistantViewState) {\n <praxis-ai-assistant-shell\n [labels]=\"aiAssistantLabels\"\n [mode]=\"aiAssistantViewState.mode\"\n [state]=\"aiAssistantViewState.state\"\n [contextItems]=\"aiAssistantViewState.contextItems\"\n [attachments]=\"aiAssistantViewState.attachments\"\n [messages]=\"aiAssistantViewState.messages\"\n [quickReplies]=\"aiAssistantViewState.quickReplies\"\n [prompt]=\"aiAssistantPrompt\"\n [statusText]=\"aiAssistantViewState.statusText\"\n [errorText]=\"aiAssistantViewState.errorText\"\n [busy]=\"aiAssistantViewState.state === 'processing' || aiAssistantViewState.state === 'applying'\"\n [canApply]=\"aiAssistantViewState.canApply\"\n [layout]=\"aiAssistantLayout\"\n testIdPrefix=\"dynamic-form-ai-assistant\"\n panelTestId=\"dynamic-form-ai-assistant-panel\"\n submitTestId=\"dynamic-form-ai-assistant-submit\"\n applyTestId=\"dynamic-form-ai-assistant-apply\"\n (promptChange)=\"onAiAssistantPromptChange($event)\"\n (submitPrompt)=\"onAiAssistantSubmit($event)\"\n (apply)=\"onAiAssistantApply()\"\n (retryTurn)=\"onAiAssistantRetry()\"\n (cancelTurn)=\"onAiAssistantCancel()\"\n (quickReply)=\"onAiAssistantQuickReply($event)\"\n (editMessage)=\"onAiAssistantEditMessage($event)\"\n (resendMessage)=\"onAiAssistantResendMessage($event)\"\n (layoutChange)=\"onAiAssistantLayoutChange($event)\"\n (close)=\"closeAiAssistant()\"\n ></praxis-ai-assistant-shell>\n }\n }\n", styles: ["@charset \"UTF-8\";.span-xs-1{grid-column:span 1}.span-xs-2{grid-column:span 2}.span-xs-3{grid-column:span 3}.span-xs-4{grid-column:span 4}.span-xs-5{grid-column:span 5}.span-xs-6{grid-column:span 6}.span-xs-7{grid-column:span 7}.span-xs-8{grid-column:span 8}.span-xs-9{grid-column:span 9}.span-xs-10{grid-column:span 10}.span-xs-11{grid-column:span 11}.span-xs-12{grid-column:span 12}.offset-xs-0{margin-left:0%}.offset-xs-1{margin-left:calc(1 / 12 * 100%)}.offset-xs-2{margin-left:calc(2 / 12 * 100%)}.offset-xs-3{margin-left:25%}.offset-xs-4{margin-left:calc(4 / 12 * 100%)}.offset-xs-5{margin-left:calc(5 / 12 * 100%)}.offset-xs-6{margin-left:50%}.offset-xs-7{margin-left:calc(7 / 12 * 100%)}.offset-xs-8{margin-left:calc(8 / 12 * 100%)}.offset-xs-9{margin-left:75%}.offset-xs-10{margin-left:calc(10 / 12 * 100%)}.offset-xs-11{margin-left:calc(11 / 12 * 100%)}.order-xs--12{order:-12}.order-xs--11{order:-11}.order-xs--10{order:-10}.order-xs--9{order:-9}.order-xs--8{order:-8}.order-xs--7{order:-7}.order-xs--6{order:-6}.order-xs--5{order:-5}.order-xs--4{order:-4}.order-xs--3{order:-3}.order-xs--2{order:-2}.order-xs--1{order:-1}.order-xs-0{order:0}.order-xs-1{order:1}.order-xs-2{order:2}.order-xs-3{order:3}.order-xs-4{order:4}.order-xs-5{order:5}.order-xs-6{order:6}.order-xs-7{order:7}.order-xs-8{order:8}.order-xs-9{order:9}.order-xs-10{order:10}.order-xs-11{order:11}.order-xs-12{order:12}.hidden-xs{display:none}@container praxis-form-row (min-width: 600px){.span-sm-1{grid-column:span 1}.span-sm-2{grid-column:span 2}.span-sm-3{grid-column:span 3}.span-sm-4{grid-column:span 4}.span-sm-5{grid-column:span 5}.span-sm-6{grid-column:span 6}.span-sm-7{grid-column:span 7}.span-sm-8{grid-column:span 8}.span-sm-9{grid-column:span 9}.span-sm-10{grid-column:span 10}.span-sm-11{grid-column:span 11}.span-sm-12{grid-column:span 12}.offset-sm-0{margin-left:0%}.offset-sm-1{margin-left:calc(1 / 12 * 100%)}.offset-sm-2{margin-left:calc(2 / 12 * 100%)}.offset-sm-3{margin-left:25%}.offset-sm-4{margin-left:calc(4 / 12 * 100%)}.offset-sm-5{margin-left:calc(5 / 12 * 100%)}.offset-sm-6{margin-left:50%}.offset-sm-7{margin-left:calc(7 / 12 * 100%)}.offset-sm-8{margin-left:calc(8 / 12 * 100%)}.offset-sm-9{margin-left:75%}.offset-sm-10{margin-left:calc(10 / 12 * 100%)}.offset-sm-11{margin-left:calc(11 / 12 * 100%)}.order-sm--12{order:-12}.order-sm--11{order:-11}.order-sm--10{order:-10}.order-sm--9{order:-9}.order-sm--8{order:-8}.order-sm--7{order:-7}.order-sm--6{order:-6}.order-sm--5{order:-5}.order-sm--4{order:-4}.order-sm--3{order:-3}.order-sm--2{order:-2}.order-sm--1{order:-1}.order-sm-0{order:0}.order-sm-1{order:1}.order-sm-2{order:2}.order-sm-3{order:3}.order-sm-4{order:4}.order-sm-5{order:5}.order-sm-6{order:6}.order-sm-7{order:7}.order-sm-8{order:8}.order-sm-9{order:9}.order-sm-10{order:10}.order-sm-11{order:11}.order-sm-12{order:12}.hidden-sm{display:none}}@container praxis-form-row (min-width: 900px){.span-md-1{grid-column:span 1}.span-md-2{grid-column:span 2}.span-md-3{grid-column:span 3}.span-md-4{grid-column:span 4}.span-md-5{grid-column:span 5}.span-md-6{grid-column:span 6}.span-md-7{grid-column:span 7}.span-md-8{grid-column:span 8}.span-md-9{grid-column:span 9}.span-md-10{grid-column:span 10}.span-md-11{grid-column:span 11}.span-md-12{grid-column:span 12}.offset-md-0{margin-left:0%}.offset-md-1{margin-left:calc(1 / 12 * 100%)}.offset-md-2{margin-left:calc(2 / 12 * 100%)}.offset-md-3{margin-left:25%}.offset-md-4{margin-left:calc(4 / 12 * 100%)}.offset-md-5{margin-left:calc(5 / 12 * 100%)}.offset-md-6{margin-left:50%}.offset-md-7{margin-left:calc(7 / 12 * 100%)}.offset-md-8{margin-left:calc(8 / 12 * 100%)}.offset-md-9{margin-left:75%}.offset-md-10{margin-left:calc(10 / 12 * 100%)}.offset-md-11{margin-left:calc(11 / 12 * 100%)}.order-md--12{order:-12}.order-md--11{order:-11}.order-md--10{order:-10}.order-md--9{order:-9}.order-md--8{order:-8}.order-md--7{order:-7}.order-md--6{order:-6}.order-md--5{order:-5}.order-md--4{order:-4}.order-md--3{order:-3}.order-md--2{order:-2}.order-md--1{order:-1}.order-md-0{order:0}.order-md-1{order:1}.order-md-2{order:2}.order-md-3{order:3}.order-md-4{order:4}.order-md-5{order:5}.order-md-6{order:6}.order-md-7{order:7}.order-md-8{order:8}.order-md-9{order:9}.order-md-10{order:10}.order-md-11{order:11}.order-md-12{order:12}.hidden-md{display:none}}@container praxis-form-row (min-width: 1200px){.span-lg-1{grid-column:span 1}.span-lg-2{grid-column:span 2}.span-lg-3{grid-column:span 3}.span-lg-4{grid-column:span 4}.span-lg-5{grid-column:span 5}.span-lg-6{grid-column:span 6}.span-lg-7{grid-column:span 7}.span-lg-8{grid-column:span 8}.span-lg-9{grid-column:span 9}.span-lg-10{grid-column:span 10}.span-lg-11{grid-column:span 11}.span-lg-12{grid-column:span 12}.offset-lg-0{margin-left:0%}.offset-lg-1{margin-left:calc(1 / 12 * 100%)}.offset-lg-2{margin-left:calc(2 / 12 * 100%)}.offset-lg-3{margin-left:25%}.offset-lg-4{margin-left:calc(4 / 12 * 100%)}.offset-lg-5{margin-left:calc(5 / 12 * 100%)}.offset-lg-6{margin-left:50%}.offset-lg-7{margin-left:calc(7 / 12 * 100%)}.offset-lg-8{margin-left:calc(8 / 12 * 100%)}.offset-lg-9{margin-left:75%}.offset-lg-10{margin-left:calc(10 / 12 * 100%)}.offset-lg-11{margin-left:calc(11 / 12 * 100%)}.order-lg--12{order:-12}.order-lg--11{order:-11}.order-lg--10{order:-10}.order-lg--9{order:-9}.order-lg--8{order:-8}.order-lg--7{order:-7}.order-lg--6{order:-6}.order-lg--5{order:-5}.order-lg--4{order:-4}.order-lg--3{order:-3}.order-lg--2{order:-2}.order-lg--1{order:-1}.order-lg-0{order:0}.order-lg-1{order:1}.order-lg-2{order:2}.order-lg-3{order:3}.order-lg-4{order:4}.order-lg-5{order:5}.order-lg-6{order:6}.order-lg-7{order:7}.order-lg-8{order:8}.order-lg-9{order:9}.order-lg-10{order:10}.order-lg-11{order:11}.order-lg-12{order:12}.hidden-lg{display:none}}@container praxis-form-row (min-width: 1536px){.span-xl-1{grid-column:span 1}.span-xl-2{grid-column:span 2}.span-xl-3{grid-column:span 3}.span-xl-4{grid-column:span 4}.span-xl-5{grid-column:span 5}.span-xl-6{grid-column:span 6}.span-xl-7{grid-column:span 7}.span-xl-8{grid-column:span 8}.span-xl-9{grid-column:span 9}.span-xl-10{grid-column:span 10}.span-xl-11{grid-column:span 11}.span-xl-12{grid-column:span 12}.offset-xl-0{margin-left:0%}.offset-xl-1{margin-left:calc(1 / 12 * 100%)}.offset-xl-2{margin-left:calc(2 / 12 * 100%)}.offset-xl-3{margin-left:25%}.offset-xl-4{margin-left:calc(4 / 12 * 100%)}.offset-xl-5{margin-left:calc(5 / 12 * 100%)}.offset-xl-6{margin-left:50%}.offset-xl-7{margin-left:calc(7 / 12 * 100%)}.offset-xl-8{margin-left:calc(8 / 12 * 100%)}.offset-xl-9{margin-left:75%}.offset-xl-10{margin-left:calc(10 / 12 * 100%)}.offset-xl-11{margin-left:calc(11 / 12 * 100%)}.order-xl--12{order:-12}.order-xl--11{order:-11}.order-xl--10{order:-10}.order-xl--9{order:-9}.order-xl--8{order:-8}.order-xl--7{order:-7}.order-xl--6{order:-6}.order-xl--5{order:-5}.order-xl--4{order:-4}.order-xl--3{order:-3}.order-xl--2{order:-2}.order-xl--1{order:-1}.order-xl-0{order:0}.order-xl-1{order:1}.order-xl-2{order:2}.order-xl-3{order:3}.order-xl-4{order:4}.order-xl-5{order:5}.order-xl-6{order:6}.order-xl-7{order:7}.order-xl-8{order:8}.order-xl-9{order:9}.order-xl-10{order:10}.order-xl-11{order:11}.order-xl-12{order:12}.hidden-xl{display:none}}.canvas-mode-enabled{--canvas-hit: 14px}.canvas-mode-enabled .canvas-element{position:relative;z-index:0;border-radius:8px;outline:2px solid transparent;outline-offset:2px;transition:outline-color .2s ease,outline-style .2s ease}.canvas-mode-enabled .canvas-element:before{content:\"\";position:absolute;inset:calc(-1 * var(--canvas-hit));pointer-events:none;border-radius:inherit;background:transparent}.canvas-mode-enabled .canvas-element[data-canvas-type=section]{--outline-color: var(--md-sys-color-primary)}.canvas-mode-enabled .canvas-element[data-canvas-type=row]{--outline-color: var(--md-sys-color-secondary)}.canvas-mode-enabled .canvas-element[data-canvas-type=column],.canvas-mode-enabled .canvas-element[data-canvas-type=field]{--outline-color: var(--md-sys-color-tertiary)}.canvas-mode-enabled .canvas-element[data-canvas-type=actions]{--outline-color: var(--md-sys-color-primary)}.canvas-mode-enabled .canvas-element.hovered:not(.selected){outline-color:var(--outline-color, var(--md-sys-color-primary));outline-style:dashed}.canvas-mode-enabled .canvas-element.selected{outline-color:var(--outline-color, var(--md-sys-color-primary));outline-style:solid;box-shadow:0 0 0 2px var(--outline-color, var(--md-sys-color-primary))}.canvas-mode-enabled .canvas-element.hovered{z-index:var(--praxis-layer-authoring-hover, 300)}.canvas-mode-enabled .canvas-element.selected{z-index:var(--praxis-layer-authoring-selected, 320)}.section-drop-wrapper,.row-drop-wrapper,.column-drop-wrapper{display:contents}.add-section-container{display:flex;align-items:center;justify-content:center;padding:.5rem 0;margin:-.5rem 0;position:relative;z-index:var(--praxis-layer-authoring-insert, 280)}.add-section-container .add-section-line{flex-grow:1;height:1px;background:repeating-linear-gradient(90deg,var(--md-sys-color-outline-variant),var(--md-sys-color-outline-variant) 4px,transparent 4px,transparent 8px)}.add-section-container button{margin:0 1rem;transform:scale(.85)}:host{display:block;position:relative;--pfx-editorial-form-radius: var(--pfx-form-section-radius, 8px);--pfx-editorial-form-border: var( --pfx-form-stroke, var(--pdx-color-border-subtle, var(--md-sys-color-outline-variant)) );--pfx-editorial-form-surface: var( --pfx-form-section-surface, var(--pdx-color-surface, var(--md-sys-color-surface-container)) );--pfx-editorial-form-surface-muted: var( --pdx-color-surface-muted, var(--md-sys-color-surface-container-low) );--pfx-form-shell-surface: color-mix( in srgb, var(--pfx-editorial-form-surface) 36%, transparent );--pfx-form-section-divider: color-mix( in srgb, var(--pfx-editorial-form-border) 68%, transparent );--pfx-form-footer-surface: color-mix( in srgb, var(--pfx-editorial-form-surface) 70%, var(--pfx-editorial-form-surface-muted) 30% );--pfx-form-footer-border: color-mix( in srgb, var(--pfx-editorial-form-border) 76%, transparent );--pfx-form-shell-padding: clamp(.9rem, 1.4vw, 1.2rem)}.form-config-controls{position:relative;top:auto;margin:0;display:flex;align-items:center;gap:.35rem;z-index:60;background:color-mix(in srgb,var(--pfx-form-shell-surface) 88%,var(--md-sys-color-surface) 12%);padding:8px var(--pfx-form-shell-padding);border:1px solid var(--pfx-form-footer-border);border-bottom-color:color-mix(in srgb,var(--pfx-form-footer-border) 72%,transparent);border-radius:var(--pfx-editorial-form-radius) var(--pfx-editorial-form-radius) 0 0;-webkit-backdrop-filter:blur(12px);backdrop-filter:blur(12px);box-shadow:none;min-width:0;justify-content:flex-end;pointer-events:none;opacity:.96;transition:opacity .16s ease,border-color .16s ease}.form-config-controls>*{pointer-events:auto}.form-config-controls:hover,.form-config-controls:focus-within{opacity:1;border-color:color-mix(in srgb,var(--md-sys-color-primary) 26%,var(--md-sys-color-outline-variant) 74%)}.form-config-controls .praxis-icon-button{color:var(--md-sys-color-on-surface-variant)}.form-config-controls .praxis-icon-button:hover{color:var(--md-sys-color-primary)}.ai-floating-assistant{position:sticky;right:0;bottom:12px;margin-top:14px;margin-left:auto;width:fit-content;z-index:70;pointer-events:none}.ai-floating-assistant button{pointer-events:auto;display:inline-flex}.ai-floating-assistant .ai-trigger-btn{box-shadow:0 12px 28px #0f172a24}.config-button{color:var(--md-sys-color-primary)}.form-loading{display:flex;flex-direction:column;align-items:stretch;justify-content:center;padding:1.25rem;text-align:left;color:var(--md-sys-color-on-surface);gap:1rem;min-height:220px;border:1px solid color-mix(in srgb,var(--md-sys-color-primary) 14%,var(--md-sys-color-outline-variant) 86%);border-radius:8px;background:linear-gradient(135deg,color-mix(in srgb,var(--md-sys-color-primary) 8%,transparent),transparent 42%),color-mix(in srgb,var(--md-sys-color-surface-container-low) 78%,var(--md-sys-color-surface) 22%);box-shadow:0 12px 28px #0f172a14}.entity-read-region{position:relative;min-width:0}.entity-read-feedback{position:absolute;inset:0;display:flex;flex-direction:column;align-items:center;justify-content:flex-start;gap:1rem;padding:2rem 1rem;box-sizing:border-box;text-align:center;color:var(--md-sys-color-on-surface)}.entity-read-feedback p{margin:0;max-width:40ch}.form-loading-header{display:flex;align-items:center;gap:.85rem}.form-loading-copy{min-width:0}.form-loading p{margin:0}.form-loading-title{font-weight:700;color:var(--md-sys-color-on-surface)}.form-loading-subtitle{margin-top:.2rem;font-size:.875rem;color:var(--md-sys-color-on-surface-variant)}.form-loading-skeleton{display:grid;gap:.7rem}.form-loading-line,.form-loading-field{display:block;overflow:hidden;position:relative;border-radius:6px;background:color-mix(in srgb,var(--md-sys-color-surface-container-high) 74%,var(--md-sys-color-primary) 6%)}.form-loading-line:after,.form-loading-field:after{content:\"\";position:absolute;inset:0;transform:translate(-100%);background:linear-gradient(90deg,transparent,color-mix(in srgb,var(--md-sys-color-primary) 16%,var(--md-sys-color-on-surface) 18%),transparent);animation:form-loading-shimmer 1.4s ease-in-out infinite}.form-loading-line{height:12px}.form-loading-line-title{width:min(42%,240px)}.form-loading-line-short{width:min(64%,360px)}.form-loading-field{height:44px}.form-loading-field-wide{height:72px}@keyframes form-loading-shimmer{to{transform:translate(100%)}}@media(prefers-reduced-motion:reduce){.form-loading-line:after,.form-loading-field:after{animation:none;transform:none;opacity:.28}}.form-error{display:flex;flex-direction:column;align-items:center;justify-content:center;padding:3rem;text-align:center;color:var(--md-sys-color-error);gap:1rem;border:1px solid var(--md-sys-color-error);border-radius:8px;background-color:var(--md-sys-color-error-container);margin:1rem;box-shadow:0 12px 30px #7f1d1d1f}.form-error h3{margin:0;color:var(--md-sys-color-on-error-container)}.form-error p{margin:0;color:var(--md-sys-color-on-error-container);opacity:.8}.form-error button{margin-top:.5rem}.pfx-form-info-banner{margin-bottom:14px;padding:12px 14px;border-radius:16px;border:1px solid color-mix(in srgb,var(--md-sys-color-primary) 18%,var(--md-sys-color-outline-variant) 82%);background:color-mix(in srgb,var(--md-sys-color-primary-container) 24%,var(--md-sys-color-surface) 76%);color:var(--md-sys-color-on-surface);display:flex;align-items:flex-start;justify-content:space-between;gap:14px}.pfx-form-info-banner .text{font-size:.92rem;line-height:1.5;font-weight:600}.pfx-form-info-banner .actions{display:flex;flex-wrap:wrap;justify-content:flex-end;gap:8px}.praxis-dynamic-form{display:flex;flex-direction:column;max-width:100%;min-width:0;transition:all .3s ease;position:relative;font-family:inherit;font-size:inherit;color:inherit;--pfx-editorial-form-surface: var( --pfx-form-section-surface, var(--md-sys-color-surface-container) );--pfx-editorial-form-surface-muted: var( --pdx-color-surface-muted, var(--md-sys-color-surface-container-low) );--pfx-editorial-form-border: var( --pfx-form-stroke, var(--pdx-color-border-subtle, var(--md-sys-color-outline-variant)) );--pfx-editorial-form-text: var( --pdx-color-text-primary, var(--md-sys-color-on-surface) );--pfx-editorial-form-text-muted: var( --pdx-color-text-secondary, var(--md-sys-color-on-surface-variant) );--pfx-editorial-form-field-surface: color-mix( in srgb, var(--pfx-editorial-form-surface-muted) 76%, var(--pfx-editorial-form-surface) 24% );--pfx-editorial-form-field-outline: color-mix( in srgb, var(--pfx-editorial-form-border) 88%, transparent );--pfx-editorial-form-accent: var( --pdx-color-primary, var(--md-sys-color-primary) );--pfx-editorial-form-accent-text: var(--md-sys-color-on-primary);--pfx-editorial-form-radius: var(--pfx-form-section-radius, 8px);--pfx-editorial-form-field-radius: var(--pfx-form-field-radius, 4px);--pfx-editorial-form-border-width: 1px;--pfx-editorial-form-field-border-width: 1px;--pfx-editorial-form-shadow: none;--pfx-form-shell-surface: color-mix( in srgb, var(--pfx-editorial-form-surface) 36%, transparent );--pfx-form-section-surface-flat: color-mix( in srgb, var(--pfx-editorial-form-surface) 78%, var(--pfx-editorial-form-surface-muted) 22% );--pfx-form-section-divider: color-mix( in srgb, var(--pfx-editorial-form-border) 68%, transparent );--pfx-form-label-strong: color-mix( in srgb, var(--pfx-editorial-form-text) 96%, white 4% );--pfx-form-label-muted: color-mix( in srgb, var(--pfx-editorial-form-text-muted) 92%, var(--pfx-editorial-form-text) 8% );--pfx-form-field-surface-rest: color-mix( in srgb, var(--pfx-editorial-form-field-surface) 82%, var(--pfx-editorial-form-surface) 18% );--pfx-form-field-surface-focus: color-mix( in srgb, var(--pfx-editorial-form-accent) 4%, var(--pfx-form-field-surface-rest) 96% );--pfx-form-field-min-height: 48px;--pfx-form-section-padding: clamp(1.1rem, 1.8vw, 1.5rem);--pfx-form-section-gap: 22px;--pdx-presentation-label-size: var(--pfx-pres-compact-label-size, .78rem);--pdx-presentation-value-size: var(--pfx-pres-compact-value-size, 1rem);--pdx-presentation-icon-size: var(--pfx-pres-icon-size, 18px);--pdx-presentation-row-gap: var(--pfx-pres-row-gap, .5rem);--pdx-presentation-column-gap: var(--pfx-pres-column-gap, .5rem);--pdx-presentation-section-gap: var(--pfx-pres-section-gap, .75rem);--pdx-presentation-label-width: var(--pfx-pres-label-width, 220px);--pdx-presentation-flag-height: var(--pfx-pres-boolean-min-height, 22px);--pdx-presentation-flag-radius: var(--pfx-pres-boolean-radius, 999px);--pdx-presentation-flag-padding: var(--pfx-pres-boolean-padding, 0 8px);--pdx-presentation-flag-active-color: var( --pfx-pres-boolean-active-color, var(--md-sys-color-primary) );--pdx-presentation-flag-active-bg: var( --pfx-pres-boolean-active-bg, color-mix(in srgb, var(--md-sys-color-primary) 14%, transparent) );--pdx-presentation-flag-inactive-color: var( --pfx-pres-boolean-inactive-color, var(--md-sys-color-on-surface-variant) );--pdx-presentation-flag-inactive-bg: var( --pfx-pres-boolean-inactive-bg, color-mix(in srgb, var(--md-sys-color-outline-variant) 34%, transparent) );--pfx-form-footer-surface: color-mix( in srgb, var(--pfx-editorial-form-surface) 70%, var(--pfx-editorial-form-surface-muted) 30% );--pfx-form-footer-border: color-mix( in srgb, var(--pfx-editorial-form-border) 76%, transparent )}.praxis-dynamic-form.canvas-mode-enabled{border:1px solid var(--pfx-form-footer-border);border-radius:var(--pfx-editorial-form-radius);background:linear-gradient(180deg,color-mix(in srgb,var(--pfx-form-shell-surface) 86%,transparent),color-mix(in srgb,var(--pfx-editorial-form-surface-muted) 42%,transparent));overflow:visible}.form-config-controls+.praxis-dynamic-form.canvas-mode-enabled{border-top:0;border-top-left-radius:0;border-top-right-radius:0}.praxis-dynamic-form.canvas-mode-enabled>.section-drop-wrapper,.praxis-dynamic-form.canvas-mode-enabled>.form-editorial-blocks{margin-inline:var(--pfx-form-shell-padding)}.praxis-dynamic-form.canvas-mode-enabled>.section-drop-wrapper:first-of-type,.praxis-dynamic-form.canvas-mode-enabled>.form-editorial-blocks:first-child{margin-top:var(--pfx-form-shell-padding)}.praxis-dynamic-form.canvas-mode-enabled>praxis-form-actions[data-actions-placement=afterSections]{display:block;margin-top:var(--pfx-form-shell-padding)}.praxis-dynamic-form.editorial-visual-context{--_pfx-editorial-host-text: var( --editorial-text-primary, var(--foreground, var(--mat-sys-on-surface, #1d1b20)) );--_pfx-editorial-host-text-muted: var( --editorial-text-secondary, var( --muted-foreground, color-mix(in srgb, var(--_pfx-editorial-host-text) 64%, transparent) ) );--_pfx-editorial-host-surface: var( --editorial-surface-primary, var(--card, var(--mat-sys-surface-container, #ffffff)) );--_pfx-editorial-host-surface-muted: var( --editorial-surface-secondary, var(--surface-dim, var(--muted, var(--mat-sys-surface-container-low, #f7f2fa))) );--_pfx-editorial-host-border: var( --editorial-border-color, var(--border, var(--mat-sys-outline-variant, #cac4d0)) );--_pfx-editorial-host-accent: var( --editorial-cta-primary, var(--editorial-accent, var(--primary, var(--mat-sys-primary, #6750a4))) );--_pfx-editorial-host-accent-text: var( --editorial-cta-primary-text, var( --editorial-accent-contrast, var(--primary-foreground, var(--mat-sys-on-primary, #ffffff)) ) );--_pfx-editorial-host-accent-container: var( --primary-container, color-mix(in srgb, var(--_pfx-editorial-host-accent) 16%, var(--_pfx-editorial-host-surface) 84%) );--_pfx-editorial-host-accent-container-text: var( --primary-container-fg, var(--_pfx-editorial-host-accent) );font-family:var(--editorial-body-font-family, inherit);font-size:var(--editorial-body-size, 1rem);color:var(--_pfx-editorial-host-text);--pfx-editorial-form-surface: var( --editorial-surface-primary, var(--pfx-form-section-surface, var(--_pfx-editorial-host-surface)) );--pfx-editorial-form-surface-muted: var( --editorial-surface-secondary, var(--_pfx-editorial-host-surface-muted) );--pfx-editorial-form-border: var( --editorial-border-color, var(--pfx-form-stroke, var(--_pfx-editorial-host-border)) );--pfx-editorial-form-text: var( --editorial-text-primary, var(--_pfx-editorial-host-text) );--pfx-editorial-form-text-muted: var( --editorial-text-secondary, color-mix( in srgb, var(--_pfx-editorial-host-text-muted) 86%, var(--_pfx-editorial-host-text) 14% ) );--pfx-editorial-form-accent: var( --editorial-cta-primary, var(--editorial-accent, var(--_pfx-editorial-host-accent)) );--pfx-editorial-form-accent-text: var( --editorial-cta-primary-text, var(--editorial-accent-contrast, var(--_pfx-editorial-host-accent-text)) );--pfx-editorial-form-accent-container: var(--_pfx-editorial-host-accent-container);--pfx-editorial-form-accent-container-text: var(--_pfx-editorial-host-accent-container-text);--pfx-editorial-form-radius: var(--editorial-card-radius, 18px);--pfx-editorial-form-field-radius: var( --editorial-field-radius, var(--editorial-card-radius, 14px) );--pfx-editorial-form-border-width: var(--editorial-card-border-width, 1px);--pfx-editorial-form-field-border-width: var(--editorial-field-border-width, 1px);--pfx-editorial-form-shadow: var(--editorial-card-shadow, none);--md-sys-color-surface: var( --pfx-editorial-form-surface, var(--md-sys-color-surface) );--md-sys-color-surface-container: var( --pfx-editorial-form-surface, var(--md-sys-color-surface-container) );--md-sys-color-surface-container-low: var( --pfx-editorial-form-surface-muted, var(--md-sys-color-surface-container-low) );--md-sys-color-surface-variant: var( --pfx-editorial-form-field-surface, var(--md-sys-color-surface-variant) );--md-sys-color-outline: var( --pfx-editorial-form-field-outline, var(--md-sys-color-outline) );--md-sys-color-outline-variant: var( --pfx-editorial-form-border, var(--md-sys-color-outline-variant) );--md-sys-color-on-surface: var( --editorial-text-primary, inherit );--md-sys-color-on-surface-variant: var( --editorial-text-secondary, inherit );--md-sys-color-primary: var( --pfx-editorial-form-accent, var(--md-sys-color-primary) );--md-sys-color-primary-container: var( --pfx-editorial-form-accent-container, var(--md-sys-color-primary-container) );--md-sys-color-on-primary-container: var( --pfx-editorial-form-accent-container-text, var(--md-sys-color-on-primary-container) );--md-sys-color-on-primary: var( --pfx-editorial-form-accent-text, var(--md-sys-color-on-primary) );--md-sys-color-on-surface-rgb: var( --editorial-text-primary-rgb, inherit );--mat-sys-on-surface: var( --editorial-text-primary, inherit );--mat-sys-on-surface-variant: var( --editorial-text-secondary, inherit );--mat-sys-on-surface-rgb: var( --editorial-text-primary-rgb, inherit );color:inherit;color-scheme:light}.praxis-dynamic-form.presentation-mode .form-row,.praxis-dynamic-form.readonly-mode .form-row{gap:var(--pdx-presentation-column-gap);margin-bottom:var(--pdx-presentation-row-gap)}.praxis-dynamic-form.presentation-mode{--pfx-pres-on-surface: var( --pdx-color-text-primary, var(--pfx-editorial-form-text, var(--pfx-form-label-strong, currentColor)) );--pfx-pres-on-surface-variant: var( --pdx-color-text-secondary, var( --pfx-editorial-form-text-muted, var( --pfx-form-label-muted, color-mix(in srgb, var(--pfx-pres-on-surface) 78%, transparent) ) ) )}.praxis-dynamic-form.presentation-mode .form-section,.praxis-dynamic-form.readonly-mode .form-section{padding:var(--pdx-presentation-section-gap) .875rem}.praxis-dynamic-form.pres-compact .form-row{gap:var(--pdx-presentation-column-gap, .35rem);margin-bottom:var(--pdx-presentation-row-gap, .35rem)}.praxis-dynamic-form.pres-compact .form-section{padding:var(--pdx-presentation-section-gap, .5rem) .75rem}.praxis-dynamic-form.pres-label-left .praxis-presentation{display:grid;grid-template-columns:minmax(0,var(--pfx-presentation-label-w, var(--pdx-presentation-label-width))) minmax(0,1fr);align-items:baseline;column-gap:var(--pdx-presentation-column-gap, 10px)}.praxis-dynamic-form.pres-label-left .praxis-presentation__label{text-align:right;margin-bottom:0}@media(max-width:480px){.praxis-dynamic-form.pres-label-left .praxis-presentation{grid-template-columns:minmax(0,1fr);row-gap:4px}.praxis-dynamic-form.pres-label-left .praxis-presentation__label{text-align:start}}.praxis-dynamic-form.praxis-dynamic-form--corporate-dossier .form-section:not(.section-appearance-plain),.praxis-dynamic-form .form-section.form-section--corporate-dossier:not(.section-appearance-plain),.praxis-dynamic-form .form-section[data-presentation-preset=corporate-dossier]:not(.section-appearance-plain){background:var(--md-sys-color-surface-container-low, #f8f9fa);border:1px solid var(--md-sys-color-outline-variant, #e0e2ec);border-radius:16px;padding:16px 20px;box-shadow:0 1px 3px #0000000a}.praxis-dynamic-form.praxis-dynamic-form--corporate-dossier .form-section .section-heading,.praxis-dynamic-form .form-section.form-section--corporate-dossier .section-heading,.praxis-dynamic-form .form-section[data-presentation-preset=corporate-dossier] .section-heading{margin-bottom:12px;padding-bottom:8px;border-bottom:1px solid var(--md-sys-color-outline-variant, #e0e2ec)}.praxis-dynamic-form.praxis-dynamic-form--corporate-dossier .form-section .section-title,.praxis-dynamic-form .form-section.form-section--corporate-dossier .section-title,.praxis-dynamic-form .form-section[data-presentation-preset=corporate-dossier] .section-title{font-size:.88rem;font-weight:700;letter-spacing:.05em;text-transform:uppercase;color:var(--md-sys-color-primary, #005ac1)}:host ::ng-deep .praxis-dynamic-form--corporate-dossier .praxis-presentation,:host ::ng-deep .form-section--corporate-dossier .praxis-presentation,:host ::ng-deep [data-presentation-preset=corporate-dossier] .praxis-presentation{padding:8px 0;border-bottom:1px dashed var(--md-sys-color-outline-variant, rgba(0, 0, 0, .08))}:host ::ng-deep .praxis-dynamic-form--corporate-dossier .form-row:last-child .praxis-presentation,:host ::ng-deep .praxis-dynamic-form--corporate-dossier .praxis-presentation:last-child,:host ::ng-deep .form-section--corporate-dossier .form-row:last-child .praxis-presentation,:host ::ng-deep .form-section--corporate-dossier .praxis-presentation:last-child,:host ::ng-deep [data-presentation-preset=corporate-dossier] .form-row:last-child .praxis-presentation,:host ::ng-deep [data-presentation-preset=corporate-dossier] .praxis-presentation:last-child{border-bottom:none}:host ::ng-deep .praxis-dynamic-form--corporate-dossier .praxis-presentation__label,:host ::ng-deep .form-section--corporate-dossier .praxis-presentation__label,:host ::ng-deep [data-presentation-preset=corporate-dossier] .praxis-presentation__label{font-size:.74rem;font-weight:600;text-transform:uppercase;letter-spacing:.05em;color:var(--md-sys-color-on-surface-variant, #44474f);margin-bottom:3px}:host ::ng-deep .praxis-dynamic-form--corporate-dossier .praxis-presentation__value,:host ::ng-deep .form-section--corporate-dossier .praxis-presentation__value,:host ::ng-deep [data-presentation-preset=corporate-dossier] .praxis-presentation__value{font-size:.95rem;font-weight:600;color:var(--md-sys-color-on-surface, #1a1c1e);line-height:1.4}.praxis-dynamic-form.praxis-dynamic-form--editorial-card .form-section:not(.section-appearance-plain),.praxis-dynamic-form .form-section.form-section--editorial-card:not(.section-appearance-plain),.praxis-dynamic-form .form-section[data-presentation-preset=editorial-card]:not(.section-appearance-plain){background:var(--pfx-editorial-form-surface, var(--md-sys-color-surface-container-low, var(--mat-sys-surface-container-low)));border:1px solid var(--pfx-editorial-form-border, var(--md-sys-color-outline-variant, #e0e2ec));border-radius:20px;padding:24px;box-shadow:0 2px 8px #0000000d}.praxis-dynamic-form.praxis-dynamic-form--editorial-card .form-section .section-heading,.praxis-dynamic-form .form-section.form-section--editorial-card .section-heading,.praxis-dynamic-form .form-section[data-presentation-preset=editorial-card] .section-heading{margin-bottom:16px;padding-bottom:10px;border-bottom:1px solid color-mix(in srgb,var(--md-sys-color-outline-variant, #e0e2ec) 40%,transparent)}.praxis-dynamic-form.praxis-dynamic-form--editorial-card .form-section .section-title,.praxis-dynamic-form .form-section.form-section--editorial-card .section-title,.praxis-dynamic-form .form-section[data-presentation-preset=editorial-card] .section-title{font-size:1.15rem;font-weight:700;color:var(--pfx-editorial-form-accent, var(--md-sys-color-primary, #005ac1))}:host ::ng-deep .praxis-dynamic-form--editorial-card .praxis-presentation,:host ::ng-deep .form-section--editorial-card .praxis-presentation,:host ::ng-deep [data-presentation-preset=editorial-card] .praxis-presentation{padding:10px 0;border-bottom:1px solid color-mix(in srgb,var(--md-sys-color-outline-variant, #e0e2ec) 35%,transparent)}:host ::ng-deep .praxis-dynamic-form--editorial-card .form-row:last-child .praxis-presentation,:host ::ng-deep .praxis-dynamic-form--editorial-card .praxis-presentation:last-child,:host ::ng-deep .form-section--editorial-card .form-row:last-child .praxis-presentation,:host ::ng-deep .form-section--editorial-card .praxis-presentation:last-child,:host ::ng-deep [data-presentation-preset=editorial-card] .form-row:last-child .praxis-presentation,:host ::ng-deep [data-presentation-preset=editorial-card] .praxis-presentation:last-child{border-bottom:none}:host ::ng-deep .praxis-dynamic-form--editorial-card .praxis-presentation__label,:host ::ng-deep .form-section--editorial-card .praxis-presentation__label,:host ::ng-deep [data-presentation-preset=editorial-card] .praxis-presentation__label{font-size:.8rem;font-weight:500;color:var(--pfx-editorial-form-text-muted, var(--md-sys-color-on-surface-variant, #44474f));margin-bottom:4px}:host ::ng-deep .praxis-dynamic-form--editorial-card .praxis-presentation__value,:host ::ng-deep .form-section--editorial-card .praxis-presentation__value,:host ::ng-deep [data-presentation-preset=editorial-card] .praxis-presentation__value{font-size:1rem;font-weight:600;color:var(--pfx-editorial-form-text, var(--md-sys-color-on-surface, #1a1c1e));line-height:1.5}.praxis-dynamic-form.praxis-dynamic-form--compact-presentation .form-section:not(.section-appearance-plain),.praxis-dynamic-form .form-section.form-section--compact-presentation:not(.section-appearance-plain),.praxis-dynamic-form .form-section[data-presentation-preset=compact-presentation]:not(.section-appearance-plain){background:transparent;border:1px solid color-mix(in srgb,var(--md-sys-color-outline-variant, #e0e2ec) 50%,transparent);border-radius:8px;padding:10px 14px;box-shadow:none}.praxis-dynamic-form.praxis-dynamic-form--compact-presentation .form-section .section-heading,.praxis-dynamic-form .form-section.form-section--compact-presentation .section-heading,.praxis-dynamic-form .form-section[data-presentation-preset=compact-presentation] .section-heading{margin-bottom:8px;padding-bottom:4px;border-bottom:1px solid color-mix(in srgb,var(--md-sys-color-outline-variant, #e0e2ec) 25%,transparent)}.praxis-dynamic-form.praxis-dynamic-form--compact-presentation .form-section .section-title,.praxis-dynamic-form .form-section.form-section--compact-presentation .section-title,.praxis-dynamic-form .form-section[data-presentation-preset=compact-presentation] .section-title{font-size:.82rem;font-weight:700;letter-spacing:.03em;text-transform:uppercase;color:var(--md-sys-color-on-surface-variant, #44474f)}:host ::ng-deep .praxis-dynamic-form--compact-presentation .praxis-presentation,:host ::ng-deep .form-section--compact-presentation .praxis-presentation,:host ::ng-deep [data-presentation-preset=compact-presentation] .praxis-presentation{padding:4px 0;border-bottom:none}:host ::ng-deep .praxis-dynamic-form--compact-presentation .praxis-presentation__label,:host ::ng-deep .form-section--compact-presentation .praxis-presentation__label,:host ::ng-deep [data-presentation-preset=compact-presentation] .praxis-presentation__label{font-size:.72rem;font-weight:600;color:var(--md-sys-color-on-surface-variant, #44474f);margin-bottom:2px}:host ::ng-deep .praxis-dynamic-form--compact-presentation .praxis-presentation__value,:host ::ng-deep .form-section--compact-presentation .praxis-presentation__value,:host ::ng-deep [data-presentation-preset=compact-presentation] .praxis-presentation__value{font-size:.88rem;font-weight:500;color:var(--md-sys-color-on-surface, #1a1c1e);line-height:1.35}:host-context(.mdc-theme-dark) .praxis-dynamic-form.praxis-dynamic-form--corporate-dossier .form-section:not(.section-appearance-plain),:host-context(.mdc-theme-dark) .praxis-dynamic-form .form-section.form-section--corporate-dossier:not(.section-appearance-plain),:host-context(.mdc-theme-dark) .praxis-dynamic-form .form-section[data-presentation-preset=corporate-dossier]:not(.section-appearance-plain),:host-context(.theme-dark) .praxis-dynamic-form.praxis-dynamic-form--corporate-dossier .form-section:not(.section-appearance-plain),:host-context(.theme-dark) .praxis-dynamic-form .form-section.form-section--corporate-dossier:not(.section-appearance-plain),:host-context(.theme-dark) .praxis-dynamic-form .form-section[data-presentation-preset=corporate-dossier]:not(.section-appearance-plain){background:var(--md-sys-color-surface-container-low);border-color:color-mix(in srgb,var(--md-sys-color-outline-variant) 70%,transparent);box-shadow:0 2px 8px #0000004d}:host-context(.mdc-theme-dark) .praxis-dynamic-form.praxis-dynamic-form--editorial-card .form-section:not(.section-appearance-plain),:host-context(.mdc-theme-dark) .praxis-dynamic-form .form-section.form-section--editorial-card:not(.section-appearance-plain),:host-context(.mdc-theme-dark) .praxis-dynamic-form .form-section[data-presentation-preset=editorial-card]:not(.section-appearance-plain),:host-context(.theme-dark) .praxis-dynamic-form.praxis-dynamic-form--editorial-card .form-section:not(.section-appearance-plain),:host-context(.theme-dark) .praxis-dynamic-form .form-section.form-section--editorial-card:not(.section-appearance-plain),:host-context(.theme-dark) .praxis-dynamic-form .form-section[data-presentation-preset=editorial-card]:not(.section-appearance-plain){background:var(--pfx-editorial-form-surface, var(--md-sys-color-surface-container-low));border-color:color-mix(in srgb,var(--md-sys-color-outline-variant) 70%,transparent);box-shadow:0 4px 16px #0006}.form-section{border:1px solid var(--pfx-form-section-divider);border-radius:var(--pfx-editorial-form-radius);padding:var(--pfx-form-section-padding);max-width:100%;min-width:0;background:var(--pfx-form-section-surface-flat);box-shadow:none;transition:all .2s ease;position:relative}.praxis-dynamic-form.editorial-visual-context .form-section:not(.section-appearance-plain){border:var(--pfx-editorial-form-border-width) solid var(--pfx-editorial-form-border)!important;background:var(--pfx-editorial-form-surface)!important;color:var(--pfx-editorial-form-text);box-shadow:var(--editorial-card-shadow, none)}.praxis-dynamic-form.editorial-visual-context .form-section.section-appearance-step{background-color:var(--pfx-editorial-form-surface)!important;background-image:linear-gradient(180deg,color-mix(in srgb,var(--editorial-accent, var(--md-sys-color-primary)) 6%,transparent) 0%,transparent 132px)!important;background-repeat:no-repeat!important}.section-drop-wrapper>.form-section{margin-bottom:var(--pfx-section-gap, 20px)}.section-drop-wrapper:last-of-type>.form-section{margin-bottom:0}.praxis-dynamic-form>praxis-form-actions[data-actions-placement=afterSections]{margin-top:var(--pfx-actions-gap-top, var(--pfx-section-gap, 20px))}.section-title{margin:0 0 var(--pfx-section-title-mb, 12px) 0;font-family:var(--editorial-title-font-family, var(--editorial-body-font-family, inherit));font-size:var(--editorial-step-title-size, 1.12rem);font-weight:700;color:var(--pfx-form-label-strong)}.section-heading{position:relative;display:flex;align-items:flex-start;gap:12px;margin-bottom:18px;padding-bottom:var(--pfx-form-section-heading-divider-gap, 18px)}.section-heading:after{content:\"\";position:absolute;right:0;bottom:0;left:0;height:2px;pointer-events:none;background:linear-gradient(90deg,transparent 0%,color-mix(in srgb,var(--pfx-form-section-divider) 18%,transparent) 8%,var(--pfx-form-section-divider) 46%,var(--pfx-form-section-divider) 54%,color-mix(in srgb,var(--pfx-form-section-divider) 18%,transparent) 92%,transparent 100%);border-radius:999px;-webkit-mask-image:linear-gradient(90deg,transparent 0%,black 18%,black 82%,transparent 100%);mask-image:linear-gradient(90deg,transparent 0%,black 18%,black 82%,transparent 100%)}.section-heading.title-only{padding-bottom:var(--pfx-form-section-heading-title-only-divider-gap, 10px)}:host(.pfx-form-section-divider-inline-title) .section-heading.title-only{padding-bottom:var(--pfx-form-section-heading-title-only-inline-divider-gap, 0)}:host(.pfx-form-section-divider-inline-title) .section-heading.title-only:after{display:none}.section-heading.align-center{flex-direction:column;align-items:center;text-align:center}.section-heading.align-center .section-heading-text{display:grid;justify-items:center}.section-step-label{display:inline-flex;align-items:center;min-height:24px;padding:0 10px;margin:0 0 8px;border-radius:999px;background:color-mix(in srgb,var(--pfx-editorial-form-accent) 10%,transparent);color:color-mix(in srgb,var(--pfx-editorial-form-accent) 84%,var(--pfx-form-label-strong) 16%);font-size:.72rem;font-weight:800;font-family:var(--editorial-title-font-family, var(--editorial-body-font-family, inherit));letter-spacing:.08em;text-transform:uppercase}.section-heading-text{flex:1 1 auto;min-width:0}.section-heading-actions{display:inline-flex;align-items:center;align-self:flex-start;flex-wrap:wrap;gap:4px;margin-left:auto}.section-heading-actions.align-center{align-self:center;margin-left:0}.section-heading-action-btn{color:var(--pfx-form-label-muted)}.section-heading-action-btn.tone-primary{color:var(--md-sys-color-primary)}.section-heading-action-btn.tone-accent,.section-heading-action-btn.tone-secondary{color:var(--md-sys-color-tertiary)}.section-heading-action-btn.tone-warn,.section-heading-action-btn.tone-danger,.section-heading-action-btn.tone-error{color:var(--md-sys-color-error)}.section-heading-action-btn .mat-mdc-progress-spinner,.section-heading-action-btn mat-progress-spinner{--mdc-circular-progress-active-indicator-color: currentColor}.section-heading-action-btn.loading{opacity:.72;pointer-events:none}.section-heading-action-sr-only{position:absolute;width:1px;height:1px;padding:0;margin:-1px;overflow:hidden;clip:rect(0,0,0,0);white-space:nowrap;border:0}.section-collapse-btn{margin-left:4px;color:var(--pfx-form-label-muted)}.section-title.title-large{font:var(--mdc-typography-title-large, 500 22px/28px system-ui)}.section-title.title-medium{font:var(--mdc-typography-title-medium, 500 16px/24px system-ui)}.section-title.title-small{font:var(--mdc-typography-title-small, 500 14px/20px system-ui)}.section-title.headline-small{font:var(--mdc-typography-headline-small, 600 24px/32px system-ui)}.section-title.title-large,.section-title.title-medium,.section-title.title-small,.section-title.headline-small{font-family:var(--editorial-title-font-family, var(--editorial-body-font-family, inherit));font-weight:var(--editorial-title-weight, 600)}.section-description{margin:0;font-family:var(--editorial-body-font-family, inherit);font-size:.93rem;color:var(--pfx-form-label-muted);line-height:1.6}.section-description.body-large{font:var(--mdc-typography-body-large, 400 16px/24px system-ui)}.section-description.body-medium{font:var(--mdc-typography-body-medium, 400 14px/20px system-ui)}.section-description.body-small{font:var(--mdc-typography-body-small, 400 12px/16px system-ui)}.section-description.body-large,.section-description.body-medium,.section-description.body-small{font-family:var(--editorial-body-font-family, inherit);font-weight:var(--editorial-body-weight, 400)}.section-title.align-center,.section-description.align-center,.section-step-label.align-center{text-align:center}.praxis-dynamic-form .form-section.section-appearance-plain{border-color:transparent;border-width:0;border-radius:0;padding:0;background:transparent;box-shadow:none}.praxis-dynamic-form .form-section.section-appearance-plain.section-has-divider{padding-bottom:16px;border-bottom:1px solid var(--pfx-form-section-divider, var(--md-sys-color-outline-variant, #e0e2ec))}.praxis-dynamic-form .section-drop-wrapper:last-of-type>.form-section.section-appearance-plain.section-has-divider,.praxis-dynamic-form>.form-section.section-appearance-plain.section-has-divider:last-of-type{border-bottom:none;padding-bottom:0}.form-section.section-appearance-plain .section-heading{margin-bottom:14px}.form-section.section-appearance-step{border-radius:var(--pfx-editorial-form-radius);padding:var(--pfx-form-section-padding);background:var(--pfx-form-section-surface-flat);border-color:var(--pfx-form-section-divider);box-shadow:none}.praxis-dynamic-form.editorial-visual-context .form-section.section-appearance-step{border-radius:var(--editorial-card-radius, 20px);box-shadow:none}.form-section.section-appearance-step .section-heading{margin-bottom:22px;padding-bottom:var(--pfx-form-section-heading-divider-gap, 16px)}.form-section.section-appearance-step .section-heading.title-only{padding-bottom:var(--pfx-form-section-heading-title-only-divider-gap, 16px)}:host(.pfx-form-section-divider-inline-title) .form-section.section-appearance-step .section-heading.title-only{padding-bottom:var(--pfx-form-section-heading-title-only-inline-divider-gap, 0)}.form-section.section-appearance-step .section-title{font:var(--mdc-typography-title-large, 700 22px/28px system-ui);color:var(--pfx-form-label-strong);margin-bottom:8px}.form-section.section-appearance-step .section-description{color:var(--pfx-form-label-muted);max-width:60ch}.form-section.section-appearance-step .section-step-label{min-height:24px;padding:0 10px;margin-bottom:10px;box-shadow:none}.form-section.section-appearance-step .section-heading.align-center .section-description{max-width:52ch}.form-section.section-appearance-step .section-body{display:grid;gap:8px;padding-top:0}.form-section.section-appearance-step .form-row{margin-bottom:var(--pfx-field-gap, 1rem)}.form-section.section-appearance-step .form-column{gap:var(--pfx-field-gap, 12px)}.form-section .form-editorial-blocks{display:grid;gap:16px}.form-section .form-editorial-blocks[data-editorial-placement=beforeActions]{margin-top:24px;padding-top:18px;border-top:1px solid var(--pfx-form-section-divider)}.form-section.section-appearance-step .form-editorial-blocks[data-editorial-placement=beforeActions]{gap:18px}.form-section.section-appearance-step .form-editorial-blocks[data-editorial-placement=beforeActions]>*+*{margin-top:2px}.praxis-dynamic-form:not(.canvas-mode-enabled)>praxis-form-actions[data-actions-placement=afterSections]{margin-top:18px}.praxis-dynamic-form>.form-editorial-blocks[data-editorial-placement=after]{margin-top:6px}:host-context(.mdc-theme-dark) .form-section.section-appearance-step,:host-context(.theme-dark) .form-section.section-appearance-step{border-color:color-mix(in srgb,var(--pfx-editorial-form-border) 82%,transparent);box-shadow:none}:host-context(.mdc-theme-dark) .form-section.section-appearance-step .section-title,:host-context(.theme-dark) .form-section.section-appearance-step .section-title{color:color-mix(in srgb,var(--pfx-editorial-form-text) 96%,white)}:host-context(.mdc-theme-dark) .form-section.section-appearance-step .section-description,:host-context(.theme-dark) .form-section.section-appearance-step .section-description{color:color-mix(in srgb,var(--pfx-editorial-form-text-muted) 86%,var(--pfx-editorial-form-text) 14%)}:host-context(.mdc-theme-dark) .section-step-label,:host-context(.theme-dark) .section-step-label{background:color-mix(in srgb,var(--md-sys-color-primary-container) 54%,transparent);color:color-mix(in srgb,var(--md-sys-color-primary) 88%,white)}:host-context(.mdc-theme-dark) .form-section .form-editorial-blocks[data-editorial-placement=beforeActions],:host-context(.theme-dark) .form-section .form-editorial-blocks[data-editorial-placement=beforeActions]{border-top-color:color-mix(in srgb,var(--md-sys-color-outline-variant) 90%,transparent)}.inline-edit-btn{margin-left:6px;vertical-align:middle}.section-body.collapsed{border:1px dashed var(--md-sys-color-outline-variant);background:var(--md-sys-color-surface-container-low);border-radius:6px;padding:8px 10px}.section-collapsed-placeholder{display:flex;align-items:center;gap:8px;color:var(--md-sys-color-on-surface-variant);font-size:.95rem}.section-collapsed-placeholder mat-icon{font-size:20px;width:20px;height:20px}.form-row{display:flex;gap:1.1rem;margin-bottom:var(--pfx-field-gap, 1.1rem);max-width:100%;min-width:0;transition:all .2s ease;border-radius:6px;position:relative}.praxis-dynamic-form.pfx-mounting .form-row{opacity:0;transform:translateY(var(--pdx-form-mount-offset, 6px));animation:pdxFormMount var(--pdx-form-mount-duration, .16s) ease-out both;animation-delay:calc(var(--pfx-mount-index, 0) * var(--pdx-form-mount-stagger, 20ms))}@media(prefers-reduced-motion:reduce){.praxis-dynamic-form.pfx-mounting .form-row{animation:none;opacity:1;transform:none}}@keyframes pdxFormMount{to{opacity:1;transform:translateY(0)}}.praxis-dynamic-form .mat-mdc-form-field{width:100%;margin-bottom:var(--pfx-field-gap, 10px);font-family:inherit;--mdc-filled-text-field-container-color: var(--pfx-form-field-surface-rest);--mdc-filled-text-field-focus-active-indicator-color: var(--pfx-editorial-form-accent);--mdc-filled-text-field-active-indicator-color: var(--pfx-editorial-form-field-outline);--mdc-filled-text-field-hover-active-indicator-color: var(--pfx-editorial-form-accent);--mdc-filled-text-field-focus-label-text-color: var(--pfx-editorial-form-accent);--mdc-filled-text-field-label-text-color: var(--pfx-form-label-muted);--mdc-filled-text-field-input-text-color: var(--pfx-editorial-form-text);--mdc-filled-text-field-caret-color: var(--pfx-editorial-form-accent);--mdc-filled-text-field-input-text-placeholder-color: color-mix( in srgb, var(--pfx-editorial-form-text-muted) 82%, transparent );--mdc-outlined-text-field-outline-color: var(--pfx-editorial-form-field-outline);--mdc-outlined-text-field-hover-outline-color: var(--pfx-editorial-form-accent);--mdc-outlined-text-field-focus-outline-color: var(--pfx-editorial-form-accent);--mdc-outlined-text-field-focus-label-text-color: var(--pfx-editorial-form-accent);--mdc-outlined-text-field-label-text-color: var(--pfx-form-label-muted);--mdc-outlined-text-field-input-text-color: var(--pfx-editorial-form-text);--mdc-filled-text-field-container-shape: var(--pfx-editorial-form-field-radius);--mdc-outlined-text-field-container-shape: var(--pfx-editorial-form-field-radius);--mdc-filled-text-field-active-indicator-height: var(--pfx-editorial-form-field-border-width);--mdc-filled-text-field-focus-active-indicator-height: var(--pfx-editorial-form-field-border-width);--mdc-outlined-text-field-outline-width: var(--pfx-editorial-form-field-border-width);--mdc-outlined-text-field-focus-outline-width: var(--pfx-editorial-form-field-border-width);--mat-select-enabled-trigger-text-color: var(--pfx-editorial-form-text);--mat-select-enabled-arrow-color: var(--pfx-form-label-muted);--mat-form-field-enabled-select-arrow-color: var(--pfx-form-label-muted);--mat-form-field-focus-select-arrow-color: var(--pfx-editorial-form-accent);--mat-form-field-hover-state-layer-opacity: 0;--mat-form-field-focus-state-layer-opacity: 0}.praxis-dynamic-form.editorial-visual-context .mat-mdc-form-field{font-family:var(--editorial-body-font-family, inherit)}.praxis-dynamic-form .mat-mdc-text-field-wrapper,.praxis-dynamic-form .mdc-text-field{background:var(--pfx-form-field-surface-rest);border-radius:var(--pfx-editorial-form-field-radius);min-height:var(--pfx-form-field-min-height);transition:background-color .16s ease,box-shadow .16s ease,border-color .16s ease}.praxis-dynamic-form.editorial-visual-context .mat-mdc-text-field-wrapper,.praxis-dynamic-form.editorial-visual-context .mdc-text-field,.praxis-dynamic-form.editorial-visual-context .mdc-text-field--filled,.praxis-dynamic-form.editorial-visual-context .mdc-text-field--outlined{background-color:var(--pfx-form-field-surface-rest)!important;background:var(--pfx-form-field-surface-rest)!important}.praxis-dynamic-form .mat-mdc-form-field .mdc-floating-label,.praxis-dynamic-form .mat-mdc-form-field .mat-mdc-form-field-hint,.praxis-dynamic-form .mat-mdc-form-field .mat-mdc-form-field-error,.praxis-dynamic-form .mat-mdc-form-field .mat-mdc-form-field-required-marker,.praxis-dynamic-form .mat-mdc-form-field .mat-mdc-select-arrow,.praxis-dynamic-form .mat-mdc-form-field .mat-mdc-select-placeholder,.praxis-dynamic-form .mat-mdc-form-field .mat-mdc-form-field-icon-suffix,.praxis-dynamic-form .mat-mdc-form-field .mat-mdc-form-field-icon-prefix{color:var(--pfx-form-label-muted)}.praxis-dynamic-form .mat-mdc-input-element,.praxis-dynamic-form .mat-mdc-select-value-text,.praxis-dynamic-form .mat-mdc-form-field-infix,.praxis-dynamic-form .mat-mdc-select-min-line{color:var(--pfx-editorial-form-text)}.praxis-dynamic-form .mat-mdc-form-field:hover .mat-mdc-text-field-wrapper,.praxis-dynamic-form .mat-mdc-form-field:hover .mdc-text-field,.praxis-dynamic-form .mat-mdc-form-field.mat-focused .mat-mdc-text-field-wrapper,.praxis-dynamic-form .mat-mdc-form-field.mat-focused .mdc-text-field{background:var(--pfx-form-field-surface-focus)}.praxis-dynamic-form.editorial-visual-context .mat-mdc-input-element,.praxis-dynamic-form.editorial-visual-context .mat-mdc-select-value-text,.praxis-dynamic-form.editorial-visual-context .mat-mdc-form-field-infix,.praxis-dynamic-form.editorial-visual-context .mat-mdc-select-min-line,.praxis-dynamic-form.editorial-visual-context .mdc-text-field__input{color:var(--pfx-editorial-form-text)!important;-webkit-text-fill-color:var(--pfx-editorial-form-text)!important}.praxis-dynamic-form.editorial-visual-context .mat-mdc-form-field .mdc-floating-label,.praxis-dynamic-form.editorial-visual-context .mat-mdc-form-field .mat-mdc-form-field-hint,.praxis-dynamic-form.editorial-visual-context .mat-mdc-form-field .mat-mdc-form-field-error,.praxis-dynamic-form.editorial-visual-context .mat-mdc-form-field .mat-mdc-form-field-required-marker,.praxis-dynamic-form.editorial-visual-context .mat-mdc-form-field .mat-mdc-select-arrow,.praxis-dynamic-form.editorial-visual-context .mat-mdc-form-field .mat-mdc-select-placeholder,.praxis-dynamic-form.editorial-visual-context .mat-mdc-form-field .mat-mdc-form-field-icon-suffix,.praxis-dynamic-form.editorial-visual-context .mat-mdc-form-field .mat-mdc-form-field-icon-prefix{color:var(--pfx-editorial-form-text-muted)!important}.praxis-dynamic-form.editorial-visual-context .mat-mdc-floating-label,.praxis-dynamic-form.editorial-visual-context .mdc-floating-label,.praxis-dynamic-form.editorial-visual-context .mdc-text-field__input::placeholder{color:color-mix(in srgb,var(--pfx-editorial-form-text) 68%,transparent)!important}.praxis-dynamic-form.editorial-visual-context .mat-mdc-input-element::placeholder,.praxis-dynamic-form.editorial-visual-context textarea.mat-mdc-input-element::placeholder{color:color-mix(in srgb,var(--pfx-editorial-form-text) 58%,transparent)!important}.praxis-dynamic-form .mat-mdc-radio-button,.praxis-dynamic-form .mat-mdc-checkbox,.praxis-dynamic-form .mat-mdc-slide-toggle{--mdc-radio-selected-icon-color: var(--pfx-editorial-form-accent);--mdc-radio-selected-hover-icon-color: var(--pfx-editorial-form-accent);--mdc-radio-selected-focus-icon-color: var(--pfx-editorial-form-accent);--mdc-checkbox-selected-checkmark-color: var(--pfx-editorial-form-accent-text);--mdc-checkbox-selected-focus-icon-color: var(--pfx-editorial-form-accent);--mdc-checkbox-selected-hover-icon-color: var(--pfx-editorial-form-accent);--mdc-checkbox-selected-icon-color: var(--pfx-editorial-form-accent);--mdc-switch-selected-focus-state-layer-color: var(--pfx-editorial-form-accent);--mdc-switch-selected-handle-color: var(--pfx-editorial-form-accent);--mdc-switch-selected-track-color: color-mix(in srgb, var(--pfx-editorial-form-accent) 45%, #fff)}.praxis-dynamic-form [data-field-type=input],.praxis-dynamic-form [data-field-type=textarea],.praxis-dynamic-form [data-field-type=email],.praxis-dynamic-form [data-field-type=password],.praxis-dynamic-form [data-field-type=url],.praxis-dynamic-form [data-field-type=search],.praxis-dynamic-form [data-field-type=phone],.praxis-dynamic-form [data-field-type=numericTextBox],.praxis-dynamic-form [data-field-type=currency],.praxis-dynamic-form [data-field-type=cpfCnpj],.praxis-dynamic-form [data-field-type=date],.praxis-dynamic-form [data-field-type=dateInput],.praxis-dynamic-form [data-field-type=dateRange],.praxis-dynamic-form [data-field-type=dateTimeLocal],.praxis-dynamic-form [data-field-type=time],.praxis-dynamic-form [data-field-type=timePicker],.praxis-dynamic-form [data-field-type=timeRange],.praxis-dynamic-form [data-field-type=month],.praxis-dynamic-form [data-field-type=week],.praxis-dynamic-form [data-field-type=yearInput],.praxis-dynamic-form [data-field-type=select],.praxis-dynamic-form [data-field-type=multi-select],.praxis-dynamic-form [data-field-type=searchable-select],.praxis-dynamic-form [data-field-type=async-select],.praxis-dynamic-form [data-field-type=autocomplete],.praxis-dynamic-form [data-field-type=entityLookup],.praxis-dynamic-form [data-field-type=tree-select],.praxis-dynamic-form [data-field-type=multi-select-tree],.praxis-dynamic-form [data-field-type=priceRange],.praxis-dynamic-form [data-field-type=file-upload]{display:block;width:100%;min-width:0}.praxis-dynamic-form .mat-mdc-form-field-subscript-wrapper{min-height:var(--pfx-subscript-min-h, 22px)}.form-row:last-child{margin-bottom:0}.form-column{display:grid;grid-template-columns:minmax(0,1fr);align-content:start;gap:var(--pfx-field-gap, 10px);flex:1;max-width:100%;min-width:0;transition:all .2s ease;border-radius:4px;position:relative}.form-layout-rich-content{display:block;width:100%;max-width:100%;min-width:0;margin-bottom:var(--pfx-field-gap, 10px);color:var(--pfx-editorial-form-text-muted, var(--md-sys-color-on-surface-variant));font:var(--mdc-typography-body-medium, 400 14px/20px system-ui);overflow-wrap:anywhere}:host ::ng-deep .form-layout-rich-content .prx-rich-content-root{display:grid;gap:8px;min-width:0;max-width:100%}:host ::ng-deep .form-layout-rich-content .prx-rich-node{min-width:0;max-width:100%}:host ::ng-deep .form-layout-rich-content .prx-rich-text{color:inherit;line-height:20px}:host ::ng-deep .form-layout-rich-content .praxis-form-visual-block--note,:host ::ng-deep .form-layout-rich-content .praxis-rich-content-notice{border:1px solid color-mix(in srgb,var(--pfx-editorial-form-accent) 12%,var(--pfx-editorial-form-border) 88%);border-left:3px solid var(--pfx-editorial-form-accent);border-radius:8px;background:color-mix(in srgb,var(--pfx-editorial-form-accent-container) 12%,var(--pfx-editorial-form-surface-muted) 88%)}:host ::ng-deep .form-layout-rich-content .praxis-form-visual-block--note{display:grid;grid-template-columns:20px minmax(0,1fr);gap:10px;align-items:flex-start;padding:11px 12px}:host ::ng-deep .form-layout-rich-content .praxis-form-visual-block--note:before{content:\"info\";display:inline-flex;align-items:center;justify-content:center;width:20px;height:20px;color:var(--pfx-editorial-form-accent);font-family:Material Symbols Outlined;font-size:20px;font-weight:400;line-height:20px}:host ::ng-deep .form-layout-rich-content .praxis-form-visual-block--note .prx-rich-text{color:var(--pfx-editorial-form-text-muted)}:host ::ng-deep .form-layout-rich-content .praxis-rich-content-notice{padding:10px 12px;color:var(--pfx-editorial-form-text)}:host ::ng-deep .form-layout-rich-content .praxis-rich-content-notice .prx-rich-compose{align-items:flex-start;gap:10px}:host ::ng-deep .form-layout-rich-content .praxis-rich-content-notice .prx-rich-icon{color:var(--pfx-editorial-form-accent);font-size:20px;line-height:20px;margin-top:1px}:host ::ng-deep .form-layout-rich-content .praxis-rich-content-divider{display:grid;grid-template-columns:minmax(24px,1fr) auto minmax(24px,1fr);align-items:center;gap:10px;color:var(--pfx-editorial-form-text-muted);font:var(--mdc-typography-label-small, 600 12px/16px system-ui);text-transform:uppercase}:host ::ng-deep .form-layout-rich-content .praxis-rich-content-divider:before,:host ::ng-deep .form-layout-rich-content .praxis-rich-content-divider:after{content:\"\";height:1px;background:var(--pfx-editorial-form-border)}:host ::ng-deep .form-layout-rich-content .prx-rich-card{gap:6px;padding:12px 14px;border-color:var(--pfx-editorial-form-border);border-radius:8px;background:var(--pfx-editorial-form-surface-muted);color:var(--pfx-editorial-form-text);box-shadow:none}:host ::ng-deep .form-layout-rich-content .prx-rich-card-title{color:var(--pfx-editorial-form-text);font:var(--mdc-typography-title-small, 600 14px/20px system-ui)}:host ::ng-deep .form-layout-rich-content .prx-rich-card-subtitle,:host ::ng-deep .form-layout-rich-content .prx-rich-metric-caption{color:var(--pfx-editorial-form-text-muted)}:host ::ng-deep .form-layout-rich-content .prx-rich-card .prx-rich-text{color:var(--pfx-editorial-form-text-muted)}:host ::ng-deep .form-layout-rich-content .prx-rich-badge{background:var(--pfx-editorial-form-accent-container);color:var(--pfx-editorial-form-accent-container-text)}.form-row.grid-12{container-type:inline-size;container-name:praxis-form-row;display:grid;grid-template-columns:repeat(12,minmax(0,1fr));gap:var(--pfx-grid-gap, 16px)}.align-start{align-self:flex-start}.align-center{align-self:center}.align-end{align-self:flex-end}.align-stretch{align-self:stretch}.form-blocking-overlay{position:absolute;inset:0;background:transparent;color:var(--md-sys-color-on-surface);backdrop-filter:blur(2px) saturate(103%);-webkit-backdrop-filter:blur(2px) saturate(103%);display:flex;align-items:center;justify-content:center;flex-direction:column;gap:12px;z-index:10;pointer-events:all}@media(max-width:768px){.column-drop-wrapper,.row-drop-wrapper,.form-layout-rich-content,.praxis-dynamic-form .mat-mdc-form-field,.praxis-dynamic-form .mat-mdc-text-field-wrapper,.praxis-dynamic-form .mdc-text-field{max-width:100%;min-width:0}:host ::ng-deep .praxis-dynamic-form .pfx-field-shell,:host ::ng-deep .praxis-dynamic-form .pfx-field-shell-wrapper,:host ::ng-deep .praxis-dynamic-form .pfx-field-shell-host,:host ::ng-deep .praxis-dynamic-form .mat-mdc-form-field,:host ::ng-deep .praxis-dynamic-form .mat-mdc-text-field-wrapper,:host ::ng-deep .praxis-dynamic-form .mdc-text-field{width:100%;max-width:100%;min-width:0}.form-section{padding:clamp(.75rem,4vw,1rem)}.section-heading{gap:10px;margin-bottom:16px;padding-bottom:var(--pfx-form-section-heading-divider-gap, 14px)}.section-heading.title-only{padding-bottom:var(--pfx-form-section-heading-title-only-divider-gap, 8px)}}.section-title{display:flex;align-items:center;gap:8px}:host(.pfx-form-section-divider-inline-title) .section-heading.title-only .section-title{width:100%;min-width:0}:host(.pfx-form-section-divider-inline-title) .section-heading.title-only .section-title:after{content:\"\";display:block;flex:1 1 auto;min-width:var(--pfx-form-section-title-inline-divider-min-width, 48px);height:2px;margin-left:var(--pfx-form-section-title-inline-divider-gap, 12px);pointer-events:none;background:linear-gradient(90deg,var(--pfx-form-section-divider) 0%,var(--pfx-form-section-divider) 62%,color-mix(in srgb,var(--pfx-form-section-divider) 18%,transparent) 88%,transparent 100%);border-radius:999px;-webkit-mask-image:linear-gradient(90deg,black 0%,black 72%,transparent 100%);mask-image:linear-gradient(90deg,black 0%,black 72%,transparent 100%)}:host(.pfx-form-section-divider-inline-title) .section-heading.align-center .section-title:after{display:none}@media(max-width:640px){:host(.pfx-form-section-divider-inline-title) .section-heading.title-only{padding-bottom:var(--pfx-form-section-heading-title-only-divider-gap, 8px)}:host(.pfx-form-section-divider-inline-title) .section-heading.title-only:after{display:block}:host(.pfx-form-section-divider-inline-title) .section-heading.title-only .section-title{width:auto}:host(.pfx-form-section-divider-inline-title) .section-heading.title-only .section-title:after{display:none}}.section-title .section-title-icon{font-size:1.25em;line-height:1}.section-title-avatar{--_pfx-form-section-avatar-size: var(--pfx-form-section-avatar-size-md, var(--pfx-form-section-avatar-size, 32px));display:inline-flex;align-items:center;justify-content:center;width:var(--_pfx-form-section-avatar-size);height:var(--_pfx-form-section-avatar-size);border-radius:999px;flex:0 0 var(--_pfx-form-section-avatar-size);overflow:hidden}.section-title-avatar.size-sm{--_pfx-form-section-avatar-size: var(--pfx-form-section-avatar-size-sm, 24px)}.section-title-avatar.size-md{--_pfx-form-section-avatar-size: var(--pfx-form-section-avatar-size-md, var(--pfx-form-section-avatar-size, 32px))}.section-title-avatar.size-lg{--_pfx-form-section-avatar-size: var(--pfx-form-section-avatar-size-lg, 40px)}.section-title-avatar-image{object-fit:cover;border:1px solid color-mix(in srgb,var(--pfx-form-section-divider) 72%,transparent);background:var(--pfx-form-section-surface-flat)}.section-title-avatar-text,.section-title-avatar-placeholder{background:color-mix(in srgb,var(--pfx-editorial-form-accent) 14%,var(--pfx-form-section-surface-flat));color:color-mix(in srgb,var(--pfx-editorial-form-accent) 82%,var(--pfx-form-label-strong) 18%);font-size:calc(var(--_pfx-form-section-avatar-size) * .41);font-weight:800;letter-spacing:.04em;text-transform:uppercase}.section-title-avatar-placeholder mat-icon{font-size:calc(var(--_pfx-form-section-avatar-size) * .5625);width:calc(var(--_pfx-form-section-avatar-size) * .5625);height:calc(var(--_pfx-form-section-avatar-size) * .5625);line-height:calc(var(--_pfx-form-section-avatar-size) * .5625)}.section-title-avatar-sr-only{position:absolute;width:1px;height:1px;padding:0;margin:-1px;overflow:hidden;clip:rect(0,0,0,0);white-space:nowrap;border:0}.form-context-empty-state{display:grid;min-height:var(--pdx-form-context-empty-min-height, 0);place-items:center;padding:var(--pdx-form-context-empty-padding, 0)}.form-context-empty-state praxis-empty-state-card{display:block;width:min(100%,var(--pdx-form-context-empty-max-width, 32rem))}.prx-form-tabs{display:block;margin-bottom:16px;max-width:100%}.prx-form-tabs__tablist{display:flex;flex-wrap:wrap;align-items:center;gap:8px;max-width:100%}.prx-form-tabs__tablist--scrollable{flex-wrap:nowrap;overflow-x:auto;overflow-y:hidden;scrollbar-width:none;-webkit-overflow-scrolling:touch;padding:4px 2px}.prx-form-tabs__tablist--scrollable::-webkit-scrollbar{display:none}.prx-form-tabs__tab{display:inline-flex;align-items:center;gap:8px;min-width:0;padding:8px 14px;border-radius:999px;border:1px solid var(--md-sys-color-outline-variant, rgba(0, 0, 0, .12));background:color-mix(in srgb,var(--md-sys-color-surface, transparent) 40%,transparent);color:var(--md-sys-color-on-surface, #1d1b20);font-family:inherit;font-size:.84rem;font-weight:500;cursor:pointer;white-space:nowrap;flex-shrink:0;-webkit-user-select:none;user-select:none;transition:all .2s cubic-bezier(.2,0,0,1)}.prx-form-tabs__tab:hover:not(:disabled):not(.prx-form-tabs__tab--active){background:var(--md-sys-color-surface-container-high, rgba(0, 0, 0, .05));border-color:var(--md-sys-color-outline, rgba(0, 0, 0, .24));color:var(--md-sys-color-on-surface)}.prx-form-tabs__tab:focus-visible{outline:2px solid var(--md-sys-color-primary, #005ac1);outline-offset:2px}.prx-form-tabs__tab:disabled{cursor:not-allowed;opacity:.45}.prx-form-tabs__tab--active{background:var(--md-sys-color-primary-container, color-mix(in srgb, var(--md-sys-color-primary, #005ac1) 16%, var(--md-sys-color-surface-container-high, #2b2930)));color:var(--md-sys-color-on-primary-container, var(--md-sys-color-primary, #005ac1));border-color:transparent;font-weight:600;box-shadow:0 1px 3px #00000014}.prx-form-tabs__tab-icon{font-size:18px;width:18px;height:18px;display:inline-flex;align-items:center;justify-content:center}.prx-form-tabs__tab-badge{display:inline-flex;align-items:center;justify-content:center;padding:1px 7px;font-size:.72rem;font-weight:600;border-radius:999px;background:color-mix(in srgb,currentColor 14%,transparent)}.prx-form-tabs__tab-error-badge{display:inline-flex;align-items:center;justify-content:center;min-width:18px;height:18px;padding:0 5px;border-radius:999px;font-size:.7rem;font-weight:700;background:var(--md-sys-color-error, #ba1a1a);color:var(--md-sys-color-on-error, #ffffff);box-shadow:0 1px 2px #0003}.prx-form-tabs[data-appearance=underline]{border-bottom:1px solid var(--md-sys-color-outline-variant, #cac4d0)}.prx-form-tabs[data-appearance=underline] .prx-form-tabs__tablist{gap:16px;padding-bottom:0}.prx-form-tabs[data-appearance=underline] .prx-form-tabs__tab{border:none;border-radius:0;border-bottom:2px solid transparent;background:transparent;padding:8px 4px 10px;margin-bottom:-1px}.prx-form-tabs[data-appearance=underline] .prx-form-tabs__tab:hover:not(:disabled):not(.prx-form-tabs__tab--active){background:transparent;border-bottom-color:var(--md-sys-color-outline-variant, #cac4d0)}.prx-form-tabs[data-appearance=underline] .prx-form-tabs__tab--active{background:transparent;box-shadow:none;border-bottom-color:var(--md-sys-color-primary, #005ac1);color:var(--md-sys-color-primary, #005ac1)}.prx-form-tabs[data-appearance=buttons] .prx-form-tabs__tablist{background:var(--md-sys-color-surface-container, rgba(0, 0, 0, .04));border-radius:12px;padding:4px;gap:4px;border:1px solid var(--md-sys-color-outline-variant, rgba(0, 0, 0, .08))}.prx-form-tabs[data-appearance=buttons] .prx-form-tabs__tab{border:none;border-radius:8px;padding:6px 12px;background:transparent}.prx-form-tabs[data-appearance=buttons] .prx-form-tabs__tab:hover:not(:disabled):not(.prx-form-tabs__tab--active){background:color-mix(in srgb,currentColor 8%,transparent)}.prx-form-tabs[data-appearance=buttons] .prx-form-tabs__tab--active{background:var(--md-sys-color-surface, var(--mat-sys-surface));color:var(--md-sys-color-primary, #005ac1);box-shadow:0 1px 3px #0000001f}.section-drop-wrapper[hidden]{display:none!important}\n"] }]
|
|
21766
22001
|
}], ctorParameters: () => [{ type: i1.GenericCrudService }, { type: i2.HttpClient }, { type: i1$3.FormBuilder }, { type: i0.ChangeDetectorRef }, { type: FormLayoutService }, { type: FormContextService }, { type: FormRulesService }, { type: i7.SettingsPanelService }, { type: i2$1.MatDialog }, { type: undefined, decorators: [{
|
|
21767
22002
|
type: Inject,
|
|
21768
22003
|
args: [ASYNC_CONFIG_STORAGE]
|
|
@@ -23040,14 +23275,20 @@ class FieldConfiguratorComponent {
|
|
|
23040
23275
|
get icon() {
|
|
23041
23276
|
return this.resolveEditorialMeta()?.icon ?? 'text_fields';
|
|
23042
23277
|
}
|
|
23278
|
+
normalizedFieldControlType() {
|
|
23279
|
+
const raw = String(this.field?.controlType ?? '').trim();
|
|
23280
|
+
const normalized = resolveControlTypeAlias(normalizeControlTypeKey(raw) || raw);
|
|
23281
|
+
return (normalized || raw);
|
|
23282
|
+
}
|
|
23043
23283
|
get typeClass() {
|
|
23044
|
-
const
|
|
23284
|
+
const controlType = this.normalizedFieldControlType();
|
|
23285
|
+
const cat = this.categoryByType[controlType] ?? this.categoryByType[this.field?.controlType];
|
|
23045
23286
|
return cat ? `${cat}-type` : 'unknown-type';
|
|
23046
23287
|
}
|
|
23047
23288
|
get typeSpecificClass() {
|
|
23048
|
-
const
|
|
23289
|
+
const controlType = this.normalizedFieldControlType();
|
|
23049
23290
|
const map = this.typeSpecificClassMap;
|
|
23050
|
-
return map[
|
|
23291
|
+
return map[controlType] ?? map[this.field?.controlType] ?? '';
|
|
23051
23292
|
}
|
|
23052
23293
|
get typeLabel() {
|
|
23053
23294
|
return this.resolveEditorialMeta()?.friendlyName ?? String(this.field.controlType ?? '');
|
|
@@ -23121,7 +23362,7 @@ class FieldConfiguratorComponent {
|
|
|
23121
23362
|
}
|
|
23122
23363
|
</div>
|
|
23123
23364
|
</div>
|
|
23124
|
-
`, isInline: true, styles: [":host{--pdx-surface: var(--md-sys-color-surface);--pdx-surface-variant: var(--md-sys-color-surface-container);--pdx-outline: var(--md-sys-color-outline-variant);--pdx-cat-text: var(--md-sys-color-primary);--pdx-cat-select: var(--md-sys-color-secondary);--pdx-cat-number: var(--md-sys-color-tertiary);--pdx-cat-datetime: var(--md-sys-color-primary);--pdx-cat-boolean: var(--md-sys-color-secondary);--pdx-cat-slider: var(--md-sys-color-tertiary);--pdx-cat-file: var(--md-sys-color-primary);--pdx-cat-color: var(--md-sys-color-secondary);--pdx-cat-id: var(--md-sys-color-secondary)}.field-item{display:grid;grid-template-columns:24px 24px 1fr;grid-auto-rows:min-content;column-gap:6px;row-gap:2px;padding:6px 8px;border:1px solid var(--pdx-outline);border-radius:4px;background:var(--pdx-surface-variant);cursor:grab;border-left-width:4px;border-left-style:solid;border-left-color:var(--pdx-outline)}.field-item.cdk-drag-dragging{cursor:grabbing}.drag-handle,.field-icon{font-size:20px;line-height:1;width:24px;height:24px;display:inline-flex;align-items:center;justify-content:center;align-self:start;grid-row:1 / span 2}.drag-handle{cursor:grab;grid-column:1}.field-icon{grid-column:2}.field-item.cdk-drag-preview{box-sizing:border-box;box-shadow:var(--md-sys-elevation-level3);border-color:var(--md-sys-color-primary);background:var(--pdx-surface-variant);cursor:grabbing}.field-item.cdk-drag-placeholder{position:relative;min-height:42px;border-color:transparent;border-left-color:transparent;background:transparent;opacity:1}.field-item.cdk-drag-placeholder>*{visibility:hidden}.field-item.cdk-drag-placeholder:before{content:\"\";position:absolute;inset:calc(50% - 1px) 8px auto 8px;height:2px;border-radius:999px;background:var(--md-sys-color-primary);box-shadow:0 0 0 3px color-mix(in srgb,var(--md-sys-color-primary) 16%,transparent)}.field-item.cdk-drag-placeholder:after{content:\"\";position:absolute;top:calc(50% - 4px);left:8px;width:8px;height:8px;border-radius:50%;background:var(--md-sys-color-primary)}.field-texts{display:flex;flex-direction:column;grid-column:3;grid-row:1 / span 2;line-height:1.2}.field-label{line-height:24px}.field-type-label{font-size:12px;color:var(--md-sys-color-on-surface-variant)}.field-item.text-type{border-left-color:var(--pdx-cat-text)}.field-item.text-type .field-icon{color:var(--pdx-cat-text)}.field-item.date-type{border-left-color:var(--pdx-cat-datetime)}.field-item.date-type .field-icon{color:var(--pdx-cat-datetime)}.field-item.numeric-type{border-left-color:var(--pdx-cat-number)}.field-item.numeric-type .field-icon{color:var(--pdx-cat-number)}.field-item.select-type{border-left-color:var(--pdx-cat-select)}.field-item.select-type .field-icon{color:var(--pdx-cat-select)}.field-item.boolean-type{border-left-color:var(--pdx-cat-boolean)}.field-item.boolean-type .field-icon{color:var(--pdx-cat-boolean)}.field-item.slider-type{border-left-color:var(--pdx-cat-slider)}.field-item.slider-type .field-icon{color:var(--pdx-cat-slider)}.field-item.file-type{border-left-color:var(--pdx-cat-file)}.field-item.file-type .field-icon{color:var(--pdx-cat-file)}.field-item.color-type{border-left-color:var(--pdx-cat-color)}.field-item.color-type .field-icon{color:var(--pdx-cat-color)}.field-item.id-type{border-left-color:var(--pdx-cat-id)}.field-item.id-type .field-icon{color:var(--pdx-cat-id)}.field-item.unknown-type{border-left-color:var(--md-sys-color-outline)}.field-item.unknown-type .field-icon{color:var(--md-sys-color-outline)}.field-item.ft-input{border-left-color:var(--pdx-cat-text)}.field-item.ft-input .field-icon{color:var(--pdx-cat-text)}.field-item.ft-textarea{border-left-color:var(--pdx-cat-text)}.field-item.ft-textarea .field-icon{color:var(--pdx-cat-text)}.field-item.ft-email{border-left-color:var(--pdx-cat-select)}.field-item.ft-email .field-icon{color:var(--pdx-cat-select)}.field-item.ft-password{border-left-color:var(--pdx-cat-number)}.field-item.ft-password .field-icon{color:var(--pdx-cat-number)}.field-item.ft-url{border-left-color:var(--pdx-cat-text)}.field-item.ft-url .field-icon{color:var(--pdx-cat-text)}.field-item.ft-search{border-left-color:var(--pdx-cat-select)}.field-item.ft-search .field-icon{color:var(--pdx-cat-select)}.field-item.ft-phone{border-left-color:var(--pdx-cat-select)}.field-item.ft-phone .field-icon{color:var(--pdx-cat-select)}.field-item.ft-chip-input{border-left-color:var(--pdx-cat-select)}.field-item.ft-chip-input .field-icon{color:var(--pdx-cat-select)}.field-item.ft-numeric-text-box{border-left-color:var(--pdx-cat-number)}.field-item.ft-numeric-text-box .field-icon{color:var(--pdx-cat-number)}.field-item.ft-currency{border-left-color:var(--pdx-cat-number)}.field-item.ft-currency .field-icon{color:var(--pdx-cat-number)}.field-item.ft-year{border-left-color:var(--pdx-cat-number)}.field-item.ft-year .field-icon{color:var(--pdx-cat-number)}.field-item.ft-cpf-cnpj{border-left-color:var(--pdx-cat-id)}.field-item.ft-cpf-cnpj .field-icon{color:var(--pdx-cat-id)}.field-item.ft-select{border-left-color:var(--pdx-cat-select)}.field-item.ft-select .field-icon{color:var(--pdx-cat-select)}.field-item.ft-multi-select{border-left-color:var(--pdx-cat-select)}.field-item.ft-multi-select .field-icon{color:var(--pdx-cat-select)}.field-item.ft-auto-complete{border-left-color:var(--pdx-cat-select)}.field-item.ft-auto-complete .field-icon{color:var(--pdx-cat-select)}.field-item.ft-selection-list{border-left-color:var(--pdx-cat-select)}.field-item.ft-selection-list .field-icon{color:var(--pdx-cat-select)}.field-item.ft-tree-select{border-left-color:var(--pdx-cat-select)}.field-item.ft-tree-select .field-icon{color:var(--pdx-cat-select)}.field-item.ft-multi-select-tree{border-left-color:var(--pdx-cat-select)}.field-item.ft-multi-select-tree .field-icon{color:var(--pdx-cat-select)}.field-item.ft-transfer-list{border-left-color:var(--pdx-cat-text)}.field-item.ft-transfer-list .field-icon{color:var(--pdx-cat-text)}.field-item.ft-date-input{border-left-color:var(--pdx-cat-datetime)}.field-item.ft-date-input .field-icon{color:var(--pdx-cat-datetime)}.field-item.ft-date{border-left-color:var(--pdx-cat-datetime)}.field-item.ft-date .field-icon{color:var(--pdx-cat-datetime)}.field-item.ft-date-range{border-left-color:var(--pdx-cat-datetime)}.field-item.ft-date-range .field-icon{color:var(--pdx-cat-datetime)}.field-item.ft-date-time-local{border-left-color:var(--pdx-cat-datetime)}.field-item.ft-date-time-local .field-icon{color:var(--pdx-cat-datetime)}.field-item.ft-time{border-left-color:var(--pdx-cat-datetime)}.field-item.ft-time .field-icon{color:var(--pdx-cat-datetime)}.field-item.ft-time-picker{border-left-color:var(--pdx-cat-datetime)}.field-item.ft-time-picker .field-icon{color:var(--pdx-cat-datetime)}.field-item.ft-time-range{border-left-color:var(--pdx-cat-datetime)}.field-item.ft-time-range .field-icon{color:var(--pdx-cat-datetime)}.field-item.ft-month{border-left-color:var(--pdx-cat-select)}.field-item.ft-month .field-icon{color:var(--pdx-cat-select)}.field-item.ft-week{border-left-color:var(--pdx-cat-select)}.field-item.ft-week .field-icon{color:var(--pdx-cat-select)}.field-item.ft-checkbox{border-left-color:var(--pdx-cat-boolean)}.field-item.ft-checkbox .field-icon{color:var(--pdx-cat-boolean)}.field-item.ft-radio{border-left-color:var(--pdx-cat-boolean)}.field-item.ft-radio .field-icon{color:var(--pdx-cat-boolean)}.field-item.ft-toggle{border-left-color:var(--pdx-cat-boolean)}.field-item.ft-toggle .field-icon{color:var(--pdx-cat-boolean)}.field-item.ft-slider{border-left-color:var(--pdx-cat-slider)}.field-item.ft-slider .field-icon{color:var(--pdx-cat-slider)}.field-item.ft-range-slider{border-left-color:var(--pdx-cat-slider)}.field-item.ft-range-slider .field-icon{color:var(--pdx-cat-slider)}.field-item.ft-color{border-left-color:var(--pdx-cat-color)}.field-item.ft-color .field-icon{color:var(--pdx-cat-color)}.field-item.ft-color-picker{border-left-color:var(--pdx-cat-color)}.field-item.ft-color-picker .field-icon{color:var(--pdx-cat-color)}.field-item.ft-upload{border-left-color:var(--pdx-cat-file)}.field-item.ft-upload .field-icon{color:var(--pdx-cat-file)}\n"], dependencies: [{ kind: "ngmodule", type: CommonModule }, { kind: "directive", type: i1$2.NgClass, selector: "[ngClass]", inputs: ["class", "ngClass"] }, { kind: "ngmodule", type: DragDropModule }, { kind: "directive", type: i2$2.CdkDrag, selector: "[cdkDrag]", inputs: ["cdkDragData", "cdkDragLockAxis", "cdkDragRootElement", "cdkDragBoundary", "cdkDragStartDelay", "cdkDragFreeDragPosition", "cdkDragDisabled", "cdkDragConstrainPosition", "cdkDragPreviewClass", "cdkDragPreviewContainer", "cdkDragScale"], outputs: ["cdkDragStarted", "cdkDragReleased", "cdkDragEnded", "cdkDragEntered", "cdkDragExited", "cdkDragDropped", "cdkDragMoved"], exportAs: ["cdkDrag"] }, { kind: "directive", type: i2$2.CdkDragHandle, selector: "[cdkDragHandle]", inputs: ["cdkDragHandleDisabled"] }, { kind: "ngmodule", type: MatIconModule }, { kind: "component", type: i4.MatIcon, selector: "mat-icon", inputs: ["color", "inline", "svgIcon", "fontSet", "fontIcon"], exportAs: ["matIcon"] }, { kind: "ngmodule", type: MatTooltipModule }, { kind: "directive", type: i5.MatTooltip, selector: "[matTooltip]", inputs: ["matTooltipPosition", "matTooltipPositionAtOrigin", "matTooltipDisabled", "matTooltipShowDelay", "matTooltipHideDelay", "matTooltipTouchGestures", "matTooltip", "matTooltipClass"], exportAs: ["matTooltip"] }] });
|
|
23365
|
+
`, isInline: true, styles: [":host{--pdx-surface: var(--md-sys-color-surface);--pdx-surface-variant: var(--md-sys-color-surface-container);--pdx-outline: var(--md-sys-color-outline-variant);--pdx-cat-text: var(--md-sys-color-primary);--pdx-cat-select: color-mix(in srgb, var(--md-sys-color-primary) 72%, var(--md-sys-color-on-surface) 28%);--pdx-cat-number: color-mix(in srgb, var(--md-sys-color-tertiary, var(--md-sys-color-primary)) 78%, var(--md-sys-color-on-surface) 22%);--pdx-cat-datetime: color-mix(in srgb, var(--md-sys-color-primary) 84%, var(--md-sys-color-tertiary, var(--md-sys-color-on-surface)) 16%);--pdx-cat-boolean: color-mix(in srgb, var(--md-sys-color-primary) 64%, var(--md-sys-color-on-surface) 36%);--pdx-cat-slider: color-mix(in srgb, var(--md-sys-color-tertiary, var(--md-sys-color-primary)) 74%, var(--md-sys-color-on-surface) 26%);--pdx-cat-file: var(--md-sys-color-primary);--pdx-cat-color: color-mix(in srgb, var(--md-sys-color-tertiary, var(--md-sys-color-primary)) 68%, var(--md-sys-color-on-surface) 32%);--pdx-cat-id: color-mix(in srgb, var(--md-sys-color-primary) 68%, var(--md-sys-color-on-surface) 32%)}.field-item{display:grid;grid-template-columns:24px 24px 1fr;grid-auto-rows:min-content;column-gap:6px;row-gap:2px;padding:6px 8px;border:1px solid var(--pdx-outline);border-radius:4px;background:var(--pdx-surface-variant);cursor:grab;border-left-width:4px;border-left-style:solid;border-left-color:var(--pdx-outline)}.field-item.cdk-drag-dragging{cursor:grabbing}.drag-handle,.field-icon{font-size:20px;line-height:1;width:24px;height:24px;display:inline-flex;align-items:center;justify-content:center;align-self:start;grid-row:1 / span 2}.drag-handle{cursor:grab;grid-column:1;color:var(--md-sys-color-on-surface-variant)}.field-icon{grid-column:2;color:var(--md-sys-color-primary)}.field-item.cdk-drag-preview{box-sizing:border-box;box-shadow:var(--md-sys-elevation-level3);border-color:var(--md-sys-color-primary);background:var(--pdx-surface-variant);cursor:grabbing}.field-item.cdk-drag-placeholder{position:relative;min-height:42px;border-color:transparent;border-left-color:transparent;background:transparent;opacity:1}.field-item.cdk-drag-placeholder>*{visibility:hidden}.field-item.cdk-drag-placeholder:before{content:\"\";position:absolute;inset:calc(50% - 1px) 8px auto 8px;height:2px;border-radius:999px;background:var(--md-sys-color-primary);box-shadow:0 0 0 3px color-mix(in srgb,var(--md-sys-color-primary) 16%,transparent)}.field-item.cdk-drag-placeholder:after{content:\"\";position:absolute;top:calc(50% - 4px);left:8px;width:8px;height:8px;border-radius:50%;background:var(--md-sys-color-primary)}.field-texts{display:flex;flex-direction:column;grid-column:3;grid-row:1 / span 2;line-height:1.2}.field-label{line-height:24px}.field-type-label{font-size:12px;color:var(--md-sys-color-on-surface-variant)}.field-item.text-type{border-left-color:var(--pdx-cat-text)}.field-item.text-type .field-icon{color:var(--pdx-cat-text)}.field-item.date-type{border-left-color:var(--pdx-cat-datetime)}.field-item.date-type .field-icon{color:var(--pdx-cat-datetime)}.field-item.numeric-type,.field-item.number-type{border-left-color:var(--pdx-cat-number)}.field-item.numeric-type .field-icon,.field-item.number-type .field-icon{color:var(--pdx-cat-number)}.field-item.select-type{border-left-color:var(--pdx-cat-select)}.field-item.select-type .field-icon{color:var(--pdx-cat-select)}.field-item.boolean-type{border-left-color:var(--pdx-cat-boolean)}.field-item.boolean-type .field-icon{color:var(--pdx-cat-boolean)}.field-item.slider-type{border-left-color:var(--pdx-cat-slider)}.field-item.slider-type .field-icon{color:var(--pdx-cat-slider)}.field-item.file-type{border-left-color:var(--pdx-cat-file)}.field-item.file-type .field-icon{color:var(--pdx-cat-file)}.field-item.color-type{border-left-color:var(--pdx-cat-color)}.field-item.color-type .field-icon{color:var(--pdx-cat-color)}.field-item.id-type{border-left-color:var(--pdx-cat-id)}.field-item.id-type .field-icon{color:var(--pdx-cat-id)}.field-item.unknown-type{border-left-color:var(--md-sys-color-outline)}.field-item.unknown-type .field-icon{color:var(--md-sys-color-outline)}.field-item.ft-input{border-left-color:var(--pdx-cat-text)}.field-item.ft-input .field-icon{color:var(--pdx-cat-text)}.field-item.ft-textarea{border-left-color:var(--pdx-cat-text)}.field-item.ft-textarea .field-icon{color:var(--pdx-cat-text)}.field-item.ft-email{border-left-color:var(--pdx-cat-select)}.field-item.ft-email .field-icon{color:var(--pdx-cat-select)}.field-item.ft-password{border-left-color:var(--pdx-cat-number)}.field-item.ft-password .field-icon{color:var(--pdx-cat-number)}.field-item.ft-url{border-left-color:var(--pdx-cat-text)}.field-item.ft-url .field-icon{color:var(--pdx-cat-text)}.field-item.ft-search{border-left-color:var(--pdx-cat-select)}.field-item.ft-search .field-icon{color:var(--pdx-cat-select)}.field-item.ft-phone{border-left-color:var(--pdx-cat-select)}.field-item.ft-phone .field-icon{color:var(--pdx-cat-select)}.field-item.ft-chip-input{border-left-color:var(--pdx-cat-select)}.field-item.ft-chip-input .field-icon{color:var(--pdx-cat-select)}.field-item.ft-numeric-text-box{border-left-color:var(--pdx-cat-number)}.field-item.ft-numeric-text-box .field-icon{color:var(--pdx-cat-number)}.field-item.ft-currency{border-left-color:var(--pdx-cat-number)}.field-item.ft-currency .field-icon{color:var(--pdx-cat-number)}.field-item.ft-year{border-left-color:var(--pdx-cat-number)}.field-item.ft-year .field-icon{color:var(--pdx-cat-number)}.field-item.ft-cpf-cnpj{border-left-color:var(--pdx-cat-id)}.field-item.ft-cpf-cnpj .field-icon{color:var(--pdx-cat-id)}.field-item.ft-select{border-left-color:var(--pdx-cat-select)}.field-item.ft-select .field-icon{color:var(--pdx-cat-select)}.field-item.ft-multi-select{border-left-color:var(--pdx-cat-select)}.field-item.ft-multi-select .field-icon{color:var(--pdx-cat-select)}.field-item.ft-auto-complete{border-left-color:var(--pdx-cat-select)}.field-item.ft-auto-complete .field-icon{color:var(--pdx-cat-select)}.field-item.ft-selection-list{border-left-color:var(--pdx-cat-select)}.field-item.ft-selection-list .field-icon{color:var(--pdx-cat-select)}.field-item.ft-tree-select{border-left-color:var(--pdx-cat-select)}.field-item.ft-tree-select .field-icon{color:var(--pdx-cat-select)}.field-item.ft-multi-select-tree{border-left-color:var(--pdx-cat-select)}.field-item.ft-multi-select-tree .field-icon{color:var(--pdx-cat-select)}.field-item.ft-transfer-list{border-left-color:var(--pdx-cat-text)}.field-item.ft-transfer-list .field-icon{color:var(--pdx-cat-text)}.field-item.ft-date-input{border-left-color:var(--pdx-cat-datetime)}.field-item.ft-date-input .field-icon{color:var(--pdx-cat-datetime)}.field-item.ft-date{border-left-color:var(--pdx-cat-datetime)}.field-item.ft-date .field-icon{color:var(--pdx-cat-datetime)}.field-item.ft-date-range{border-left-color:var(--pdx-cat-datetime)}.field-item.ft-date-range .field-icon{color:var(--pdx-cat-datetime)}.field-item.ft-date-time-local{border-left-color:var(--pdx-cat-datetime)}.field-item.ft-date-time-local .field-icon{color:var(--pdx-cat-datetime)}.field-item.ft-time{border-left-color:var(--pdx-cat-datetime)}.field-item.ft-time .field-icon{color:var(--pdx-cat-datetime)}.field-item.ft-time-picker{border-left-color:var(--pdx-cat-datetime)}.field-item.ft-time-picker .field-icon{color:var(--pdx-cat-datetime)}.field-item.ft-time-range{border-left-color:var(--pdx-cat-datetime)}.field-item.ft-time-range .field-icon{color:var(--pdx-cat-datetime)}.field-item.ft-month{border-left-color:var(--pdx-cat-select)}.field-item.ft-month .field-icon{color:var(--pdx-cat-select)}.field-item.ft-week{border-left-color:var(--pdx-cat-select)}.field-item.ft-week .field-icon{color:var(--pdx-cat-select)}.field-item.ft-checkbox{border-left-color:var(--pdx-cat-boolean)}.field-item.ft-checkbox .field-icon{color:var(--pdx-cat-boolean)}.field-item.ft-radio{border-left-color:var(--pdx-cat-boolean)}.field-item.ft-radio .field-icon{color:var(--pdx-cat-boolean)}.field-item.ft-toggle{border-left-color:var(--pdx-cat-boolean)}.field-item.ft-toggle .field-icon{color:var(--pdx-cat-boolean)}.field-item.ft-slider{border-left-color:var(--pdx-cat-slider)}.field-item.ft-slider .field-icon{color:var(--pdx-cat-slider)}.field-item.ft-range-slider{border-left-color:var(--pdx-cat-slider)}.field-item.ft-range-slider .field-icon{color:var(--pdx-cat-slider)}.field-item.ft-color{border-left-color:var(--pdx-cat-color)}.field-item.ft-color .field-icon{color:var(--pdx-cat-color)}.field-item.ft-color-picker{border-left-color:var(--pdx-cat-color)}.field-item.ft-color-picker .field-icon{color:var(--pdx-cat-color)}.field-item.ft-upload{border-left-color:var(--pdx-cat-file)}.field-item.ft-upload .field-icon{color:var(--pdx-cat-file)}\n"], dependencies: [{ kind: "ngmodule", type: CommonModule }, { kind: "directive", type: i1$2.NgClass, selector: "[ngClass]", inputs: ["class", "ngClass"] }, { kind: "ngmodule", type: DragDropModule }, { kind: "directive", type: i2$2.CdkDrag, selector: "[cdkDrag]", inputs: ["cdkDragData", "cdkDragLockAxis", "cdkDragRootElement", "cdkDragBoundary", "cdkDragStartDelay", "cdkDragFreeDragPosition", "cdkDragDisabled", "cdkDragConstrainPosition", "cdkDragPreviewClass", "cdkDragPreviewContainer", "cdkDragScale"], outputs: ["cdkDragStarted", "cdkDragReleased", "cdkDragEnded", "cdkDragEntered", "cdkDragExited", "cdkDragDropped", "cdkDragMoved"], exportAs: ["cdkDrag"] }, { kind: "directive", type: i2$2.CdkDragHandle, selector: "[cdkDragHandle]", inputs: ["cdkDragHandleDisabled"] }, { kind: "ngmodule", type: MatIconModule }, { kind: "component", type: i4.MatIcon, selector: "mat-icon", inputs: ["color", "inline", "svgIcon", "fontSet", "fontIcon"], exportAs: ["matIcon"] }, { kind: "ngmodule", type: MatTooltipModule }, { kind: "directive", type: i5.MatTooltip, selector: "[matTooltip]", inputs: ["matTooltipPosition", "matTooltipPositionAtOrigin", "matTooltipDisabled", "matTooltipShowDelay", "matTooltipHideDelay", "matTooltipTouchGestures", "matTooltip", "matTooltipClass"], exportAs: ["matTooltip"] }] });
|
|
23125
23366
|
}
|
|
23126
23367
|
i0.ɵɵngDeclareClassMetadata({ minVersion: "12.0.0", version: "21.2.14", ngImport: i0, type: FieldConfiguratorComponent, decorators: [{
|
|
23127
23368
|
type: Component,
|
|
@@ -23143,7 +23384,7 @@ i0.ɵɵngDeclareClassMetadata({ minVersion: "12.0.0", version: "21.2.14", ngImpo
|
|
|
23143
23384
|
}
|
|
23144
23385
|
</div>
|
|
23145
23386
|
</div>
|
|
23146
|
-
`, styles: [":host{--pdx-surface: var(--md-sys-color-surface);--pdx-surface-variant: var(--md-sys-color-surface-container);--pdx-outline: var(--md-sys-color-outline-variant);--pdx-cat-text: var(--md-sys-color-primary);--pdx-cat-select: var(--md-sys-color-
|
|
23387
|
+
`, styles: [":host{--pdx-surface: var(--md-sys-color-surface);--pdx-surface-variant: var(--md-sys-color-surface-container);--pdx-outline: var(--md-sys-color-outline-variant);--pdx-cat-text: var(--md-sys-color-primary);--pdx-cat-select: color-mix(in srgb, var(--md-sys-color-primary) 72%, var(--md-sys-color-on-surface) 28%);--pdx-cat-number: color-mix(in srgb, var(--md-sys-color-tertiary, var(--md-sys-color-primary)) 78%, var(--md-sys-color-on-surface) 22%);--pdx-cat-datetime: color-mix(in srgb, var(--md-sys-color-primary) 84%, var(--md-sys-color-tertiary, var(--md-sys-color-on-surface)) 16%);--pdx-cat-boolean: color-mix(in srgb, var(--md-sys-color-primary) 64%, var(--md-sys-color-on-surface) 36%);--pdx-cat-slider: color-mix(in srgb, var(--md-sys-color-tertiary, var(--md-sys-color-primary)) 74%, var(--md-sys-color-on-surface) 26%);--pdx-cat-file: var(--md-sys-color-primary);--pdx-cat-color: color-mix(in srgb, var(--md-sys-color-tertiary, var(--md-sys-color-primary)) 68%, var(--md-sys-color-on-surface) 32%);--pdx-cat-id: color-mix(in srgb, var(--md-sys-color-primary) 68%, var(--md-sys-color-on-surface) 32%)}.field-item{display:grid;grid-template-columns:24px 24px 1fr;grid-auto-rows:min-content;column-gap:6px;row-gap:2px;padding:6px 8px;border:1px solid var(--pdx-outline);border-radius:4px;background:var(--pdx-surface-variant);cursor:grab;border-left-width:4px;border-left-style:solid;border-left-color:var(--pdx-outline)}.field-item.cdk-drag-dragging{cursor:grabbing}.drag-handle,.field-icon{font-size:20px;line-height:1;width:24px;height:24px;display:inline-flex;align-items:center;justify-content:center;align-self:start;grid-row:1 / span 2}.drag-handle{cursor:grab;grid-column:1;color:var(--md-sys-color-on-surface-variant)}.field-icon{grid-column:2;color:var(--md-sys-color-primary)}.field-item.cdk-drag-preview{box-sizing:border-box;box-shadow:var(--md-sys-elevation-level3);border-color:var(--md-sys-color-primary);background:var(--pdx-surface-variant);cursor:grabbing}.field-item.cdk-drag-placeholder{position:relative;min-height:42px;border-color:transparent;border-left-color:transparent;background:transparent;opacity:1}.field-item.cdk-drag-placeholder>*{visibility:hidden}.field-item.cdk-drag-placeholder:before{content:\"\";position:absolute;inset:calc(50% - 1px) 8px auto 8px;height:2px;border-radius:999px;background:var(--md-sys-color-primary);box-shadow:0 0 0 3px color-mix(in srgb,var(--md-sys-color-primary) 16%,transparent)}.field-item.cdk-drag-placeholder:after{content:\"\";position:absolute;top:calc(50% - 4px);left:8px;width:8px;height:8px;border-radius:50%;background:var(--md-sys-color-primary)}.field-texts{display:flex;flex-direction:column;grid-column:3;grid-row:1 / span 2;line-height:1.2}.field-label{line-height:24px}.field-type-label{font-size:12px;color:var(--md-sys-color-on-surface-variant)}.field-item.text-type{border-left-color:var(--pdx-cat-text)}.field-item.text-type .field-icon{color:var(--pdx-cat-text)}.field-item.date-type{border-left-color:var(--pdx-cat-datetime)}.field-item.date-type .field-icon{color:var(--pdx-cat-datetime)}.field-item.numeric-type,.field-item.number-type{border-left-color:var(--pdx-cat-number)}.field-item.numeric-type .field-icon,.field-item.number-type .field-icon{color:var(--pdx-cat-number)}.field-item.select-type{border-left-color:var(--pdx-cat-select)}.field-item.select-type .field-icon{color:var(--pdx-cat-select)}.field-item.boolean-type{border-left-color:var(--pdx-cat-boolean)}.field-item.boolean-type .field-icon{color:var(--pdx-cat-boolean)}.field-item.slider-type{border-left-color:var(--pdx-cat-slider)}.field-item.slider-type .field-icon{color:var(--pdx-cat-slider)}.field-item.file-type{border-left-color:var(--pdx-cat-file)}.field-item.file-type .field-icon{color:var(--pdx-cat-file)}.field-item.color-type{border-left-color:var(--pdx-cat-color)}.field-item.color-type .field-icon{color:var(--pdx-cat-color)}.field-item.id-type{border-left-color:var(--pdx-cat-id)}.field-item.id-type .field-icon{color:var(--pdx-cat-id)}.field-item.unknown-type{border-left-color:var(--md-sys-color-outline)}.field-item.unknown-type .field-icon{color:var(--md-sys-color-outline)}.field-item.ft-input{border-left-color:var(--pdx-cat-text)}.field-item.ft-input .field-icon{color:var(--pdx-cat-text)}.field-item.ft-textarea{border-left-color:var(--pdx-cat-text)}.field-item.ft-textarea .field-icon{color:var(--pdx-cat-text)}.field-item.ft-email{border-left-color:var(--pdx-cat-select)}.field-item.ft-email .field-icon{color:var(--pdx-cat-select)}.field-item.ft-password{border-left-color:var(--pdx-cat-number)}.field-item.ft-password .field-icon{color:var(--pdx-cat-number)}.field-item.ft-url{border-left-color:var(--pdx-cat-text)}.field-item.ft-url .field-icon{color:var(--pdx-cat-text)}.field-item.ft-search{border-left-color:var(--pdx-cat-select)}.field-item.ft-search .field-icon{color:var(--pdx-cat-select)}.field-item.ft-phone{border-left-color:var(--pdx-cat-select)}.field-item.ft-phone .field-icon{color:var(--pdx-cat-select)}.field-item.ft-chip-input{border-left-color:var(--pdx-cat-select)}.field-item.ft-chip-input .field-icon{color:var(--pdx-cat-select)}.field-item.ft-numeric-text-box{border-left-color:var(--pdx-cat-number)}.field-item.ft-numeric-text-box .field-icon{color:var(--pdx-cat-number)}.field-item.ft-currency{border-left-color:var(--pdx-cat-number)}.field-item.ft-currency .field-icon{color:var(--pdx-cat-number)}.field-item.ft-year{border-left-color:var(--pdx-cat-number)}.field-item.ft-year .field-icon{color:var(--pdx-cat-number)}.field-item.ft-cpf-cnpj{border-left-color:var(--pdx-cat-id)}.field-item.ft-cpf-cnpj .field-icon{color:var(--pdx-cat-id)}.field-item.ft-select{border-left-color:var(--pdx-cat-select)}.field-item.ft-select .field-icon{color:var(--pdx-cat-select)}.field-item.ft-multi-select{border-left-color:var(--pdx-cat-select)}.field-item.ft-multi-select .field-icon{color:var(--pdx-cat-select)}.field-item.ft-auto-complete{border-left-color:var(--pdx-cat-select)}.field-item.ft-auto-complete .field-icon{color:var(--pdx-cat-select)}.field-item.ft-selection-list{border-left-color:var(--pdx-cat-select)}.field-item.ft-selection-list .field-icon{color:var(--pdx-cat-select)}.field-item.ft-tree-select{border-left-color:var(--pdx-cat-select)}.field-item.ft-tree-select .field-icon{color:var(--pdx-cat-select)}.field-item.ft-multi-select-tree{border-left-color:var(--pdx-cat-select)}.field-item.ft-multi-select-tree .field-icon{color:var(--pdx-cat-select)}.field-item.ft-transfer-list{border-left-color:var(--pdx-cat-text)}.field-item.ft-transfer-list .field-icon{color:var(--pdx-cat-text)}.field-item.ft-date-input{border-left-color:var(--pdx-cat-datetime)}.field-item.ft-date-input .field-icon{color:var(--pdx-cat-datetime)}.field-item.ft-date{border-left-color:var(--pdx-cat-datetime)}.field-item.ft-date .field-icon{color:var(--pdx-cat-datetime)}.field-item.ft-date-range{border-left-color:var(--pdx-cat-datetime)}.field-item.ft-date-range .field-icon{color:var(--pdx-cat-datetime)}.field-item.ft-date-time-local{border-left-color:var(--pdx-cat-datetime)}.field-item.ft-date-time-local .field-icon{color:var(--pdx-cat-datetime)}.field-item.ft-time{border-left-color:var(--pdx-cat-datetime)}.field-item.ft-time .field-icon{color:var(--pdx-cat-datetime)}.field-item.ft-time-picker{border-left-color:var(--pdx-cat-datetime)}.field-item.ft-time-picker .field-icon{color:var(--pdx-cat-datetime)}.field-item.ft-time-range{border-left-color:var(--pdx-cat-datetime)}.field-item.ft-time-range .field-icon{color:var(--pdx-cat-datetime)}.field-item.ft-month{border-left-color:var(--pdx-cat-select)}.field-item.ft-month .field-icon{color:var(--pdx-cat-select)}.field-item.ft-week{border-left-color:var(--pdx-cat-select)}.field-item.ft-week .field-icon{color:var(--pdx-cat-select)}.field-item.ft-checkbox{border-left-color:var(--pdx-cat-boolean)}.field-item.ft-checkbox .field-icon{color:var(--pdx-cat-boolean)}.field-item.ft-radio{border-left-color:var(--pdx-cat-boolean)}.field-item.ft-radio .field-icon{color:var(--pdx-cat-boolean)}.field-item.ft-toggle{border-left-color:var(--pdx-cat-boolean)}.field-item.ft-toggle .field-icon{color:var(--pdx-cat-boolean)}.field-item.ft-slider{border-left-color:var(--pdx-cat-slider)}.field-item.ft-slider .field-icon{color:var(--pdx-cat-slider)}.field-item.ft-range-slider{border-left-color:var(--pdx-cat-slider)}.field-item.ft-range-slider .field-icon{color:var(--pdx-cat-slider)}.field-item.ft-color{border-left-color:var(--pdx-cat-color)}.field-item.ft-color .field-icon{color:var(--pdx-cat-color)}.field-item.ft-color-picker{border-left-color:var(--pdx-cat-color)}.field-item.ft-color-picker .field-icon{color:var(--pdx-cat-color)}.field-item.ft-upload{border-left-color:var(--pdx-cat-file)}.field-item.ft-upload .field-icon{color:var(--pdx-cat-file)}\n"] }]
|
|
23147
23388
|
}], propDecorators: { field: [{
|
|
23148
23389
|
type: Input
|
|
23149
23390
|
}] } });
|
|
@@ -24637,7 +24878,7 @@ class SectionConfiguratorComponent {
|
|
|
24637
24878
|
this.applyStyleToAll.emit(patch);
|
|
24638
24879
|
}
|
|
24639
24880
|
static ɵfac = i0.ɵɵngDeclareFactory({ minVersion: "12.0.0", version: "21.2.14", ngImport: i0, type: SectionConfiguratorComponent, deps: [{ token: i2$1.MatDialog }, { token: SectionPresetRegistry }, { token: i7.SettingsPanelService }], target: i0.ɵɵFactoryTarget.Component });
|
|
24640
|
-
static ɵcmp = i0.ɵɵngDeclareComponent({ minVersion: "17.0.0", version: "21.2.14", type: SectionConfiguratorComponent, isStandalone: true, selector: "praxis-section-configurator", inputs: { section: "section", sectionIndex: "sectionIndex", allSections: "allSections", fieldMetadata: "fieldMetadata", availableFields: "availableFields", selected: "selected", availableFieldsListId: "availableFieldsListId", columnDropListIds: "columnDropListIds", gapGlobal: "gapGlobal" }, outputs: { sectionChange: "sectionChange", applyStyleToAll: "applyStyleToAll", remove: "remove", select: "select", fieldDrop: "fieldDrop", addVisualBlock: "addVisualBlock", addApiField: "addApiField", addLocalField: "addLocalField", requestMoveField: "requestMoveField", editField: "editField", editVisualBlock: "editVisualBlock", moveVisualBlock: "moveVisualBlock", moveVisualBlockToColumn: "moveVisualBlockToColumn", removeVisualBlock: "removeVisualBlock" }, providers: [providePraxisI18nConfig(LAYOUT_EDITOR_I18N_CONFIG)], ngImport: i0, template: "<mat-card\n class=\"section-card\"\n cdkDrag\n (mouseenter)=\"onMouseEnter()\"\n (mouseleave)=\"onMouseLeave()\"\n [class.hovered]=\"isHovered\"\n [class.selected]=\"isThisSectionSelected()\"\n [class.collapsed]=\"isCollapsed\"\n (click)=\"onSelectSection()\"\n tabindex=\"0\"\n role=\"button\"\n [attr.aria-label]=\"'Se\u00E7\u00E3o ' + (sectionIndex + 1)\"\n [attr.aria-selected]=\"isThisSectionSelected()\"\n >\n <mat-card-header class=\"section-header\">\n <mat-card-title class=\"title-wrapper\">\n <div class=\"section-heading\">\n @let headerPreview = getSectionHeaderPreview();\n @let headerAvatarSize = getSectionHeaderAvatarSize();\n @if (headerPreview.kind === 'icon') {\n <mat-icon class=\"section-heading__icon\" aria-hidden=\"true\" [praxisIcon]=\"headerPreview.icon\"></mat-icon>\n }\n @if (headerPreview.kind === 'initials') {\n <span class=\"section-heading__avatar section-heading__avatar--text\" [class.size-sm]=\"headerAvatarSize === 'sm'\"\n [class.size-md]=\"headerAvatarSize === 'md'\" [class.size-lg]=\"headerAvatarSize === 'lg'\"\n [matTooltip]=\"headerPreview.tooltip || ''\" [matTooltipDisabled]=\"!headerPreview.tooltip\">\n {{ headerPreview.text }}\n </span>\n }\n @if (headerPreview.kind === 'placeholder') {\n <span class=\"section-heading__avatar section-heading__avatar--placeholder\" [class.size-sm]=\"headerAvatarSize === 'sm'\"\n [class.size-md]=\"headerAvatarSize === 'md'\" [class.size-lg]=\"headerAvatarSize === 'lg'\"\n [matTooltip]=\"headerPreview.tooltip || ''\" [matTooltipDisabled]=\"!headerPreview.tooltip\">\n @if (headerPreview.icon) {\n <mat-icon aria-hidden=\"true\" [praxisIcon]=\"headerPreview.icon\"></mat-icon>\n }\n </span>\n }\n <div class=\"section-heading__text\">\n <span class=\"section-name\">{{ section.title || 'Sem t\u00EDtulo' }}</span>\n @if (section.description) {\n <span class=\"section-desc\">{{ section.description }}</span>\n }\n </div>\n </div>\n <button praxisIconButton=\"edit\" size=\"dense\" type=\"button\"\n data-testid=\"section-rename-trigger\" (click)=\"startRename($event)\"\n [matTooltip]=\"t('section.rename.action')\" [attr.aria-label]=\"t('section.rename.action')\">\n </button>\n <button\n praxisIconButton=\"open_in_new\"\n size=\"dense\"\n type=\"button\"\n class=\"section-editor-trigger primary-action\"\n (click)=\"openAdvancedEditor($event)\"\n [matTooltip]=\"t('section.editor.hint')\"\n aria-label=\"Abrir editor da se\u00E7\u00E3o\"\n >\n </button>\n </mat-card-title>\n <div class=\"section-header-actions\">\n <button\n [praxisIconButton]=\"isCollapsed ? 'unfold_more' : 'unfold_less'\"\n size=\"dense\"\n class=\"section-collapse-btn\"\n type=\"button\"\n (click)=\"toggleCollapsed($event)\"\n [attr.aria-expanded]=\"!isCollapsed\"\n [attr.aria-label]=\"isCollapsed ? 'Expandir se\u00E7\u00E3o' : 'Colapsar se\u00E7\u00E3o'\"\n [matTooltip]=\"isCollapsed ? 'Expandir se\u00E7\u00E3o' : 'Colapsar se\u00E7\u00E3o'\"\n >\n </button>\n <button\n praxisIconButton=\"more_vert\"\n size=\"dense\"\n class=\"section-menu-btn\"\n [matMenuTriggerFor]=\"sectionMenu\"\n aria-label=\"Mais a\u00E7\u00F5es da se\u00E7\u00E3o\"\n matTooltip=\"Mais a\u00E7\u00F5es\"\n >\n </button>\n </div>\n <mat-menu #sectionMenu=\"matMenu\">\n <button mat-menu-item (click)=\"openSectionPresets()\">\n <mat-icon [praxisIcon]=\"'view_quilt'\"></mat-icon>\n <span>Presets de se\u00E7\u00E3o\u2026</span>\n </button>\n <button mat-menu-item (click)=\"applyCurrentStyleToAll()\">\n <mat-icon [praxisIcon]=\"'format_paint'\"></mat-icon>\n <span>Aplicar estilo desta se\u00E7\u00E3o a todas</span>\n </button>\n <mat-divider></mat-divider>\n @if (section.description == null) {\n <button mat-menu-item (click)=\"section.description = ''; onSectionUpdated()\">\n <mat-icon [praxisIcon]=\"'note_add'\"></mat-icon>\n <span>Adicionar descri\u00E7\u00E3o</span>\n </button>\n }\n @if (section.description != null) {\n <button mat-menu-item (click)=\"section.description = undefined; onSectionUpdated()\">\n <mat-icon [praxisIcon]=\"'backspace'\"></mat-icon>\n <span>Remover descri\u00E7\u00E3o</span>\n </button>\n }\n <mat-divider></mat-divider>\n <button mat-menu-item (click)=\"onRemoveSection()\">\n <mat-icon [praxisIcon]=\"'delete'\"></mat-icon>\n <span>Remover se\u00E7\u00E3o</span>\n </button>\n </mat-menu>\n </mat-card-header>\n <mat-card-content [attr.aria-hidden]=\"isCollapsed\">\n @if (renameDraft() !== null) {\n <div class=\"section-rename-controls\" role=\"group\" [attr.aria-label]=\"t('section.rename.action')\" (click)=\"$event.stopPropagation()\">\n <mat-form-field subscriptSizing=\"dynamic\">\n <mat-label>{{ t('section.rename.title') }}</mat-label>\n <input matInput data-testid=\"section-rename-input\" required\n [ngModel]=\"renameDraft()\" (ngModelChange)=\"renameDraft.set($event)\"\n (keydown.enter)=\"finishRename($event, true)\" (keydown.escape)=\"finishRename($event, false)\" />\n <mat-error>{{ t('section.rename.required') }}</mat-error>\n @if (renameDraft()?.length && !renameDraft()?.trim()) {\n <mat-hint>{{ t('section.rename.required') }}</mat-hint>\n }\n </mat-form-field>\n <button mat-stroked-button type=\"button\" [disabled]=\"!renameDraft()?.trim()\" (click)=\"finishRename($event, true)\">{{ t('section.rename.save') }}</button>\n <button mat-button type=\"button\" (click)=\"finishRename($event, false)\">{{ t('field.move.cancel') }}</button>\n </div>\n }\n @if (!section.rows.length) {\n <p class=\"section-empty-guidance\">{{ t('section.empty.guidance') }}</p>\n }\n @if (isThisSectionSelected()) {\n <div class=\"selection-context\" (click)=\"$event.stopPropagation()\" role=\"region\" [attr.aria-label]=\"t('selection.context')\">\n <nav class=\"section-breadcrumbs\" [attr.aria-label]=\"t('selection.path')\">\n <button\n type=\"button\"\n class=\"crumb as-button crumb-section\"\n data-crumb=\"section\"\n (click)=\"onSelectSectionFromBreadcrumb($event)\"\n [attr.aria-label]=\"section.title || t('selection.section', { index: sectionIndex + 1 })\"\n >\n {{ section.title || t('selection.section', { index: sectionIndex + 1 }) }}\n </button>\n @if (selected?.rowIndex != null) {\n <span class=\"sep\">\u203A</span>\n <button\n type=\"button\"\n class=\"crumb as-button crumb-row\"\n data-crumb=\"row\"\n (click)=\"onSelectRowFromBreadcrumb($event)\"\n [attr.aria-label]=\"t('selection.row', { index: selected!.rowIndex! + 1 })\"\n >\n {{ t('selection.row', { index: selected!.rowIndex! + 1 }) }}\n </button>\n }\n @if (selected?.columnIndex != null) {\n <span class=\"sep\">\u203A</span>\n <button\n type=\"button\"\n class=\"crumb as-button crumb-column\"\n data-crumb=\"column\"\n (click)=\"onSelectColumnFromBreadcrumb($event)\"\n [attr.aria-label]=\"t('selection.column', { index: selected!.columnIndex! + 1 })\"\n >\n {{ t('selection.column', { index: selected!.columnIndex! + 1 }) }}\n </button>\n }\n @if (selected?.fieldName) {\n <span class=\"sep\">\u203A</span>\n <span class=\"crumb active\">{{ selectedFieldLabel }}</span>\n }\n @if (selected) {\n <button\n type=\"button\"\n class=\"crumb as-button crumb-clear\"\n data-crumb=\"clear\"\n (click)=\"onClearSelectionFromBreadcrumb($event)\"\n [attr.aria-label]=\"t('selection.clear')\"\n >\n {{ t('selection.clear') }}\n </button>\n }\n </nav>\n <div class=\"selection-actions\">\n @if (selectedField) {\n <button mat-stroked-button type=\"button\" (click)=\"requestSelectedFieldMove($event)\">\n <mat-icon aria-hidden=\"true\">drive_file_move</mat-icon>{{ t('field.move.action') }}\n </button>\n <button mat-stroked-button type=\"button\" data-testid=\"layout-edit-selected-field\" (click)=\"editSelectedField($event)\">\n <mat-icon aria-hidden=\"true\">edit</mat-icon>{{ t('selection.editField') }}\n </button>\n }\n @if (selectedColumn) {\n <button mat-stroked-button type=\"button\" data-testid=\"layout-edit-selected-column\" (click)=\"editSelectedColumn($event)\">\n <mat-icon aria-hidden=\"true\">view_column</mat-icon>{{ t('selection.editColumn') }}\n </button>\n }\n </div>\n </div>\n } @else {\n <h5>Linhas</h5>\n }\n <div\n class=\"row-list\"\n cdkDropList\n [cdkDropListData]=\"section.rows\"\n (cdkDropListDropped)=\"dropRow($event)\"\n >\n @for (row of section.rows; track row; let i = $index) {\n <praxis-row-configurator\n class=\"row-item\"\n [row]=\"row\"\n [fieldMetadata]=\"fieldMetadata\"\n [availableFields]=\"availableFields\"\n [sectionIndex]=\"sectionIndex\"\n [rowIndex]=\"i\"\n [isLastRow]=\"i === section.rows.length - 1\"\n [selected]=\"selected\"\n [availableFieldsListId]=\"availableFieldsListId\"\n [connectedDropListIds]=\"columnDropListIds\"\n [gapGlobal]=\"gapGlobal\"\n (rowChange)=\"onRowUpdated(i, $event)\"\n (applyRowGapAll)=\"onApplyRowGapAll($event)\"\n (remove)=\"removeRow(i)\"\n (select)=\"select.emit($event)\"\n (fieldDrop)=\"onFieldDrop($event, i)\"\n (addVisualBlock)=\"onAddVisualBlock($event)\"\n (addApiField)=\"onAddApiField($event)\"\n (addLocalField)=\"onAddLocalField($event)\"\n (editField)=\"onEditField($event)\"\n (editVisualBlock)=\"onEditVisualBlock($event)\"\n (moveVisualBlock)=\"onMoveVisualBlock($event)\"\n (moveVisualBlockToColumn)=\"onMoveVisualBlockToColumn($event)\"\n (removeVisualBlock)=\"onRemoveVisualBlock($event)\"\n cdkDrag\n ></praxis-row-configurator>\n }\n </div>\n <div class=\"section-actions\" aria-label=\"A\u00E7\u00F5es da se\u00E7\u00E3o\">\n @if (!section.rows.length) {\n <button mat-stroked-button type=\"button\" (click)=\"addRow()\">\n <mat-icon aria-hidden=\"true\">add</mat-icon>{{ t('section.empty.addRow') }}\n </button>\n } @else {\n <button\n class=\"fab-add-row\"\n mat-fab\n color=\"primary\"\n (click)=\"addRow()\"\n matTooltip=\"Adicionar linha\"\n aria-label=\"Adicionar linha\"\n >\n <mat-icon>add</mat-icon>\n </button>\n }\n </div>\n </mat-card-content>\n</mat-card>\n", styles: ["@charset \"UTF-8\";.section-card{background:var(--md-sys-color-surface, var(--sicoob-bg-elev-1));margin-bottom:16px;transition:border-color .2s ease;border:1px solid transparent;box-sizing:border-box;max-width:100%;min-width:0}.section-card.hovered{border-color:var(--md-sys-color-primary, var(--md-sys-color-primary, var(--sicoob-primary-default)))}.section-card.selected{border-color:var(--md-sys-color-primary, var(--md-sys-color-primary, var(--sicoob-primary-default)));box-shadow:0 0 0 2px var(--md-sys-color-primary)}.section-card.cdk-drag-dragging{cursor:grabbing}.section-card.cdk-drag-preview{box-sizing:border-box;border-color:var(--md-sys-color-primary, var(--sicoob-primary-default));box-shadow:var(--md-sys-elevation-level3);cursor:grabbing}.section-card.cdk-drag-placeholder{position:relative;min-height:64px;border-color:transparent;background:transparent;box-shadow:none;opacity:1}.section-card.cdk-drag-placeholder>*{visibility:hidden}.section-card.cdk-drag-placeholder:before{content:\"\";position:absolute;inset:calc(50% - 1px) 12px auto 12px;height:2px;border-radius:999px;background:var(--md-sys-color-primary, var(--sicoob-primary-default));box-shadow:0 0 0 3px color-mix(in srgb,var(--md-sys-color-primary, var(--sicoob-primary-default)) 16%,transparent)}.section-card.cdk-drag-placeholder:after{content:\"\";position:absolute;top:calc(50% - 5px);left:12px;width:10px;height:10px;border-radius:50%;background:var(--md-sys-color-primary, var(--sicoob-primary-default))}.section-card:focus-visible{outline:2px solid var(--md-sys-color-primary, var(--md-sys-color-primary, var(--sicoob-primary-default)));outline-offset:2px}.section-card .mat-mdc-card-content{padding-bottom:var(--px-editor-section-gap, 16px)}.section-breadcrumbs{font-size:12px;color:var(--md-sys-color-on-surface-variant);margin:4px 0 8px;display:flex;align-items:center;gap:6px}.section-breadcrumbs .as-button{background:transparent;border:none;padding:0 2px;color:inherit;font:inherit;cursor:pointer;border-radius:4px}.section-breadcrumbs .as-button:hover{color:var(--md-sys-color-primary, var(--md-sys-color-primary, var(--sicoob-primary-default)))}.section-breadcrumbs .as-button:focus-visible{outline:2px solid var(--md-sys-color-primary, var(--md-sys-color-primary, var(--sicoob-primary-default)));outline-offset:2px}.section-breadcrumbs .crumb-clear{margin-left:6px;opacity:.85}.section-breadcrumbs .crumb.active{color:var(--md-sys-color-on-surface);font-weight:600}.section-breadcrumbs .sep{opacity:.6}.section-header{display:flex;justify-content:space-between;align-items:center;gap:12px;min-height:56px;min-width:0}.title-wrapper{display:flex;align-items:center;gap:8px;width:100%;min-width:0;flex:1 1 auto}.section-heading{display:flex;align-items:center;gap:10px;min-width:0}.section-heading__icon{color:var(--md-sys-color-primary, var(--md-sys-color-primary, var(--sicoob-primary-default)))}.section-heading__avatar{--_pfx-layout-section-avatar-size: var(--pfx-form-section-avatar-size-md, var(--pfx-form-section-avatar-size, 32px));display:inline-flex;align-items:center;justify-content:center;width:var(--_pfx-layout-section-avatar-size);height:var(--_pfx-layout-section-avatar-size);border-radius:999px;flex:0 0 var(--_pfx-layout-section-avatar-size);overflow:hidden}.section-heading__avatar.size-sm{--_pfx-layout-section-avatar-size: var(--pfx-form-section-avatar-size-sm, 24px)}.section-heading__avatar.size-md{--_pfx-layout-section-avatar-size: var(--pfx-form-section-avatar-size-md, var(--pfx-form-section-avatar-size, 32px))}.section-heading__avatar.size-lg{--_pfx-layout-section-avatar-size: var(--pfx-form-section-avatar-size-lg, 40px)}.section-heading__avatar--text,.section-heading__avatar--placeholder{background:color-mix(in srgb,var(--pfx-editorial-form-accent, var(--md-sys-color-primary, var(--sicoob-primary-default))) 14%,var(--pfx-form-section-surface-flat, var(--md-sys-color-surface, var(--sicoob-bg-elev-1))));color:color-mix(in srgb,var(--pfx-editorial-form-accent, var(--md-sys-color-primary, var(--sicoob-primary-default))) 82%,var(--pfx-form-label-strong, var(--md-sys-color-on-surface, var(--sicoob-text-default))) 18%);font-size:calc(var(--_pfx-layout-section-avatar-size) * .41);font-weight:800;letter-spacing:.04em;text-transform:uppercase}.section-heading__avatar--placeholder mat-icon{font-size:calc(var(--_pfx-layout-section-avatar-size) * .5625);width:calc(var(--_pfx-layout-section-avatar-size) * .5625);height:calc(var(--_pfx-layout-section-avatar-size) * .5625);line-height:calc(var(--_pfx-layout-section-avatar-size) * .5625)}.section-heading__text{display:flex;flex-direction:column;align-items:flex-start;min-width:0}.section-heading .section-name{font-weight:600;color:var(--md-sys-color-on-surface);overflow:hidden;text-overflow:ellipsis;white-space:nowrap}.section-heading .section-desc{font-size:12px;color:var(--md-sys-color-on-surface-variant);margin-top:2px;overflow:hidden;text-overflow:ellipsis;white-space:nowrap}.section-editor-trigger{margin-left:auto}.section-editor-trigger.primary-action{color:var(--md-sys-color-primary)}.section-header-actions{display:inline-flex;align-items:center;gap:4px;flex-shrink:0}.add-row-button{margin-top:8px}.row-item{animation:fadeIn .3s ease}.row-item.cdk-drag-dragging{cursor:grabbing}.row-item.cdk-drag-preview{box-sizing:border-box;border-radius:8px;background:var(--md-sys-color-surface-container, var(--md-sys-color-surface));box-shadow:var(--md-sys-elevation-level3);cursor:grabbing}.row-item.cdk-drag-placeholder{position:relative;display:block;min-height:56px;opacity:1}.row-item.cdk-drag-placeholder>*{visibility:hidden}.row-item.cdk-drag-placeholder:before{content:\"\";position:absolute;inset:calc(50% - 1px) 8px auto 8px;height:2px;border-radius:999px;background:var(--md-sys-color-primary, var(--sicoob-primary-default));box-shadow:0 0 0 3px color-mix(in srgb,var(--md-sys-color-primary, var(--sicoob-primary-default)) 16%,transparent)}.row-item.cdk-drag-placeholder:after{content:\"\";position:absolute;top:calc(50% - 4px);left:8px;width:8px;height:8px;border-radius:50%;background:var(--md-sys-color-primary, var(--sicoob-primary-default))}@keyframes fadeIn{0%{opacity:0;transform:translateY(-4px)}to{opacity:1;transform:none}}.section-card:hover{border-color:var(--md-sys-color-primary, var(--md-sys-color-primary, var(--sicoob-primary-default)))}.section-card.collapsed .mat-mdc-card-content{display:none}:host ::ng-deep .section-card .mat-mdc-card-header{padding:8px 12px}:host ::ng-deep .section-card .mat-mdc-card-title{margin:0}:host ::ng-deep .section-card .mat-mdc-card-content{padding:0 12px 12px}.section-actions{position:relative;margin-top:12px;padding-top:16px;border-top:1px solid var(--md-sys-color-outline-variant, var(--md-sys-color-outline-variant, var(--sicoob-stroke-medium)));min-height:28px}.row-list{border-top:1px solid var(--px-editor-separator-color, var(--md-sys-color-outline-variant));padding-top:12px;margin-top:8px;min-width:0}.fab-add-row{position:absolute;top:-15px;left:50%;transform:translate(-50%,calc(-50% - var(--pfx-divider-w, 1px)));z-index:2;--pfx-fab-size: var(--pfx-fab-size-row, 32px);--pfx-fab-icon: var(--pfx-fab-icon-row, 18px);width:var(--pfx-fab-size);height:var(--pfx-fab-size);border-radius:50%}.fab-add-row.mat-mdc-fab{width:var(--pfx-fab-size);height:var(--pfx-fab-size);padding:0}.fab-add-row .mat-mdc-button-touch-target,.fab-add-row .mat-mdc-button-persistent-ripple,.fab-add-row .mat-mdc-button-ripple{width:var(--pfx-fab-size);height:var(--pfx-fab-size)}.fab-add-row mat-icon{font-size:var(--pfx-fab-icon);width:var(--pfx-fab-icon);height:var(--pfx-fab-icon)}@media(max-width:700px){.section-header{position:relative;align-items:flex-start;display:block;min-height:88px;padding-right:12px}.title-wrapper{align-items:flex-start;padding-right:132px;width:auto}.section-heading{align-items:flex-start;gap:12px}.section-heading__icon{margin-top:4px}.section-heading .section-name{font-size:20px;line-height:26px}.section-header-actions{position:absolute;top:12px;right:12px;margin-left:0}.section-editor-trigger{position:absolute;top:12px;right:88px;margin-left:0}.section-heading .section-name,.section-heading .section-desc{overflow:visible;text-overflow:clip;white-space:normal}}.selection-context{padding-block:calc(var(--px-editor-section-gap, 1rem) / 2);border-block-end:1px solid var(--md-sys-color-outline-variant);margin-block-end:calc(var(--px-editor-section-gap, 1rem) / 2)}.selection-actions{display:flex;flex-wrap:wrap;gap:calc(var(--px-editor-section-gap, 1rem) / 2)}.selection-context .section-breadcrumbs{flex-wrap:wrap}.selection-context .crumb{overflow-wrap:anywhere;min-width:0}.section-rename-controls{display:flex;flex-wrap:wrap;align-items:center;gap:var(--px-editor-section-gap, 1rem);margin-block-end:var(--px-editor-section-gap, 1rem)}.section-rename-controls mat-form-field{flex:1 1 100%;min-width:0}.section-empty-guidance{color:var(--md-sys-color-on-surface-variant);font:var(--md-sys-typescale-body-medium)}\n"], dependencies: [{ kind: "ngmodule", type: DragDropModule }, { kind: "directive", type: i2$2.CdkDropList, selector: "[cdkDropList], cdk-drop-list", inputs: ["cdkDropListConnectedTo", "cdkDropListData", "cdkDropListOrientation", "id", "cdkDropListLockAxis", "cdkDropListDisabled", "cdkDropListSortingDisabled", "cdkDropListEnterPredicate", "cdkDropListSortPredicate", "cdkDropListAutoScrollDisabled", "cdkDropListAutoScrollStep", "cdkDropListElementContainer", "cdkDropListHasAnchor"], outputs: ["cdkDropListDropped", "cdkDropListEntered", "cdkDropListExited", "cdkDropListSorted"], exportAs: ["cdkDropList"] }, { kind: "directive", type: i2$2.CdkDrag, selector: "[cdkDrag]", inputs: ["cdkDragData", "cdkDragLockAxis", "cdkDragRootElement", "cdkDragBoundary", "cdkDragStartDelay", "cdkDragFreeDragPosition", "cdkDragDisabled", "cdkDragConstrainPosition", "cdkDragPreviewClass", "cdkDragPreviewContainer", "cdkDragScale"], outputs: ["cdkDragStarted", "cdkDragReleased", "cdkDragEnded", "cdkDragEntered", "cdkDragExited", "cdkDragDropped", "cdkDragMoved"], exportAs: ["cdkDrag"] }, { kind: "ngmodule", type: FormsModule }, { kind: "directive", type: i1$3.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: i1$3.NgControlStatus, selector: "[formControlName],[ngModel],[formControl]" }, { kind: "directive", type: i1$3.RequiredValidator, selector: ":not([type=checkbox])[required][formControlName],:not([type=checkbox])[required][formControl],:not([type=checkbox])[required][ngModel]", inputs: ["required"] }, { kind: "directive", type: i1$3.NgModel, selector: "[ngModel]:not([formControlName]):not([formControl])", inputs: ["name", "disabled", "ngModel", "ngModelOptions"], outputs: ["ngModelChange"], exportAs: ["ngModel"] }, { kind: "ngmodule", type: MatFormFieldModule }, { kind: "component", type: i4$1.MatFormField, selector: "mat-form-field", inputs: ["hideRequiredMarker", "color", "floatLabel", "appearance", "subscriptSizing", "hintLabel"], exportAs: ["matFormField"] }, { kind: "directive", type: i4$1.MatLabel, selector: "mat-label" }, { kind: "directive", type: i4$1.MatHint, selector: "mat-hint", inputs: ["align", "id"] }, { kind: "directive", type: i4$1.MatError, selector: "mat-error, [matError]", inputs: ["id"] }, { kind: "ngmodule", type: MatInputModule }, { kind: "directive", type: i4$2.MatInput, selector: "input[matInput], textarea[matInput], select[matNativeControl], input[matNativeControl], textarea[matNativeControl]", inputs: ["disabled", "id", "placeholder", "name", "required", "type", "errorStateMatcher", "aria-describedby", "value", "readonly", "disabledInteractive"], exportAs: ["matInput"] }, { kind: "component", type: RowConfiguratorComponent, selector: "praxis-row-configurator", inputs: ["row", "fieldMetadata", "availableFields", "sectionIndex", "rowIndex", "isLastRow", "selected", "availableFieldsListId", "connectedDropListIds", "gapGlobal"], outputs: ["rowChange", "remove", "applyRowGapAll", "fieldDrop", "addVisualBlock", "addApiField", "addLocalField", "editField", "editVisualBlock", "moveVisualBlock", "moveVisualBlockToColumn", "removeVisualBlock", "select"] }, { kind: "ngmodule", type: MatButtonModule }, { kind: "component", type: i3.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: i3.MatFabButton, selector: "button[mat-fab], a[mat-fab], button[matFab], a[matFab]", inputs: ["extended"], exportAs: ["matButton", "matAnchor"] }, { kind: "ngmodule", type: MatIconModule }, { kind: "component", type: i4.MatIcon, selector: "mat-icon", inputs: ["color", "inline", "svgIcon", "fontSet", "fontIcon"], exportAs: ["matIcon"] }, { kind: "component", type: PraxisIconButtonComponent, selector: "button[praxisIconButton]", inputs: ["praxisIconButton", "size", "appearance", "presentation", "pressed", "busy"] }, { kind: "directive", type: PraxisIconDirective, selector: "mat-icon[praxisIcon]", inputs: ["praxisIcon"] }, { kind: "ngmodule", type: MatCardModule }, { kind: "component", type: i7$1.MatCard, selector: "mat-card", inputs: ["appearance"], exportAs: ["matCard"] }, { kind: "directive", type: i7$1.MatCardContent, selector: "mat-card-content" }, { kind: "component", type: i7$1.MatCardHeader, selector: "mat-card-header" }, { kind: "directive", type: i7$1.MatCardTitle, selector: "mat-card-title, [mat-card-title], [matCardTitle]" }, { kind: "ngmodule", type: MatTooltipModule }, { kind: "directive", type: i5.MatTooltip, selector: "[matTooltip]", inputs: ["matTooltipPosition", "matTooltipPositionAtOrigin", "matTooltipDisabled", "matTooltipShowDelay", "matTooltipHideDelay", "matTooltipTouchGestures", "matTooltip", "matTooltipClass"], exportAs: ["matTooltip"] }, { kind: "ngmodule", type: MatDialogModule }, { kind: "ngmodule", type: MatMenuModule }, { kind: "component", type: i6.MatMenu, selector: "mat-menu", inputs: ["backdropClass", "aria-label", "aria-labelledby", "aria-describedby", "xPosition", "yPosition", "overlapTrigger", "hasBackdrop", "class", "classList"], outputs: ["closed", "close"], exportAs: ["matMenu"] }, { kind: "component", type: i6.MatMenuItem, selector: "[mat-menu-item]", inputs: ["role", "disabled", "disableRipple"], exportAs: ["matMenuItem"] }, { kind: "directive", type: i6.MatMenuTrigger, selector: "[mat-menu-trigger-for], [matMenuTriggerFor]", inputs: ["mat-menu-trigger-for", "matMenuTriggerFor", "matMenuTriggerData", "matMenuTriggerRestoreFocus"], outputs: ["menuOpened", "onMenuOpen", "menuClosed", "onMenuClose"], exportAs: ["matMenuTrigger"] }, { kind: "ngmodule", type: MatDividerModule }, { kind: "component", type: i8.MatDivider, selector: "mat-divider", inputs: ["vertical", "inset"] }] });
|
|
24881
|
+
static ɵcmp = i0.ɵɵngDeclareComponent({ minVersion: "17.0.0", version: "21.2.14", type: SectionConfiguratorComponent, isStandalone: true, selector: "praxis-section-configurator", inputs: { section: "section", sectionIndex: "sectionIndex", allSections: "allSections", fieldMetadata: "fieldMetadata", availableFields: "availableFields", selected: "selected", availableFieldsListId: "availableFieldsListId", columnDropListIds: "columnDropListIds", gapGlobal: "gapGlobal" }, outputs: { sectionChange: "sectionChange", applyStyleToAll: "applyStyleToAll", remove: "remove", select: "select", fieldDrop: "fieldDrop", addVisualBlock: "addVisualBlock", addApiField: "addApiField", addLocalField: "addLocalField", requestMoveField: "requestMoveField", editField: "editField", editVisualBlock: "editVisualBlock", moveVisualBlock: "moveVisualBlock", moveVisualBlockToColumn: "moveVisualBlockToColumn", removeVisualBlock: "removeVisualBlock" }, providers: [providePraxisI18nConfig(LAYOUT_EDITOR_I18N_CONFIG)], ngImport: i0, template: "<mat-card\n class=\"section-card\"\n cdkDrag\n (mouseenter)=\"onMouseEnter()\"\n (mouseleave)=\"onMouseLeave()\"\n [class.hovered]=\"isHovered\"\n [class.selected]=\"isThisSectionSelected()\"\n [class.collapsed]=\"isCollapsed\"\n (click)=\"onSelectSection()\"\n tabindex=\"0\"\n role=\"button\"\n [attr.aria-label]=\"'Se\u00E7\u00E3o ' + (sectionIndex + 1)\"\n [attr.aria-selected]=\"isThisSectionSelected()\"\n >\n <mat-card-header class=\"section-header\">\n <mat-card-title class=\"title-wrapper\">\n <div class=\"section-heading\">\n @let headerPreview = getSectionHeaderPreview();\n @let headerAvatarSize = getSectionHeaderAvatarSize();\n @if (headerPreview.kind === 'icon') {\n <mat-icon class=\"section-heading__icon\" aria-hidden=\"true\" [praxisIcon]=\"headerPreview.icon\"></mat-icon>\n }\n @if (headerPreview.kind === 'initials') {\n <span class=\"section-heading__avatar section-heading__avatar--text\" [class.size-sm]=\"headerAvatarSize === 'sm'\"\n [class.size-md]=\"headerAvatarSize === 'md'\" [class.size-lg]=\"headerAvatarSize === 'lg'\"\n [matTooltip]=\"headerPreview.tooltip || ''\" [matTooltipDisabled]=\"!headerPreview.tooltip\">\n {{ headerPreview.text }}\n </span>\n }\n @if (headerPreview.kind === 'placeholder') {\n <span class=\"section-heading__avatar section-heading__avatar--placeholder\" [class.size-sm]=\"headerAvatarSize === 'sm'\"\n [class.size-md]=\"headerAvatarSize === 'md'\" [class.size-lg]=\"headerAvatarSize === 'lg'\"\n [matTooltip]=\"headerPreview.tooltip || ''\" [matTooltipDisabled]=\"!headerPreview.tooltip\">\n @if (headerPreview.icon) {\n <mat-icon aria-hidden=\"true\" [praxisIcon]=\"headerPreview.icon\"></mat-icon>\n }\n </span>\n }\n <div class=\"section-heading__text\">\n <span class=\"section-name\">{{ section.title || 'Sem t\u00EDtulo' }}</span>\n @if (section.description) {\n <span class=\"section-desc\">{{ section.description }}</span>\n }\n </div>\n </div>\n <button praxisIconButton=\"edit\" size=\"dense\" type=\"button\"\n data-testid=\"section-rename-trigger\" (click)=\"startRename($event)\"\n [matTooltip]=\"t('section.rename.action')\" [attr.aria-label]=\"t('section.rename.action')\">\n </button>\n <button\n praxisIconButton=\"open_in_new\"\n size=\"dense\"\n type=\"button\"\n class=\"section-editor-trigger primary-action\"\n (click)=\"openAdvancedEditor($event)\"\n [matTooltip]=\"t('section.editor.hint')\"\n aria-label=\"Abrir editor da se\u00E7\u00E3o\"\n >\n </button>\n </mat-card-title>\n <div class=\"section-header-actions\">\n <button\n [praxisIconButton]=\"isCollapsed ? 'unfold_more' : 'unfold_less'\"\n size=\"dense\"\n class=\"section-collapse-btn\"\n type=\"button\"\n (click)=\"toggleCollapsed($event)\"\n [attr.aria-expanded]=\"!isCollapsed\"\n [attr.aria-label]=\"isCollapsed ? 'Expandir se\u00E7\u00E3o' : 'Colapsar se\u00E7\u00E3o'\"\n [matTooltip]=\"isCollapsed ? 'Expandir se\u00E7\u00E3o' : 'Colapsar se\u00E7\u00E3o'\"\n >\n </button>\n <button\n praxisIconButton=\"more_vert\"\n size=\"dense\"\n class=\"section-menu-btn\"\n [matMenuTriggerFor]=\"sectionMenu\"\n aria-label=\"Mais a\u00E7\u00F5es da se\u00E7\u00E3o\"\n matTooltip=\"Mais a\u00E7\u00F5es\"\n >\n </button>\n </div>\n <mat-menu #sectionMenu=\"matMenu\">\n <button mat-menu-item (click)=\"openSectionPresets()\">\n <mat-icon [praxisIcon]=\"'view_quilt'\"></mat-icon>\n <span>Presets de se\u00E7\u00E3o\u2026</span>\n </button>\n <button mat-menu-item (click)=\"applyCurrentStyleToAll()\">\n <mat-icon [praxisIcon]=\"'format_paint'\"></mat-icon>\n <span>Aplicar estilo desta se\u00E7\u00E3o a todas</span>\n </button>\n <mat-divider></mat-divider>\n @if (section.description == null) {\n <button mat-menu-item (click)=\"section.description = ''; onSectionUpdated()\">\n <mat-icon [praxisIcon]=\"'note_add'\"></mat-icon>\n <span>Adicionar descri\u00E7\u00E3o</span>\n </button>\n }\n @if (section.description != null) {\n <button mat-menu-item (click)=\"section.description = undefined; onSectionUpdated()\">\n <mat-icon [praxisIcon]=\"'backspace'\"></mat-icon>\n <span>Remover descri\u00E7\u00E3o</span>\n </button>\n }\n <mat-divider></mat-divider>\n <button mat-menu-item (click)=\"onRemoveSection()\">\n <mat-icon [praxisIcon]=\"'delete'\"></mat-icon>\n <span>Remover se\u00E7\u00E3o</span>\n </button>\n </mat-menu>\n </mat-card-header>\n <mat-card-content [attr.aria-hidden]=\"isCollapsed\">\n @if (renameDraft() !== null) {\n <div class=\"section-rename-controls\" role=\"group\" [attr.aria-label]=\"t('section.rename.action')\" (click)=\"$event.stopPropagation()\">\n <mat-form-field subscriptSizing=\"dynamic\">\n <mat-label>{{ t('section.rename.title') }}</mat-label>\n <input matInput data-testid=\"section-rename-input\" required\n [ngModel]=\"renameDraft()\" (ngModelChange)=\"renameDraft.set($event)\"\n (keydown.enter)=\"finishRename($event, true)\" (keydown.escape)=\"finishRename($event, false)\" />\n <mat-error>{{ t('section.rename.required') }}</mat-error>\n @if (renameDraft()?.length && !renameDraft()?.trim()) {\n <mat-hint>{{ t('section.rename.required') }}</mat-hint>\n }\n </mat-form-field>\n <button mat-stroked-button type=\"button\" [disabled]=\"!renameDraft()?.trim()\" (click)=\"finishRename($event, true)\">{{ t('section.rename.save') }}</button>\n <button mat-button type=\"button\" (click)=\"finishRename($event, false)\">{{ t('field.move.cancel') }}</button>\n </div>\n }\n @if (!section.rows.length) {\n <p class=\"section-empty-guidance\">{{ t('section.empty.guidance') }}</p>\n }\n @if (isThisSectionSelected()) {\n <div class=\"selection-context\" (click)=\"$event.stopPropagation()\" role=\"region\" [attr.aria-label]=\"t('selection.context')\">\n <nav class=\"section-breadcrumbs\" [attr.aria-label]=\"t('selection.path')\">\n <button\n type=\"button\"\n class=\"crumb as-button crumb-section\"\n data-crumb=\"section\"\n (click)=\"onSelectSectionFromBreadcrumb($event)\"\n [attr.aria-label]=\"section.title || t('selection.section', { index: sectionIndex + 1 })\"\n >\n {{ section.title || t('selection.section', { index: sectionIndex + 1 }) }}\n </button>\n @if (selected?.rowIndex != null) {\n <span class=\"sep\">\u203A</span>\n <button\n type=\"button\"\n class=\"crumb as-button crumb-row\"\n data-crumb=\"row\"\n (click)=\"onSelectRowFromBreadcrumb($event)\"\n [attr.aria-label]=\"t('selection.row', { index: selected!.rowIndex! + 1 })\"\n >\n {{ t('selection.row', { index: selected!.rowIndex! + 1 }) }}\n </button>\n }\n @if (selected?.columnIndex != null) {\n <span class=\"sep\">\u203A</span>\n <button\n type=\"button\"\n class=\"crumb as-button crumb-column\"\n data-crumb=\"column\"\n (click)=\"onSelectColumnFromBreadcrumb($event)\"\n [attr.aria-label]=\"t('selection.column', { index: selected!.columnIndex! + 1 })\"\n >\n {{ t('selection.column', { index: selected!.columnIndex! + 1 }) }}\n </button>\n }\n @if (selected?.fieldName) {\n <span class=\"sep\">\u203A</span>\n <span class=\"crumb active\">{{ selectedFieldLabel }}</span>\n }\n @if (selected) {\n <button\n type=\"button\"\n class=\"crumb as-button crumb-clear\"\n data-crumb=\"clear\"\n (click)=\"onClearSelectionFromBreadcrumb($event)\"\n [attr.aria-label]=\"t('selection.clear')\"\n >\n {{ t('selection.clear') }}\n </button>\n }\n </nav>\n <div class=\"selection-actions\">\n @if (selectedField) {\n <button mat-stroked-button type=\"button\" (click)=\"requestSelectedFieldMove($event)\">\n <mat-icon aria-hidden=\"true\">drive_file_move</mat-icon>{{ t('field.move.action') }}\n </button>\n <button mat-stroked-button type=\"button\" data-testid=\"layout-edit-selected-field\" (click)=\"editSelectedField($event)\">\n <mat-icon aria-hidden=\"true\">edit</mat-icon>{{ t('selection.editField') }}\n </button>\n }\n @if (selectedColumn) {\n <button mat-stroked-button type=\"button\" data-testid=\"layout-edit-selected-column\" (click)=\"editSelectedColumn($event)\">\n <mat-icon aria-hidden=\"true\">view_column</mat-icon>{{ t('selection.editColumn') }}\n </button>\n }\n </div>\n </div>\n } @else {\n <h5>Linhas</h5>\n }\n <div\n class=\"row-list\"\n cdkDropList\n [cdkDropListData]=\"section.rows\"\n (cdkDropListDropped)=\"dropRow($event)\"\n >\n @for (row of section.rows; track row; let i = $index) {\n <praxis-row-configurator\n class=\"row-item\"\n [row]=\"row\"\n [fieldMetadata]=\"fieldMetadata\"\n [availableFields]=\"availableFields\"\n [sectionIndex]=\"sectionIndex\"\n [rowIndex]=\"i\"\n [isLastRow]=\"i === section.rows.length - 1\"\n [selected]=\"selected\"\n [availableFieldsListId]=\"availableFieldsListId\"\n [connectedDropListIds]=\"columnDropListIds\"\n [gapGlobal]=\"gapGlobal\"\n (rowChange)=\"onRowUpdated(i, $event)\"\n (applyRowGapAll)=\"onApplyRowGapAll($event)\"\n (remove)=\"removeRow(i)\"\n (select)=\"select.emit($event)\"\n (fieldDrop)=\"onFieldDrop($event, i)\"\n (addVisualBlock)=\"onAddVisualBlock($event)\"\n (addApiField)=\"onAddApiField($event)\"\n (addLocalField)=\"onAddLocalField($event)\"\n (editField)=\"onEditField($event)\"\n (editVisualBlock)=\"onEditVisualBlock($event)\"\n (moveVisualBlock)=\"onMoveVisualBlock($event)\"\n (moveVisualBlockToColumn)=\"onMoveVisualBlockToColumn($event)\"\n (removeVisualBlock)=\"onRemoveVisualBlock($event)\"\n cdkDrag\n ></praxis-row-configurator>\n }\n </div>\n <div class=\"section-actions\" aria-label=\"A\u00E7\u00F5es da se\u00E7\u00E3o\">\n @if (!section.rows.length) {\n <button mat-stroked-button type=\"button\" (click)=\"addRow()\">\n <mat-icon aria-hidden=\"true\">add</mat-icon>{{ t('section.empty.addRow') }}\n </button>\n } @else {\n <button\n class=\"fab-add-row\"\n mat-fab\n color=\"primary\"\n (click)=\"addRow()\"\n matTooltip=\"Adicionar linha\"\n aria-label=\"Adicionar linha\"\n >\n <mat-icon>add</mat-icon>\n </button>\n }\n </div>\n </mat-card-content>\n</mat-card>\n", styles: ["@charset \"UTF-8\";.section-card{background:var(--md-sys-color-surface);margin-bottom:16px;transition:border-color .2s ease;border:1px solid transparent;box-sizing:border-box;max-width:100%;min-width:0}.section-card.hovered{border-color:var(--md-sys-color-primary)}.section-card.selected{border-color:var(--md-sys-color-primary);box-shadow:0 0 0 2px var(--md-sys-color-primary)}.section-card.cdk-drag-dragging{cursor:grabbing}.section-card.cdk-drag-preview{box-sizing:border-box;border-color:var(--md-sys-color-primary);box-shadow:var(--md-sys-elevation-level3);cursor:grabbing}.section-card.cdk-drag-placeholder{position:relative;min-height:64px;border-color:transparent;background:transparent;box-shadow:none;opacity:1}.section-card.cdk-drag-placeholder>*{visibility:hidden}.section-card.cdk-drag-placeholder:before{content:\"\";position:absolute;inset:calc(50% - 1px) 12px auto 12px;height:2px;border-radius:999px;background:var(--md-sys-color-primary);box-shadow:0 0 0 3px color-mix(in srgb,var(--md-sys-color-primary) 16%,transparent)}.section-card.cdk-drag-placeholder:after{content:\"\";position:absolute;top:calc(50% - 5px);left:12px;width:10px;height:10px;border-radius:50%;background:var(--md-sys-color-primary)}.section-card:focus-visible{outline:2px solid var(--md-sys-color-primary);outline-offset:2px}.section-card .mat-mdc-card-content{padding-bottom:var(--px-editor-section-gap, 16px)}.section-breadcrumbs{font-size:12px;color:var(--md-sys-color-on-surface-variant);margin:4px 0 8px;display:flex;align-items:center;gap:6px}.section-breadcrumbs .as-button{background:transparent;border:none;padding:0 2px;color:inherit;font:inherit;cursor:pointer;border-radius:4px}.section-breadcrumbs .as-button:hover{color:var(--md-sys-color-primary)}.section-breadcrumbs .as-button:focus-visible{outline:2px solid var(--md-sys-color-primary);outline-offset:2px}.section-breadcrumbs .crumb-clear{margin-left:6px;opacity:.85}.section-breadcrumbs .crumb.active{color:var(--md-sys-color-on-surface);font-weight:600}.section-breadcrumbs .sep{opacity:.6}.section-header{display:flex;justify-content:space-between;align-items:center;gap:12px;min-height:56px;min-width:0}.title-wrapper{display:flex;align-items:center;gap:8px;width:100%;min-width:0;flex:1 1 auto}.section-heading{display:flex;align-items:center;gap:10px;min-width:0}.section-heading__icon{color:var(--md-sys-color-primary)}.section-heading__avatar{--_pfx-layout-section-avatar-size: var(--pfx-form-section-avatar-size-md, var(--pfx-form-section-avatar-size, 32px));display:inline-flex;align-items:center;justify-content:center;width:var(--_pfx-layout-section-avatar-size);height:var(--_pfx-layout-section-avatar-size);border-radius:999px;flex:0 0 var(--_pfx-layout-section-avatar-size);overflow:hidden}.section-heading__avatar.size-sm{--_pfx-layout-section-avatar-size: var(--pfx-form-section-avatar-size-sm, 24px)}.section-heading__avatar.size-md{--_pfx-layout-section-avatar-size: var(--pfx-form-section-avatar-size-md, var(--pfx-form-section-avatar-size, 32px))}.section-heading__avatar.size-lg{--_pfx-layout-section-avatar-size: var(--pfx-form-section-avatar-size-lg, 40px)}.section-heading__avatar--text,.section-heading__avatar--placeholder{background:color-mix(in srgb,var(--pfx-editorial-form-accent, var(--md-sys-color-primary)) 14%,var(--pfx-form-section-surface-flat, var(--md-sys-color-surface)));color:color-mix(in srgb,var(--pfx-editorial-form-accent, var(--md-sys-color-primary)) 82%,var(--pfx-form-label-strong, var(--md-sys-color-on-surface)) 18%);font-size:calc(var(--_pfx-layout-section-avatar-size) * .41);font-weight:800;letter-spacing:.04em;text-transform:uppercase}.section-heading__avatar--placeholder mat-icon{font-size:calc(var(--_pfx-layout-section-avatar-size) * .5625);width:calc(var(--_pfx-layout-section-avatar-size) * .5625);height:calc(var(--_pfx-layout-section-avatar-size) * .5625);line-height:calc(var(--_pfx-layout-section-avatar-size) * .5625)}.section-heading__text{display:flex;flex-direction:column;align-items:flex-start;min-width:0}.section-heading .section-name{font-weight:600;color:var(--md-sys-color-on-surface);overflow:hidden;text-overflow:ellipsis;white-space:nowrap}.section-heading .section-desc{font-size:12px;color:var(--md-sys-color-on-surface-variant);margin-top:2px;overflow:hidden;text-overflow:ellipsis;white-space:nowrap}.section-editor-trigger{margin-left:auto}.section-editor-trigger.primary-action{color:var(--md-sys-color-primary)}.section-header-actions{display:inline-flex;align-items:center;gap:4px;flex-shrink:0}.add-row-button{margin-top:8px}.row-item{animation:fadeIn .3s ease}.row-item.cdk-drag-dragging{cursor:grabbing}.row-item.cdk-drag-preview{box-sizing:border-box;border-radius:8px;background:var(--md-sys-color-surface-container, var(--md-sys-color-surface));box-shadow:var(--md-sys-elevation-level3);cursor:grabbing}.row-item.cdk-drag-placeholder{position:relative;display:block;min-height:56px;opacity:1}.row-item.cdk-drag-placeholder>*{visibility:hidden}.row-item.cdk-drag-placeholder:before{content:\"\";position:absolute;inset:calc(50% - 1px) 8px auto 8px;height:2px;border-radius:999px;background:var(--md-sys-color-primary);box-shadow:0 0 0 3px color-mix(in srgb,var(--md-sys-color-primary) 16%,transparent)}.row-item.cdk-drag-placeholder:after{content:\"\";position:absolute;top:calc(50% - 4px);left:8px;width:8px;height:8px;border-radius:50%;background:var(--md-sys-color-primary)}@keyframes fadeIn{0%{opacity:0;transform:translateY(-4px)}to{opacity:1;transform:none}}.section-card:hover{border-color:var(--md-sys-color-primary)}.section-card.collapsed .mat-mdc-card-content{display:none}:host ::ng-deep .section-card .mat-mdc-card-header{padding:8px 12px}:host ::ng-deep .section-card .mat-mdc-card-title{margin:0}:host ::ng-deep .section-card .mat-mdc-card-content{padding:0 12px 12px}.section-actions{position:relative;margin-top:12px;padding-top:16px;border-top:1px solid var(--md-sys-color-outline-variant);min-height:28px}.row-list{border-top:1px solid var(--px-editor-separator-color, var(--md-sys-color-outline-variant));padding-top:12px;margin-top:8px;min-width:0}.fab-add-row{position:absolute;top:-15px;left:50%;transform:translate(-50%,calc(-50% - var(--pfx-divider-w, 1px)));z-index:2;--pfx-fab-size: var(--pfx-fab-size-row, 32px);--pfx-fab-icon: var(--pfx-fab-icon-row, 18px);width:var(--pfx-fab-size);height:var(--pfx-fab-size);border-radius:50%}.fab-add-row.mat-mdc-fab{width:var(--pfx-fab-size);height:var(--pfx-fab-size);padding:0}.fab-add-row .mat-mdc-button-touch-target,.fab-add-row .mat-mdc-button-persistent-ripple,.fab-add-row .mat-mdc-button-ripple{width:var(--pfx-fab-size);height:var(--pfx-fab-size)}.fab-add-row mat-icon{font-size:var(--pfx-fab-icon);width:var(--pfx-fab-icon);height:var(--pfx-fab-icon)}@media(max-width:700px){.section-header{position:relative;align-items:flex-start;display:block;min-height:88px;padding-right:12px}.title-wrapper{align-items:flex-start;padding-right:132px;width:auto}.section-heading{align-items:flex-start;gap:12px}.section-heading__icon{margin-top:4px}.section-heading .section-name{font-size:20px;line-height:26px}.section-header-actions{position:absolute;top:12px;right:12px;margin-left:0}.section-editor-trigger{position:absolute;top:12px;right:88px;margin-left:0}.section-heading .section-name,.section-heading .section-desc{overflow:visible;text-overflow:clip;white-space:normal}}.selection-context{padding-block:calc(var(--px-editor-section-gap, 1rem) / 2);border-block-end:1px solid var(--md-sys-color-outline-variant);margin-block-end:calc(var(--px-editor-section-gap, 1rem) / 2)}.selection-actions{display:flex;flex-wrap:wrap;gap:calc(var(--px-editor-section-gap, 1rem) / 2)}.selection-context .section-breadcrumbs{flex-wrap:wrap}.selection-context .crumb{overflow-wrap:anywhere;min-width:0}.section-rename-controls{display:flex;flex-wrap:wrap;align-items:center;gap:var(--px-editor-section-gap, 1rem);margin-block-end:var(--px-editor-section-gap, 1rem)}.section-rename-controls mat-form-field{flex:1 1 100%;min-width:0}.section-empty-guidance{color:var(--md-sys-color-on-surface-variant);font:var(--md-sys-typescale-body-medium)}\n"], dependencies: [{ kind: "ngmodule", type: DragDropModule }, { kind: "directive", type: i2$2.CdkDropList, selector: "[cdkDropList], cdk-drop-list", inputs: ["cdkDropListConnectedTo", "cdkDropListData", "cdkDropListOrientation", "id", "cdkDropListLockAxis", "cdkDropListDisabled", "cdkDropListSortingDisabled", "cdkDropListEnterPredicate", "cdkDropListSortPredicate", "cdkDropListAutoScrollDisabled", "cdkDropListAutoScrollStep", "cdkDropListElementContainer", "cdkDropListHasAnchor"], outputs: ["cdkDropListDropped", "cdkDropListEntered", "cdkDropListExited", "cdkDropListSorted"], exportAs: ["cdkDropList"] }, { kind: "directive", type: i2$2.CdkDrag, selector: "[cdkDrag]", inputs: ["cdkDragData", "cdkDragLockAxis", "cdkDragRootElement", "cdkDragBoundary", "cdkDragStartDelay", "cdkDragFreeDragPosition", "cdkDragDisabled", "cdkDragConstrainPosition", "cdkDragPreviewClass", "cdkDragPreviewContainer", "cdkDragScale"], outputs: ["cdkDragStarted", "cdkDragReleased", "cdkDragEnded", "cdkDragEntered", "cdkDragExited", "cdkDragDropped", "cdkDragMoved"], exportAs: ["cdkDrag"] }, { kind: "ngmodule", type: FormsModule }, { kind: "directive", type: i1$3.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: i1$3.NgControlStatus, selector: "[formControlName],[ngModel],[formControl]" }, { kind: "directive", type: i1$3.RequiredValidator, selector: ":not([type=checkbox])[required][formControlName],:not([type=checkbox])[required][formControl],:not([type=checkbox])[required][ngModel]", inputs: ["required"] }, { kind: "directive", type: i1$3.NgModel, selector: "[ngModel]:not([formControlName]):not([formControl])", inputs: ["name", "disabled", "ngModel", "ngModelOptions"], outputs: ["ngModelChange"], exportAs: ["ngModel"] }, { kind: "ngmodule", type: MatFormFieldModule }, { kind: "component", type: i4$1.MatFormField, selector: "mat-form-field", inputs: ["hideRequiredMarker", "color", "floatLabel", "appearance", "subscriptSizing", "hintLabel"], exportAs: ["matFormField"] }, { kind: "directive", type: i4$1.MatLabel, selector: "mat-label" }, { kind: "directive", type: i4$1.MatHint, selector: "mat-hint", inputs: ["align", "id"] }, { kind: "directive", type: i4$1.MatError, selector: "mat-error, [matError]", inputs: ["id"] }, { kind: "ngmodule", type: MatInputModule }, { kind: "directive", type: i4$2.MatInput, selector: "input[matInput], textarea[matInput], select[matNativeControl], input[matNativeControl], textarea[matNativeControl]", inputs: ["disabled", "id", "placeholder", "name", "required", "type", "errorStateMatcher", "aria-describedby", "value", "readonly", "disabledInteractive"], exportAs: ["matInput"] }, { kind: "component", type: RowConfiguratorComponent, selector: "praxis-row-configurator", inputs: ["row", "fieldMetadata", "availableFields", "sectionIndex", "rowIndex", "isLastRow", "selected", "availableFieldsListId", "connectedDropListIds", "gapGlobal"], outputs: ["rowChange", "remove", "applyRowGapAll", "fieldDrop", "addVisualBlock", "addApiField", "addLocalField", "editField", "editVisualBlock", "moveVisualBlock", "moveVisualBlockToColumn", "removeVisualBlock", "select"] }, { kind: "ngmodule", type: MatButtonModule }, { kind: "component", type: i3.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: i3.MatFabButton, selector: "button[mat-fab], a[mat-fab], button[matFab], a[matFab]", inputs: ["extended"], exportAs: ["matButton", "matAnchor"] }, { kind: "ngmodule", type: MatIconModule }, { kind: "component", type: i4.MatIcon, selector: "mat-icon", inputs: ["color", "inline", "svgIcon", "fontSet", "fontIcon"], exportAs: ["matIcon"] }, { kind: "component", type: PraxisIconButtonComponent, selector: "button[praxisIconButton]", inputs: ["praxisIconButton", "size", "appearance", "presentation", "pressed", "busy"] }, { kind: "directive", type: PraxisIconDirective, selector: "mat-icon[praxisIcon]", inputs: ["praxisIcon"] }, { kind: "ngmodule", type: MatCardModule }, { kind: "component", type: i7$1.MatCard, selector: "mat-card", inputs: ["appearance"], exportAs: ["matCard"] }, { kind: "directive", type: i7$1.MatCardContent, selector: "mat-card-content" }, { kind: "component", type: i7$1.MatCardHeader, selector: "mat-card-header" }, { kind: "directive", type: i7$1.MatCardTitle, selector: "mat-card-title, [mat-card-title], [matCardTitle]" }, { kind: "ngmodule", type: MatTooltipModule }, { kind: "directive", type: i5.MatTooltip, selector: "[matTooltip]", inputs: ["matTooltipPosition", "matTooltipPositionAtOrigin", "matTooltipDisabled", "matTooltipShowDelay", "matTooltipHideDelay", "matTooltipTouchGestures", "matTooltip", "matTooltipClass"], exportAs: ["matTooltip"] }, { kind: "ngmodule", type: MatDialogModule }, { kind: "ngmodule", type: MatMenuModule }, { kind: "component", type: i6.MatMenu, selector: "mat-menu", inputs: ["backdropClass", "aria-label", "aria-labelledby", "aria-describedby", "xPosition", "yPosition", "overlapTrigger", "hasBackdrop", "class", "classList"], outputs: ["closed", "close"], exportAs: ["matMenu"] }, { kind: "component", type: i6.MatMenuItem, selector: "[mat-menu-item]", inputs: ["role", "disabled", "disableRipple"], exportAs: ["matMenuItem"] }, { kind: "directive", type: i6.MatMenuTrigger, selector: "[mat-menu-trigger-for], [matMenuTriggerFor]", inputs: ["mat-menu-trigger-for", "matMenuTriggerFor", "matMenuTriggerData", "matMenuTriggerRestoreFocus"], outputs: ["menuOpened", "onMenuOpen", "menuClosed", "onMenuClose"], exportAs: ["matMenuTrigger"] }, { kind: "ngmodule", type: MatDividerModule }, { kind: "component", type: i8.MatDivider, selector: "mat-divider", inputs: ["vertical", "inset"] }] });
|
|
24641
24882
|
}
|
|
24642
24883
|
i0.ɵɵngDeclareClassMetadata({ minVersion: "12.0.0", version: "21.2.14", ngImport: i0, type: SectionConfiguratorComponent, decorators: [{
|
|
24643
24884
|
type: Component,
|
|
@@ -24653,7 +24894,7 @@ i0.ɵɵngDeclareClassMetadata({ minVersion: "12.0.0", version: "21.2.14", ngImpo
|
|
|
24653
24894
|
MatDialogModule,
|
|
24654
24895
|
MatMenuModule,
|
|
24655
24896
|
MatDividerModule
|
|
24656
|
-
], providers: [providePraxisI18nConfig(LAYOUT_EDITOR_I18N_CONFIG)], template: "<mat-card\n class=\"section-card\"\n cdkDrag\n (mouseenter)=\"onMouseEnter()\"\n (mouseleave)=\"onMouseLeave()\"\n [class.hovered]=\"isHovered\"\n [class.selected]=\"isThisSectionSelected()\"\n [class.collapsed]=\"isCollapsed\"\n (click)=\"onSelectSection()\"\n tabindex=\"0\"\n role=\"button\"\n [attr.aria-label]=\"'Se\u00E7\u00E3o ' + (sectionIndex + 1)\"\n [attr.aria-selected]=\"isThisSectionSelected()\"\n >\n <mat-card-header class=\"section-header\">\n <mat-card-title class=\"title-wrapper\">\n <div class=\"section-heading\">\n @let headerPreview = getSectionHeaderPreview();\n @let headerAvatarSize = getSectionHeaderAvatarSize();\n @if (headerPreview.kind === 'icon') {\n <mat-icon class=\"section-heading__icon\" aria-hidden=\"true\" [praxisIcon]=\"headerPreview.icon\"></mat-icon>\n }\n @if (headerPreview.kind === 'initials') {\n <span class=\"section-heading__avatar section-heading__avatar--text\" [class.size-sm]=\"headerAvatarSize === 'sm'\"\n [class.size-md]=\"headerAvatarSize === 'md'\" [class.size-lg]=\"headerAvatarSize === 'lg'\"\n [matTooltip]=\"headerPreview.tooltip || ''\" [matTooltipDisabled]=\"!headerPreview.tooltip\">\n {{ headerPreview.text }}\n </span>\n }\n @if (headerPreview.kind === 'placeholder') {\n <span class=\"section-heading__avatar section-heading__avatar--placeholder\" [class.size-sm]=\"headerAvatarSize === 'sm'\"\n [class.size-md]=\"headerAvatarSize === 'md'\" [class.size-lg]=\"headerAvatarSize === 'lg'\"\n [matTooltip]=\"headerPreview.tooltip || ''\" [matTooltipDisabled]=\"!headerPreview.tooltip\">\n @if (headerPreview.icon) {\n <mat-icon aria-hidden=\"true\" [praxisIcon]=\"headerPreview.icon\"></mat-icon>\n }\n </span>\n }\n <div class=\"section-heading__text\">\n <span class=\"section-name\">{{ section.title || 'Sem t\u00EDtulo' }}</span>\n @if (section.description) {\n <span class=\"section-desc\">{{ section.description }}</span>\n }\n </div>\n </div>\n <button praxisIconButton=\"edit\" size=\"dense\" type=\"button\"\n data-testid=\"section-rename-trigger\" (click)=\"startRename($event)\"\n [matTooltip]=\"t('section.rename.action')\" [attr.aria-label]=\"t('section.rename.action')\">\n </button>\n <button\n praxisIconButton=\"open_in_new\"\n size=\"dense\"\n type=\"button\"\n class=\"section-editor-trigger primary-action\"\n (click)=\"openAdvancedEditor($event)\"\n [matTooltip]=\"t('section.editor.hint')\"\n aria-label=\"Abrir editor da se\u00E7\u00E3o\"\n >\n </button>\n </mat-card-title>\n <div class=\"section-header-actions\">\n <button\n [praxisIconButton]=\"isCollapsed ? 'unfold_more' : 'unfold_less'\"\n size=\"dense\"\n class=\"section-collapse-btn\"\n type=\"button\"\n (click)=\"toggleCollapsed($event)\"\n [attr.aria-expanded]=\"!isCollapsed\"\n [attr.aria-label]=\"isCollapsed ? 'Expandir se\u00E7\u00E3o' : 'Colapsar se\u00E7\u00E3o'\"\n [matTooltip]=\"isCollapsed ? 'Expandir se\u00E7\u00E3o' : 'Colapsar se\u00E7\u00E3o'\"\n >\n </button>\n <button\n praxisIconButton=\"more_vert\"\n size=\"dense\"\n class=\"section-menu-btn\"\n [matMenuTriggerFor]=\"sectionMenu\"\n aria-label=\"Mais a\u00E7\u00F5es da se\u00E7\u00E3o\"\n matTooltip=\"Mais a\u00E7\u00F5es\"\n >\n </button>\n </div>\n <mat-menu #sectionMenu=\"matMenu\">\n <button mat-menu-item (click)=\"openSectionPresets()\">\n <mat-icon [praxisIcon]=\"'view_quilt'\"></mat-icon>\n <span>Presets de se\u00E7\u00E3o\u2026</span>\n </button>\n <button mat-menu-item (click)=\"applyCurrentStyleToAll()\">\n <mat-icon [praxisIcon]=\"'format_paint'\"></mat-icon>\n <span>Aplicar estilo desta se\u00E7\u00E3o a todas</span>\n </button>\n <mat-divider></mat-divider>\n @if (section.description == null) {\n <button mat-menu-item (click)=\"section.description = ''; onSectionUpdated()\">\n <mat-icon [praxisIcon]=\"'note_add'\"></mat-icon>\n <span>Adicionar descri\u00E7\u00E3o</span>\n </button>\n }\n @if (section.description != null) {\n <button mat-menu-item (click)=\"section.description = undefined; onSectionUpdated()\">\n <mat-icon [praxisIcon]=\"'backspace'\"></mat-icon>\n <span>Remover descri\u00E7\u00E3o</span>\n </button>\n }\n <mat-divider></mat-divider>\n <button mat-menu-item (click)=\"onRemoveSection()\">\n <mat-icon [praxisIcon]=\"'delete'\"></mat-icon>\n <span>Remover se\u00E7\u00E3o</span>\n </button>\n </mat-menu>\n </mat-card-header>\n <mat-card-content [attr.aria-hidden]=\"isCollapsed\">\n @if (renameDraft() !== null) {\n <div class=\"section-rename-controls\" role=\"group\" [attr.aria-label]=\"t('section.rename.action')\" (click)=\"$event.stopPropagation()\">\n <mat-form-field subscriptSizing=\"dynamic\">\n <mat-label>{{ t('section.rename.title') }}</mat-label>\n <input matInput data-testid=\"section-rename-input\" required\n [ngModel]=\"renameDraft()\" (ngModelChange)=\"renameDraft.set($event)\"\n (keydown.enter)=\"finishRename($event, true)\" (keydown.escape)=\"finishRename($event, false)\" />\n <mat-error>{{ t('section.rename.required') }}</mat-error>\n @if (renameDraft()?.length && !renameDraft()?.trim()) {\n <mat-hint>{{ t('section.rename.required') }}</mat-hint>\n }\n </mat-form-field>\n <button mat-stroked-button type=\"button\" [disabled]=\"!renameDraft()?.trim()\" (click)=\"finishRename($event, true)\">{{ t('section.rename.save') }}</button>\n <button mat-button type=\"button\" (click)=\"finishRename($event, false)\">{{ t('field.move.cancel') }}</button>\n </div>\n }\n @if (!section.rows.length) {\n <p class=\"section-empty-guidance\">{{ t('section.empty.guidance') }}</p>\n }\n @if (isThisSectionSelected()) {\n <div class=\"selection-context\" (click)=\"$event.stopPropagation()\" role=\"region\" [attr.aria-label]=\"t('selection.context')\">\n <nav class=\"section-breadcrumbs\" [attr.aria-label]=\"t('selection.path')\">\n <button\n type=\"button\"\n class=\"crumb as-button crumb-section\"\n data-crumb=\"section\"\n (click)=\"onSelectSectionFromBreadcrumb($event)\"\n [attr.aria-label]=\"section.title || t('selection.section', { index: sectionIndex + 1 })\"\n >\n {{ section.title || t('selection.section', { index: sectionIndex + 1 }) }}\n </button>\n @if (selected?.rowIndex != null) {\n <span class=\"sep\">\u203A</span>\n <button\n type=\"button\"\n class=\"crumb as-button crumb-row\"\n data-crumb=\"row\"\n (click)=\"onSelectRowFromBreadcrumb($event)\"\n [attr.aria-label]=\"t('selection.row', { index: selected!.rowIndex! + 1 })\"\n >\n {{ t('selection.row', { index: selected!.rowIndex! + 1 }) }}\n </button>\n }\n @if (selected?.columnIndex != null) {\n <span class=\"sep\">\u203A</span>\n <button\n type=\"button\"\n class=\"crumb as-button crumb-column\"\n data-crumb=\"column\"\n (click)=\"onSelectColumnFromBreadcrumb($event)\"\n [attr.aria-label]=\"t('selection.column', { index: selected!.columnIndex! + 1 })\"\n >\n {{ t('selection.column', { index: selected!.columnIndex! + 1 }) }}\n </button>\n }\n @if (selected?.fieldName) {\n <span class=\"sep\">\u203A</span>\n <span class=\"crumb active\">{{ selectedFieldLabel }}</span>\n }\n @if (selected) {\n <button\n type=\"button\"\n class=\"crumb as-button crumb-clear\"\n data-crumb=\"clear\"\n (click)=\"onClearSelectionFromBreadcrumb($event)\"\n [attr.aria-label]=\"t('selection.clear')\"\n >\n {{ t('selection.clear') }}\n </button>\n }\n </nav>\n <div class=\"selection-actions\">\n @if (selectedField) {\n <button mat-stroked-button type=\"button\" (click)=\"requestSelectedFieldMove($event)\">\n <mat-icon aria-hidden=\"true\">drive_file_move</mat-icon>{{ t('field.move.action') }}\n </button>\n <button mat-stroked-button type=\"button\" data-testid=\"layout-edit-selected-field\" (click)=\"editSelectedField($event)\">\n <mat-icon aria-hidden=\"true\">edit</mat-icon>{{ t('selection.editField') }}\n </button>\n }\n @if (selectedColumn) {\n <button mat-stroked-button type=\"button\" data-testid=\"layout-edit-selected-column\" (click)=\"editSelectedColumn($event)\">\n <mat-icon aria-hidden=\"true\">view_column</mat-icon>{{ t('selection.editColumn') }}\n </button>\n }\n </div>\n </div>\n } @else {\n <h5>Linhas</h5>\n }\n <div\n class=\"row-list\"\n cdkDropList\n [cdkDropListData]=\"section.rows\"\n (cdkDropListDropped)=\"dropRow($event)\"\n >\n @for (row of section.rows; track row; let i = $index) {\n <praxis-row-configurator\n class=\"row-item\"\n [row]=\"row\"\n [fieldMetadata]=\"fieldMetadata\"\n [availableFields]=\"availableFields\"\n [sectionIndex]=\"sectionIndex\"\n [rowIndex]=\"i\"\n [isLastRow]=\"i === section.rows.length - 1\"\n [selected]=\"selected\"\n [availableFieldsListId]=\"availableFieldsListId\"\n [connectedDropListIds]=\"columnDropListIds\"\n [gapGlobal]=\"gapGlobal\"\n (rowChange)=\"onRowUpdated(i, $event)\"\n (applyRowGapAll)=\"onApplyRowGapAll($event)\"\n (remove)=\"removeRow(i)\"\n (select)=\"select.emit($event)\"\n (fieldDrop)=\"onFieldDrop($event, i)\"\n (addVisualBlock)=\"onAddVisualBlock($event)\"\n (addApiField)=\"onAddApiField($event)\"\n (addLocalField)=\"onAddLocalField($event)\"\n (editField)=\"onEditField($event)\"\n (editVisualBlock)=\"onEditVisualBlock($event)\"\n (moveVisualBlock)=\"onMoveVisualBlock($event)\"\n (moveVisualBlockToColumn)=\"onMoveVisualBlockToColumn($event)\"\n (removeVisualBlock)=\"onRemoveVisualBlock($event)\"\n cdkDrag\n ></praxis-row-configurator>\n }\n </div>\n <div class=\"section-actions\" aria-label=\"A\u00E7\u00F5es da se\u00E7\u00E3o\">\n @if (!section.rows.length) {\n <button mat-stroked-button type=\"button\" (click)=\"addRow()\">\n <mat-icon aria-hidden=\"true\">add</mat-icon>{{ t('section.empty.addRow') }}\n </button>\n } @else {\n <button\n class=\"fab-add-row\"\n mat-fab\n color=\"primary\"\n (click)=\"addRow()\"\n matTooltip=\"Adicionar linha\"\n aria-label=\"Adicionar linha\"\n >\n <mat-icon>add</mat-icon>\n </button>\n }\n </div>\n </mat-card-content>\n</mat-card>\n", styles: ["@charset \"UTF-8\";.section-card{background:var(--md-sys-color-surface, var(--sicoob-bg-elev-1));margin-bottom:16px;transition:border-color .2s ease;border:1px solid transparent;box-sizing:border-box;max-width:100%;min-width:0}.section-card.hovered{border-color:var(--md-sys-color-primary, var(--md-sys-color-primary, var(--sicoob-primary-default)))}.section-card.selected{border-color:var(--md-sys-color-primary, var(--md-sys-color-primary, var(--sicoob-primary-default)));box-shadow:0 0 0 2px var(--md-sys-color-primary)}.section-card.cdk-drag-dragging{cursor:grabbing}.section-card.cdk-drag-preview{box-sizing:border-box;border-color:var(--md-sys-color-primary, var(--sicoob-primary-default));box-shadow:var(--md-sys-elevation-level3);cursor:grabbing}.section-card.cdk-drag-placeholder{position:relative;min-height:64px;border-color:transparent;background:transparent;box-shadow:none;opacity:1}.section-card.cdk-drag-placeholder>*{visibility:hidden}.section-card.cdk-drag-placeholder:before{content:\"\";position:absolute;inset:calc(50% - 1px) 12px auto 12px;height:2px;border-radius:999px;background:var(--md-sys-color-primary, var(--sicoob-primary-default));box-shadow:0 0 0 3px color-mix(in srgb,var(--md-sys-color-primary, var(--sicoob-primary-default)) 16%,transparent)}.section-card.cdk-drag-placeholder:after{content:\"\";position:absolute;top:calc(50% - 5px);left:12px;width:10px;height:10px;border-radius:50%;background:var(--md-sys-color-primary, var(--sicoob-primary-default))}.section-card:focus-visible{outline:2px solid var(--md-sys-color-primary, var(--md-sys-color-primary, var(--sicoob-primary-default)));outline-offset:2px}.section-card .mat-mdc-card-content{padding-bottom:var(--px-editor-section-gap, 16px)}.section-breadcrumbs{font-size:12px;color:var(--md-sys-color-on-surface-variant);margin:4px 0 8px;display:flex;align-items:center;gap:6px}.section-breadcrumbs .as-button{background:transparent;border:none;padding:0 2px;color:inherit;font:inherit;cursor:pointer;border-radius:4px}.section-breadcrumbs .as-button:hover{color:var(--md-sys-color-primary, var(--md-sys-color-primary, var(--sicoob-primary-default)))}.section-breadcrumbs .as-button:focus-visible{outline:2px solid var(--md-sys-color-primary, var(--md-sys-color-primary, var(--sicoob-primary-default)));outline-offset:2px}.section-breadcrumbs .crumb-clear{margin-left:6px;opacity:.85}.section-breadcrumbs .crumb.active{color:var(--md-sys-color-on-surface);font-weight:600}.section-breadcrumbs .sep{opacity:.6}.section-header{display:flex;justify-content:space-between;align-items:center;gap:12px;min-height:56px;min-width:0}.title-wrapper{display:flex;align-items:center;gap:8px;width:100%;min-width:0;flex:1 1 auto}.section-heading{display:flex;align-items:center;gap:10px;min-width:0}.section-heading__icon{color:var(--md-sys-color-primary, var(--md-sys-color-primary, var(--sicoob-primary-default)))}.section-heading__avatar{--_pfx-layout-section-avatar-size: var(--pfx-form-section-avatar-size-md, var(--pfx-form-section-avatar-size, 32px));display:inline-flex;align-items:center;justify-content:center;width:var(--_pfx-layout-section-avatar-size);height:var(--_pfx-layout-section-avatar-size);border-radius:999px;flex:0 0 var(--_pfx-layout-section-avatar-size);overflow:hidden}.section-heading__avatar.size-sm{--_pfx-layout-section-avatar-size: var(--pfx-form-section-avatar-size-sm, 24px)}.section-heading__avatar.size-md{--_pfx-layout-section-avatar-size: var(--pfx-form-section-avatar-size-md, var(--pfx-form-section-avatar-size, 32px))}.section-heading__avatar.size-lg{--_pfx-layout-section-avatar-size: var(--pfx-form-section-avatar-size-lg, 40px)}.section-heading__avatar--text,.section-heading__avatar--placeholder{background:color-mix(in srgb,var(--pfx-editorial-form-accent, var(--md-sys-color-primary, var(--sicoob-primary-default))) 14%,var(--pfx-form-section-surface-flat, var(--md-sys-color-surface, var(--sicoob-bg-elev-1))));color:color-mix(in srgb,var(--pfx-editorial-form-accent, var(--md-sys-color-primary, var(--sicoob-primary-default))) 82%,var(--pfx-form-label-strong, var(--md-sys-color-on-surface, var(--sicoob-text-default))) 18%);font-size:calc(var(--_pfx-layout-section-avatar-size) * .41);font-weight:800;letter-spacing:.04em;text-transform:uppercase}.section-heading__avatar--placeholder mat-icon{font-size:calc(var(--_pfx-layout-section-avatar-size) * .5625);width:calc(var(--_pfx-layout-section-avatar-size) * .5625);height:calc(var(--_pfx-layout-section-avatar-size) * .5625);line-height:calc(var(--_pfx-layout-section-avatar-size) * .5625)}.section-heading__text{display:flex;flex-direction:column;align-items:flex-start;min-width:0}.section-heading .section-name{font-weight:600;color:var(--md-sys-color-on-surface);overflow:hidden;text-overflow:ellipsis;white-space:nowrap}.section-heading .section-desc{font-size:12px;color:var(--md-sys-color-on-surface-variant);margin-top:2px;overflow:hidden;text-overflow:ellipsis;white-space:nowrap}.section-editor-trigger{margin-left:auto}.section-editor-trigger.primary-action{color:var(--md-sys-color-primary)}.section-header-actions{display:inline-flex;align-items:center;gap:4px;flex-shrink:0}.add-row-button{margin-top:8px}.row-item{animation:fadeIn .3s ease}.row-item.cdk-drag-dragging{cursor:grabbing}.row-item.cdk-drag-preview{box-sizing:border-box;border-radius:8px;background:var(--md-sys-color-surface-container, var(--md-sys-color-surface));box-shadow:var(--md-sys-elevation-level3);cursor:grabbing}.row-item.cdk-drag-placeholder{position:relative;display:block;min-height:56px;opacity:1}.row-item.cdk-drag-placeholder>*{visibility:hidden}.row-item.cdk-drag-placeholder:before{content:\"\";position:absolute;inset:calc(50% - 1px) 8px auto 8px;height:2px;border-radius:999px;background:var(--md-sys-color-primary, var(--sicoob-primary-default));box-shadow:0 0 0 3px color-mix(in srgb,var(--md-sys-color-primary, var(--sicoob-primary-default)) 16%,transparent)}.row-item.cdk-drag-placeholder:after{content:\"\";position:absolute;top:calc(50% - 4px);left:8px;width:8px;height:8px;border-radius:50%;background:var(--md-sys-color-primary, var(--sicoob-primary-default))}@keyframes fadeIn{0%{opacity:0;transform:translateY(-4px)}to{opacity:1;transform:none}}.section-card:hover{border-color:var(--md-sys-color-primary, var(--md-sys-color-primary, var(--sicoob-primary-default)))}.section-card.collapsed .mat-mdc-card-content{display:none}:host ::ng-deep .section-card .mat-mdc-card-header{padding:8px 12px}:host ::ng-deep .section-card .mat-mdc-card-title{margin:0}:host ::ng-deep .section-card .mat-mdc-card-content{padding:0 12px 12px}.section-actions{position:relative;margin-top:12px;padding-top:16px;border-top:1px solid var(--md-sys-color-outline-variant, var(--md-sys-color-outline-variant, var(--sicoob-stroke-medium)));min-height:28px}.row-list{border-top:1px solid var(--px-editor-separator-color, var(--md-sys-color-outline-variant));padding-top:12px;margin-top:8px;min-width:0}.fab-add-row{position:absolute;top:-15px;left:50%;transform:translate(-50%,calc(-50% - var(--pfx-divider-w, 1px)));z-index:2;--pfx-fab-size: var(--pfx-fab-size-row, 32px);--pfx-fab-icon: var(--pfx-fab-icon-row, 18px);width:var(--pfx-fab-size);height:var(--pfx-fab-size);border-radius:50%}.fab-add-row.mat-mdc-fab{width:var(--pfx-fab-size);height:var(--pfx-fab-size);padding:0}.fab-add-row .mat-mdc-button-touch-target,.fab-add-row .mat-mdc-button-persistent-ripple,.fab-add-row .mat-mdc-button-ripple{width:var(--pfx-fab-size);height:var(--pfx-fab-size)}.fab-add-row mat-icon{font-size:var(--pfx-fab-icon);width:var(--pfx-fab-icon);height:var(--pfx-fab-icon)}@media(max-width:700px){.section-header{position:relative;align-items:flex-start;display:block;min-height:88px;padding-right:12px}.title-wrapper{align-items:flex-start;padding-right:132px;width:auto}.section-heading{align-items:flex-start;gap:12px}.section-heading__icon{margin-top:4px}.section-heading .section-name{font-size:20px;line-height:26px}.section-header-actions{position:absolute;top:12px;right:12px;margin-left:0}.section-editor-trigger{position:absolute;top:12px;right:88px;margin-left:0}.section-heading .section-name,.section-heading .section-desc{overflow:visible;text-overflow:clip;white-space:normal}}.selection-context{padding-block:calc(var(--px-editor-section-gap, 1rem) / 2);border-block-end:1px solid var(--md-sys-color-outline-variant);margin-block-end:calc(var(--px-editor-section-gap, 1rem) / 2)}.selection-actions{display:flex;flex-wrap:wrap;gap:calc(var(--px-editor-section-gap, 1rem) / 2)}.selection-context .section-breadcrumbs{flex-wrap:wrap}.selection-context .crumb{overflow-wrap:anywhere;min-width:0}.section-rename-controls{display:flex;flex-wrap:wrap;align-items:center;gap:var(--px-editor-section-gap, 1rem);margin-block-end:var(--px-editor-section-gap, 1rem)}.section-rename-controls mat-form-field{flex:1 1 100%;min-width:0}.section-empty-guidance{color:var(--md-sys-color-on-surface-variant);font:var(--md-sys-typescale-body-medium)}\n"] }]
|
|
24897
|
+
], providers: [providePraxisI18nConfig(LAYOUT_EDITOR_I18N_CONFIG)], template: "<mat-card\n class=\"section-card\"\n cdkDrag\n (mouseenter)=\"onMouseEnter()\"\n (mouseleave)=\"onMouseLeave()\"\n [class.hovered]=\"isHovered\"\n [class.selected]=\"isThisSectionSelected()\"\n [class.collapsed]=\"isCollapsed\"\n (click)=\"onSelectSection()\"\n tabindex=\"0\"\n role=\"button\"\n [attr.aria-label]=\"'Se\u00E7\u00E3o ' + (sectionIndex + 1)\"\n [attr.aria-selected]=\"isThisSectionSelected()\"\n >\n <mat-card-header class=\"section-header\">\n <mat-card-title class=\"title-wrapper\">\n <div class=\"section-heading\">\n @let headerPreview = getSectionHeaderPreview();\n @let headerAvatarSize = getSectionHeaderAvatarSize();\n @if (headerPreview.kind === 'icon') {\n <mat-icon class=\"section-heading__icon\" aria-hidden=\"true\" [praxisIcon]=\"headerPreview.icon\"></mat-icon>\n }\n @if (headerPreview.kind === 'initials') {\n <span class=\"section-heading__avatar section-heading__avatar--text\" [class.size-sm]=\"headerAvatarSize === 'sm'\"\n [class.size-md]=\"headerAvatarSize === 'md'\" [class.size-lg]=\"headerAvatarSize === 'lg'\"\n [matTooltip]=\"headerPreview.tooltip || ''\" [matTooltipDisabled]=\"!headerPreview.tooltip\">\n {{ headerPreview.text }}\n </span>\n }\n @if (headerPreview.kind === 'placeholder') {\n <span class=\"section-heading__avatar section-heading__avatar--placeholder\" [class.size-sm]=\"headerAvatarSize === 'sm'\"\n [class.size-md]=\"headerAvatarSize === 'md'\" [class.size-lg]=\"headerAvatarSize === 'lg'\"\n [matTooltip]=\"headerPreview.tooltip || ''\" [matTooltipDisabled]=\"!headerPreview.tooltip\">\n @if (headerPreview.icon) {\n <mat-icon aria-hidden=\"true\" [praxisIcon]=\"headerPreview.icon\"></mat-icon>\n }\n </span>\n }\n <div class=\"section-heading__text\">\n <span class=\"section-name\">{{ section.title || 'Sem t\u00EDtulo' }}</span>\n @if (section.description) {\n <span class=\"section-desc\">{{ section.description }}</span>\n }\n </div>\n </div>\n <button praxisIconButton=\"edit\" size=\"dense\" type=\"button\"\n data-testid=\"section-rename-trigger\" (click)=\"startRename($event)\"\n [matTooltip]=\"t('section.rename.action')\" [attr.aria-label]=\"t('section.rename.action')\">\n </button>\n <button\n praxisIconButton=\"open_in_new\"\n size=\"dense\"\n type=\"button\"\n class=\"section-editor-trigger primary-action\"\n (click)=\"openAdvancedEditor($event)\"\n [matTooltip]=\"t('section.editor.hint')\"\n aria-label=\"Abrir editor da se\u00E7\u00E3o\"\n >\n </button>\n </mat-card-title>\n <div class=\"section-header-actions\">\n <button\n [praxisIconButton]=\"isCollapsed ? 'unfold_more' : 'unfold_less'\"\n size=\"dense\"\n class=\"section-collapse-btn\"\n type=\"button\"\n (click)=\"toggleCollapsed($event)\"\n [attr.aria-expanded]=\"!isCollapsed\"\n [attr.aria-label]=\"isCollapsed ? 'Expandir se\u00E7\u00E3o' : 'Colapsar se\u00E7\u00E3o'\"\n [matTooltip]=\"isCollapsed ? 'Expandir se\u00E7\u00E3o' : 'Colapsar se\u00E7\u00E3o'\"\n >\n </button>\n <button\n praxisIconButton=\"more_vert\"\n size=\"dense\"\n class=\"section-menu-btn\"\n [matMenuTriggerFor]=\"sectionMenu\"\n aria-label=\"Mais a\u00E7\u00F5es da se\u00E7\u00E3o\"\n matTooltip=\"Mais a\u00E7\u00F5es\"\n >\n </button>\n </div>\n <mat-menu #sectionMenu=\"matMenu\">\n <button mat-menu-item (click)=\"openSectionPresets()\">\n <mat-icon [praxisIcon]=\"'view_quilt'\"></mat-icon>\n <span>Presets de se\u00E7\u00E3o\u2026</span>\n </button>\n <button mat-menu-item (click)=\"applyCurrentStyleToAll()\">\n <mat-icon [praxisIcon]=\"'format_paint'\"></mat-icon>\n <span>Aplicar estilo desta se\u00E7\u00E3o a todas</span>\n </button>\n <mat-divider></mat-divider>\n @if (section.description == null) {\n <button mat-menu-item (click)=\"section.description = ''; onSectionUpdated()\">\n <mat-icon [praxisIcon]=\"'note_add'\"></mat-icon>\n <span>Adicionar descri\u00E7\u00E3o</span>\n </button>\n }\n @if (section.description != null) {\n <button mat-menu-item (click)=\"section.description = undefined; onSectionUpdated()\">\n <mat-icon [praxisIcon]=\"'backspace'\"></mat-icon>\n <span>Remover descri\u00E7\u00E3o</span>\n </button>\n }\n <mat-divider></mat-divider>\n <button mat-menu-item (click)=\"onRemoveSection()\">\n <mat-icon [praxisIcon]=\"'delete'\"></mat-icon>\n <span>Remover se\u00E7\u00E3o</span>\n </button>\n </mat-menu>\n </mat-card-header>\n <mat-card-content [attr.aria-hidden]=\"isCollapsed\">\n @if (renameDraft() !== null) {\n <div class=\"section-rename-controls\" role=\"group\" [attr.aria-label]=\"t('section.rename.action')\" (click)=\"$event.stopPropagation()\">\n <mat-form-field subscriptSizing=\"dynamic\">\n <mat-label>{{ t('section.rename.title') }}</mat-label>\n <input matInput data-testid=\"section-rename-input\" required\n [ngModel]=\"renameDraft()\" (ngModelChange)=\"renameDraft.set($event)\"\n (keydown.enter)=\"finishRename($event, true)\" (keydown.escape)=\"finishRename($event, false)\" />\n <mat-error>{{ t('section.rename.required') }}</mat-error>\n @if (renameDraft()?.length && !renameDraft()?.trim()) {\n <mat-hint>{{ t('section.rename.required') }}</mat-hint>\n }\n </mat-form-field>\n <button mat-stroked-button type=\"button\" [disabled]=\"!renameDraft()?.trim()\" (click)=\"finishRename($event, true)\">{{ t('section.rename.save') }}</button>\n <button mat-button type=\"button\" (click)=\"finishRename($event, false)\">{{ t('field.move.cancel') }}</button>\n </div>\n }\n @if (!section.rows.length) {\n <p class=\"section-empty-guidance\">{{ t('section.empty.guidance') }}</p>\n }\n @if (isThisSectionSelected()) {\n <div class=\"selection-context\" (click)=\"$event.stopPropagation()\" role=\"region\" [attr.aria-label]=\"t('selection.context')\">\n <nav class=\"section-breadcrumbs\" [attr.aria-label]=\"t('selection.path')\">\n <button\n type=\"button\"\n class=\"crumb as-button crumb-section\"\n data-crumb=\"section\"\n (click)=\"onSelectSectionFromBreadcrumb($event)\"\n [attr.aria-label]=\"section.title || t('selection.section', { index: sectionIndex + 1 })\"\n >\n {{ section.title || t('selection.section', { index: sectionIndex + 1 }) }}\n </button>\n @if (selected?.rowIndex != null) {\n <span class=\"sep\">\u203A</span>\n <button\n type=\"button\"\n class=\"crumb as-button crumb-row\"\n data-crumb=\"row\"\n (click)=\"onSelectRowFromBreadcrumb($event)\"\n [attr.aria-label]=\"t('selection.row', { index: selected!.rowIndex! + 1 })\"\n >\n {{ t('selection.row', { index: selected!.rowIndex! + 1 }) }}\n </button>\n }\n @if (selected?.columnIndex != null) {\n <span class=\"sep\">\u203A</span>\n <button\n type=\"button\"\n class=\"crumb as-button crumb-column\"\n data-crumb=\"column\"\n (click)=\"onSelectColumnFromBreadcrumb($event)\"\n [attr.aria-label]=\"t('selection.column', { index: selected!.columnIndex! + 1 })\"\n >\n {{ t('selection.column', { index: selected!.columnIndex! + 1 }) }}\n </button>\n }\n @if (selected?.fieldName) {\n <span class=\"sep\">\u203A</span>\n <span class=\"crumb active\">{{ selectedFieldLabel }}</span>\n }\n @if (selected) {\n <button\n type=\"button\"\n class=\"crumb as-button crumb-clear\"\n data-crumb=\"clear\"\n (click)=\"onClearSelectionFromBreadcrumb($event)\"\n [attr.aria-label]=\"t('selection.clear')\"\n >\n {{ t('selection.clear') }}\n </button>\n }\n </nav>\n <div class=\"selection-actions\">\n @if (selectedField) {\n <button mat-stroked-button type=\"button\" (click)=\"requestSelectedFieldMove($event)\">\n <mat-icon aria-hidden=\"true\">drive_file_move</mat-icon>{{ t('field.move.action') }}\n </button>\n <button mat-stroked-button type=\"button\" data-testid=\"layout-edit-selected-field\" (click)=\"editSelectedField($event)\">\n <mat-icon aria-hidden=\"true\">edit</mat-icon>{{ t('selection.editField') }}\n </button>\n }\n @if (selectedColumn) {\n <button mat-stroked-button type=\"button\" data-testid=\"layout-edit-selected-column\" (click)=\"editSelectedColumn($event)\">\n <mat-icon aria-hidden=\"true\">view_column</mat-icon>{{ t('selection.editColumn') }}\n </button>\n }\n </div>\n </div>\n } @else {\n <h5>Linhas</h5>\n }\n <div\n class=\"row-list\"\n cdkDropList\n [cdkDropListData]=\"section.rows\"\n (cdkDropListDropped)=\"dropRow($event)\"\n >\n @for (row of section.rows; track row; let i = $index) {\n <praxis-row-configurator\n class=\"row-item\"\n [row]=\"row\"\n [fieldMetadata]=\"fieldMetadata\"\n [availableFields]=\"availableFields\"\n [sectionIndex]=\"sectionIndex\"\n [rowIndex]=\"i\"\n [isLastRow]=\"i === section.rows.length - 1\"\n [selected]=\"selected\"\n [availableFieldsListId]=\"availableFieldsListId\"\n [connectedDropListIds]=\"columnDropListIds\"\n [gapGlobal]=\"gapGlobal\"\n (rowChange)=\"onRowUpdated(i, $event)\"\n (applyRowGapAll)=\"onApplyRowGapAll($event)\"\n (remove)=\"removeRow(i)\"\n (select)=\"select.emit($event)\"\n (fieldDrop)=\"onFieldDrop($event, i)\"\n (addVisualBlock)=\"onAddVisualBlock($event)\"\n (addApiField)=\"onAddApiField($event)\"\n (addLocalField)=\"onAddLocalField($event)\"\n (editField)=\"onEditField($event)\"\n (editVisualBlock)=\"onEditVisualBlock($event)\"\n (moveVisualBlock)=\"onMoveVisualBlock($event)\"\n (moveVisualBlockToColumn)=\"onMoveVisualBlockToColumn($event)\"\n (removeVisualBlock)=\"onRemoveVisualBlock($event)\"\n cdkDrag\n ></praxis-row-configurator>\n }\n </div>\n <div class=\"section-actions\" aria-label=\"A\u00E7\u00F5es da se\u00E7\u00E3o\">\n @if (!section.rows.length) {\n <button mat-stroked-button type=\"button\" (click)=\"addRow()\">\n <mat-icon aria-hidden=\"true\">add</mat-icon>{{ t('section.empty.addRow') }}\n </button>\n } @else {\n <button\n class=\"fab-add-row\"\n mat-fab\n color=\"primary\"\n (click)=\"addRow()\"\n matTooltip=\"Adicionar linha\"\n aria-label=\"Adicionar linha\"\n >\n <mat-icon>add</mat-icon>\n </button>\n }\n </div>\n </mat-card-content>\n</mat-card>\n", styles: ["@charset \"UTF-8\";.section-card{background:var(--md-sys-color-surface);margin-bottom:16px;transition:border-color .2s ease;border:1px solid transparent;box-sizing:border-box;max-width:100%;min-width:0}.section-card.hovered{border-color:var(--md-sys-color-primary)}.section-card.selected{border-color:var(--md-sys-color-primary);box-shadow:0 0 0 2px var(--md-sys-color-primary)}.section-card.cdk-drag-dragging{cursor:grabbing}.section-card.cdk-drag-preview{box-sizing:border-box;border-color:var(--md-sys-color-primary);box-shadow:var(--md-sys-elevation-level3);cursor:grabbing}.section-card.cdk-drag-placeholder{position:relative;min-height:64px;border-color:transparent;background:transparent;box-shadow:none;opacity:1}.section-card.cdk-drag-placeholder>*{visibility:hidden}.section-card.cdk-drag-placeholder:before{content:\"\";position:absolute;inset:calc(50% - 1px) 12px auto 12px;height:2px;border-radius:999px;background:var(--md-sys-color-primary);box-shadow:0 0 0 3px color-mix(in srgb,var(--md-sys-color-primary) 16%,transparent)}.section-card.cdk-drag-placeholder:after{content:\"\";position:absolute;top:calc(50% - 5px);left:12px;width:10px;height:10px;border-radius:50%;background:var(--md-sys-color-primary)}.section-card:focus-visible{outline:2px solid var(--md-sys-color-primary);outline-offset:2px}.section-card .mat-mdc-card-content{padding-bottom:var(--px-editor-section-gap, 16px)}.section-breadcrumbs{font-size:12px;color:var(--md-sys-color-on-surface-variant);margin:4px 0 8px;display:flex;align-items:center;gap:6px}.section-breadcrumbs .as-button{background:transparent;border:none;padding:0 2px;color:inherit;font:inherit;cursor:pointer;border-radius:4px}.section-breadcrumbs .as-button:hover{color:var(--md-sys-color-primary)}.section-breadcrumbs .as-button:focus-visible{outline:2px solid var(--md-sys-color-primary);outline-offset:2px}.section-breadcrumbs .crumb-clear{margin-left:6px;opacity:.85}.section-breadcrumbs .crumb.active{color:var(--md-sys-color-on-surface);font-weight:600}.section-breadcrumbs .sep{opacity:.6}.section-header{display:flex;justify-content:space-between;align-items:center;gap:12px;min-height:56px;min-width:0}.title-wrapper{display:flex;align-items:center;gap:8px;width:100%;min-width:0;flex:1 1 auto}.section-heading{display:flex;align-items:center;gap:10px;min-width:0}.section-heading__icon{color:var(--md-sys-color-primary)}.section-heading__avatar{--_pfx-layout-section-avatar-size: var(--pfx-form-section-avatar-size-md, var(--pfx-form-section-avatar-size, 32px));display:inline-flex;align-items:center;justify-content:center;width:var(--_pfx-layout-section-avatar-size);height:var(--_pfx-layout-section-avatar-size);border-radius:999px;flex:0 0 var(--_pfx-layout-section-avatar-size);overflow:hidden}.section-heading__avatar.size-sm{--_pfx-layout-section-avatar-size: var(--pfx-form-section-avatar-size-sm, 24px)}.section-heading__avatar.size-md{--_pfx-layout-section-avatar-size: var(--pfx-form-section-avatar-size-md, var(--pfx-form-section-avatar-size, 32px))}.section-heading__avatar.size-lg{--_pfx-layout-section-avatar-size: var(--pfx-form-section-avatar-size-lg, 40px)}.section-heading__avatar--text,.section-heading__avatar--placeholder{background:color-mix(in srgb,var(--pfx-editorial-form-accent, var(--md-sys-color-primary)) 14%,var(--pfx-form-section-surface-flat, var(--md-sys-color-surface)));color:color-mix(in srgb,var(--pfx-editorial-form-accent, var(--md-sys-color-primary)) 82%,var(--pfx-form-label-strong, var(--md-sys-color-on-surface)) 18%);font-size:calc(var(--_pfx-layout-section-avatar-size) * .41);font-weight:800;letter-spacing:.04em;text-transform:uppercase}.section-heading__avatar--placeholder mat-icon{font-size:calc(var(--_pfx-layout-section-avatar-size) * .5625);width:calc(var(--_pfx-layout-section-avatar-size) * .5625);height:calc(var(--_pfx-layout-section-avatar-size) * .5625);line-height:calc(var(--_pfx-layout-section-avatar-size) * .5625)}.section-heading__text{display:flex;flex-direction:column;align-items:flex-start;min-width:0}.section-heading .section-name{font-weight:600;color:var(--md-sys-color-on-surface);overflow:hidden;text-overflow:ellipsis;white-space:nowrap}.section-heading .section-desc{font-size:12px;color:var(--md-sys-color-on-surface-variant);margin-top:2px;overflow:hidden;text-overflow:ellipsis;white-space:nowrap}.section-editor-trigger{margin-left:auto}.section-editor-trigger.primary-action{color:var(--md-sys-color-primary)}.section-header-actions{display:inline-flex;align-items:center;gap:4px;flex-shrink:0}.add-row-button{margin-top:8px}.row-item{animation:fadeIn .3s ease}.row-item.cdk-drag-dragging{cursor:grabbing}.row-item.cdk-drag-preview{box-sizing:border-box;border-radius:8px;background:var(--md-sys-color-surface-container, var(--md-sys-color-surface));box-shadow:var(--md-sys-elevation-level3);cursor:grabbing}.row-item.cdk-drag-placeholder{position:relative;display:block;min-height:56px;opacity:1}.row-item.cdk-drag-placeholder>*{visibility:hidden}.row-item.cdk-drag-placeholder:before{content:\"\";position:absolute;inset:calc(50% - 1px) 8px auto 8px;height:2px;border-radius:999px;background:var(--md-sys-color-primary);box-shadow:0 0 0 3px color-mix(in srgb,var(--md-sys-color-primary) 16%,transparent)}.row-item.cdk-drag-placeholder:after{content:\"\";position:absolute;top:calc(50% - 4px);left:8px;width:8px;height:8px;border-radius:50%;background:var(--md-sys-color-primary)}@keyframes fadeIn{0%{opacity:0;transform:translateY(-4px)}to{opacity:1;transform:none}}.section-card:hover{border-color:var(--md-sys-color-primary)}.section-card.collapsed .mat-mdc-card-content{display:none}:host ::ng-deep .section-card .mat-mdc-card-header{padding:8px 12px}:host ::ng-deep .section-card .mat-mdc-card-title{margin:0}:host ::ng-deep .section-card .mat-mdc-card-content{padding:0 12px 12px}.section-actions{position:relative;margin-top:12px;padding-top:16px;border-top:1px solid var(--md-sys-color-outline-variant);min-height:28px}.row-list{border-top:1px solid var(--px-editor-separator-color, var(--md-sys-color-outline-variant));padding-top:12px;margin-top:8px;min-width:0}.fab-add-row{position:absolute;top:-15px;left:50%;transform:translate(-50%,calc(-50% - var(--pfx-divider-w, 1px)));z-index:2;--pfx-fab-size: var(--pfx-fab-size-row, 32px);--pfx-fab-icon: var(--pfx-fab-icon-row, 18px);width:var(--pfx-fab-size);height:var(--pfx-fab-size);border-radius:50%}.fab-add-row.mat-mdc-fab{width:var(--pfx-fab-size);height:var(--pfx-fab-size);padding:0}.fab-add-row .mat-mdc-button-touch-target,.fab-add-row .mat-mdc-button-persistent-ripple,.fab-add-row .mat-mdc-button-ripple{width:var(--pfx-fab-size);height:var(--pfx-fab-size)}.fab-add-row mat-icon{font-size:var(--pfx-fab-icon);width:var(--pfx-fab-icon);height:var(--pfx-fab-icon)}@media(max-width:700px){.section-header{position:relative;align-items:flex-start;display:block;min-height:88px;padding-right:12px}.title-wrapper{align-items:flex-start;padding-right:132px;width:auto}.section-heading{align-items:flex-start;gap:12px}.section-heading__icon{margin-top:4px}.section-heading .section-name{font-size:20px;line-height:26px}.section-header-actions{position:absolute;top:12px;right:12px;margin-left:0}.section-editor-trigger{position:absolute;top:12px;right:88px;margin-left:0}.section-heading .section-name,.section-heading .section-desc{overflow:visible;text-overflow:clip;white-space:normal}}.selection-context{padding-block:calc(var(--px-editor-section-gap, 1rem) / 2);border-block-end:1px solid var(--md-sys-color-outline-variant);margin-block-end:calc(var(--px-editor-section-gap, 1rem) / 2)}.selection-actions{display:flex;flex-wrap:wrap;gap:calc(var(--px-editor-section-gap, 1rem) / 2)}.selection-context .section-breadcrumbs{flex-wrap:wrap}.selection-context .crumb{overflow-wrap:anywhere;min-width:0}.section-rename-controls{display:flex;flex-wrap:wrap;align-items:center;gap:var(--px-editor-section-gap, 1rem);margin-block-end:var(--px-editor-section-gap, 1rem)}.section-rename-controls mat-form-field{flex:1 1 100%;min-width:0}.section-empty-guidance{color:var(--md-sys-color-on-surface-variant);font:var(--md-sys-typescale-body-medium)}\n"] }]
|
|
24657
24898
|
}], ctorParameters: () => [{ type: i2$1.MatDialog }, { type: SectionPresetRegistry }, { type: i7.SettingsPanelService }], propDecorators: { section: [{
|
|
24658
24899
|
type: Input
|
|
24659
24900
|
}], sectionIndex: [{
|
|
@@ -25798,7 +26039,7 @@ class LayoutEditorComponent {
|
|
|
25798
26039
|
</div>
|
|
25799
26040
|
</div>
|
|
25800
26041
|
</div>
|
|
25801
|
-
`, isInline: true, styles: [".layout-editor-wrapper{display:flex;flex-wrap:wrap;gap:16px;min-width:0;width:100%}.layout-editor-wrapper.no-available-fields{flex-direction:column;gap:0}.editor-toolbar{position:sticky;top:0;z-index:3;display:flex;flex-wrap:wrap;gap:16px;align-items:center;min-height:56px;background:var(--md-sys-color-surface-container);border-bottom:1px solid var(--md-sys-color-outline-variant);box-shadow:var(--md-sys-elevation-level1, var(--md-sys-elevation-level1));padding:0 12px;margin:0 0 var(--px-editor-section-gap, 16px) 0;width:100%;box-sizing:border-box;height:auto;white-space:normal}.editor-toolbar .title-block{display:flex;flex-direction:column;justify-content:center;gap:2px}.editor-toolbar .toolbar-title{font:var(--mdc-typography-title-small, 600 15px/20px system-ui);color:var(--md-sys-color-on-surface)}.editor-toolbar .toolbar-subtitle{font:var(--mdc-typography-body-small, 400 12px/16px system-ui);color:var(--md-sys-color-on-surface-variant)}.editor-toolbar .spacer{flex:1 1 auto}.editor-toolbar .toolbar-group{display:inline-flex;align-items:center;gap:8px;flex-wrap:wrap;min-width:0}.editor-toolbar .gap-group{align-items:center}.editor-toolbar .group-label{font:var(--mdc-typography-label-medium, 500 12px/16px system-ui);color:var(--md-sys-color-on-surface-variant)}.editor-toolbar .gap-group{align-items:center;gap:10px}.editor-toolbar .density-control{display:flex;align-items:center;gap:8px}.editor-toolbar .density-label{font:var(--mdc-typography-label-medium, 500 12px/16px system-ui);opacity:.9}.editor-toolbar .density-toggle,.editor-toolbar .toggle-icons-group{border:1px solid var(--md-sys-color-outline-variant);border-radius:999px;overflow:hidden;background:var(--md-sys-color-surface-container-low)}.editor-toolbar .density-toggle .mat-button-toggle,.editor-toolbar .toggle-icons-group .mat-button-toggle{background:var(--md-sys-color-surface-container-low);color:var(--md-sys-color-on-surface-variant)}.editor-toolbar .density-toggle .mat-button-toggle+.mat-button-toggle,.editor-toolbar .toggle-icons-group .mat-button-toggle+.mat-button-toggle{border-left:1px solid var(--md-sys-color-outline-variant)}.editor-toolbar .density-toggle .mat-button-toggle-button,.toggle-icons-group .mat-button-toggle-button{height:32px}.editor-toolbar .density-toggle .mat-icon,.toggle-icons-group .mat-icon{font-size:20px;width:20px;height:20px;line-height:20px}.editor-toolbar .density-toggle .mat-icon,.editor-toolbar .toggle-icons-group .mat-icon{color:inherit}.gap-chip{display:inline-flex;align-items:center;gap:2px;padding:0 4px;min-height:40px;border-radius:8px;border:1px solid var(--md-sys-color-outline-variant);background:var(--md-sys-color-surface-variant)}.gap-chip__input{width:42px;border:none;background:transparent;color:var(--md-sys-color-on-surface);font:var(--mdc-typography-body-medium, 600 13px/18px system-ui);text-align:center;outline:none;-moz-appearance:textfield}.gap-chip__input::-webkit-outer-spin-button,.gap-chip__input::-webkit-inner-spin-button{-webkit-appearance:none;margin:0}.gap-chip__suffix{color:var(--md-sys-color-on-surface-variant);font:var(--mdc-typography-label-medium, 500 12px/16px system-ui)}.pill{display:inline-flex;align-items:center;gap:6px;padding:4px 8px;border-radius:12px;background:var(--md-sys-color-surface-variant);color:var(--md-sys-color-on-surface-variant);font-size:12px}.pill.subtle{background:transparent;color:var(--md-sys-color-on-surface-variant);padding-left:0}.available-fields{width:250px;border:1px solid var(--md-sys-color-outline-variant);border-radius:12px;padding:10px;background:var(--md-sys-color-surface)}.collapse-toggle{float:right}.available-fields__hint{display:block;margin-bottom:8px;color:var(--md-sys-color-on-surface-variant);font-size:12px}.no-fields-chip{position:absolute;top:8px;right:8px;padding:4px 8px;border:1px dashed var(--md-sys-color-outline);border-radius:16px;color:var(--md-sys-color-outline);font-size:12px;background:var(--md-sys-color-surface);pointer-events:none}.layout-canvas{flex-grow:1;flex-basis:100%;min-width:0;width:100%;overflow:visible;max-height:none;position:relative}.field-list{min-height:100px}.section-list{display:flex;flex-direction:column;gap:var(--pfx-section-gap, 20px)}.section-list:empty{min-height:48px}.add-section-container{position:relative;padding-top:16px;margin-top:12px;border-top:1px solid var(--md-sys-color-outline-variant);min-height:28px}.fab-add-section{position:absolute;top:-30px;left:50%;transform:translate(-50%,calc(-50% - var(--pfx-divider-w, 1px)));z-index:2;--pfx-fab-size: var(--pfx-fab-size-section, 32px);--pfx-fab-icon: var(--pfx-fab-icon-section, 18px);width:var(--pfx-fab-size);height:var(--pfx-fab-size);border-radius:50%}.fab-add-section mat-icon{font-size:var(--pfx-fab-icon);width:var(--pfx-fab-icon);height:var(--pfx-fab-icon)}.fab-add-section.mat-mdc-fab{width:var(--pfx-fab-size);height:var(--pfx-fab-size);padding:0}.fab-add-section .mat-mdc-button-touch-target,.fab-add-section .mat-mdc-button-persistent-ripple,.fab-add-section .mat-mdc-button-ripple{width:var(--pfx-fab-size);height:var(--pfx-fab-size)}.cdk-drag-placeholder{opacity:.3;transition:opacity .2s ease}:host ::ng-deep .mdc-text-field--filled{--mdc-filled-text-field-container-color: var(--md-sys-color-surface-container)}:host ::ng-deep .mdc-text-field__input::placeholder{color:var(--md-sys-color-on-surface-variant)!important;opacity:.95}:host ::ng-deep .mat-mdc-form-field-subscript-wrapper,:host ::ng-deep .mat-mdc-hint{color:var(--md-sys-color-on-surface-variant)!important}:host ::ng-deep .mdc-text-field--disabled .mdc-text-field__input,:host ::ng-deep .mat-mdc-select-disabled .mat-mdc-select-value{color:var(--md-sys-color-on-surface-variant)!important}:host ::ng-deep .mat-button-toggle-checked{background:var(--md-sys-color-primary-container)!important;color:var(--md-sys-color-on-primary-container)!important}:host ::ng-deep .editor-toolbar .mat-button-toggle-appearance-standard{color:var(--md-sys-color-on-surface-variant)}:host ::ng-deep .editor-toolbar .mat-button-toggle-appearance-standard:hover{background:var(--md-sys-color-surface-container-high);color:var(--md-sys-color-on-surface)}:host ::ng-deep .editor-toolbar .mat-button-toggle-checked:hover{background:var(--md-sys-color-primary-container)!important;color:var(--md-sys-color-on-primary-container)!important}:host{--px-editor-section-gap: 16px;--pfx-grid-gap: 12px;--pfx-section-gap: var(--px-editor-section-gap)}@media(min-width:960px){:host{--px-editor-section-gap: 20px;--pfx-grid-gap: 16px}}@media(min-width:1280px){:host{--px-editor-section-gap: 24px;--pfx-grid-gap: 20px}}@media(max-width:700px){.editor-toolbar{position:static;align-items:flex-start;gap:12px;min-height:0;padding:12px;row-gap:12px}.editor-toolbar .spacer{display:none}.editor-toolbar .title-block,.editor-toolbar .toolbar-group{flex:1 1 100%}.editor-toolbar .title-block{gap:4px}.editor-toolbar .toolbar-group{align-items:flex-start;justify-content:flex-start}.editor-toolbar .group-label{flex:0 0 100%}.editor-toolbar .density-toggle,.editor-toolbar .toggle-icons-group{max-width:100%}}\n"], dependencies: [{ kind: "ngmodule", type: CommonModule }, { kind: "directive", type: i1$2.NgStyle, selector: "[ngStyle]", inputs: ["ngStyle"] }, { kind: "ngmodule", type: DragDropModule }, { kind: "directive", type: i2$2.CdkDropList, selector: "[cdkDropList], cdk-drop-list", inputs: ["cdkDropListConnectedTo", "cdkDropListData", "cdkDropListOrientation", "id", "cdkDropListLockAxis", "cdkDropListDisabled", "cdkDropListSortingDisabled", "cdkDropListEnterPredicate", "cdkDropListSortPredicate", "cdkDropListAutoScrollDisabled", "cdkDropListAutoScrollStep", "cdkDropListElementContainer", "cdkDropListHasAnchor"], outputs: ["cdkDropListDropped", "cdkDropListEntered", "cdkDropListExited", "cdkDropListSorted"], exportAs: ["cdkDropList"] }, { kind: "directive", type: i2$2.CdkDropListGroup, selector: "[cdkDropListGroup]", inputs: ["cdkDropListGroupDisabled"], exportAs: ["cdkDropListGroup"] }, { kind: "directive", type: i2$2.CdkDrag, selector: "[cdkDrag]", inputs: ["cdkDragData", "cdkDragLockAxis", "cdkDragRootElement", "cdkDragBoundary", "cdkDragStartDelay", "cdkDragFreeDragPosition", "cdkDragDisabled", "cdkDragConstrainPosition", "cdkDragPreviewClass", "cdkDragPreviewContainer", "cdkDragScale"], outputs: ["cdkDragStarted", "cdkDragReleased", "cdkDragEnded", "cdkDragEntered", "cdkDragExited", "cdkDragDropped", "cdkDragMoved"], exportAs: ["cdkDrag"] }, { kind: "ngmodule", type: ScrollingModule }, { kind: "component", type: SectionConfiguratorComponent, selector: "praxis-section-configurator", inputs: ["section", "sectionIndex", "allSections", "fieldMetadata", "availableFields", "selected", "availableFieldsListId", "columnDropListIds", "gapGlobal"], outputs: ["sectionChange", "applyStyleToAll", "remove", "select", "fieldDrop", "addVisualBlock", "addApiField", "addLocalField", "requestMoveField", "editField", "editVisualBlock", "moveVisualBlock", "moveVisualBlockToColumn", "removeVisualBlock"] }, { kind: "component", type: FieldConfiguratorComponent, selector: "praxis-field-configurator", inputs: ["field"] }, { kind: "ngmodule", type: MatButtonModule }, { kind: "component", type: i3.MatFabButton, selector: "button[mat-fab], a[mat-fab], button[matFab], a[matFab]", inputs: ["extended"], exportAs: ["matButton", "matAnchor"] }, { kind: "ngmodule", type: MatIconModule }, { kind: "component", type: i4.MatIcon, selector: "mat-icon", inputs: ["color", "inline", "svgIcon", "fontSet", "fontIcon"], exportAs: ["matIcon"] }, { kind: "ngmodule", type: MatTooltipModule }, { kind: "directive", type: i5.MatTooltip, selector: "[matTooltip]", inputs: ["matTooltipPosition", "matTooltipPositionAtOrigin", "matTooltipDisabled", "matTooltipShowDelay", "matTooltipHideDelay", "matTooltipTouchGestures", "matTooltip", "matTooltipClass"], exportAs: ["matTooltip"] }, { kind: "ngmodule", type: MatToolbarModule }, { kind: "component", type: i6$1.MatToolbar, selector: "mat-toolbar", inputs: ["color"], exportAs: ["matToolbar"] }, { kind: "ngmodule", type: MatButtonToggleModule }, { kind: "directive", type: i7$2.MatButtonToggleGroup, selector: "mat-button-toggle-group", inputs: ["appearance", "name", "vertical", "value", "multiple", "disabled", "disabledInteractive", "hideSingleSelectionIndicator", "hideMultipleSelectionIndicator"], outputs: ["valueChange", "change"], exportAs: ["matButtonToggleGroup"] }, { kind: "component", type: i7$2.MatButtonToggle, selector: "mat-button-toggle", inputs: ["aria-label", "aria-labelledby", "id", "name", "value", "tabIndex", "disableRipple", "appearance", "checked", "disabled", "disabledInteractive"], outputs: ["change"], exportAs: ["matButtonToggle"] }, { kind: "ngmodule", type: FormsModule }, { kind: "directive", type: i1$3.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: i1$3.NumberValueAccessor, selector: "input[type=number][formControlName],input[type=number][formControl],input[type=number][ngModel]" }, { kind: "directive", type: i1$3.NgControlStatus, selector: "[formControlName],[ngModel],[formControl]" }, { kind: "directive", type: i1$3.MinValidator, selector: "input[type=number][min][formControlName],input[type=number][min][formControl],input[type=number][min][ngModel]", inputs: ["min"] }, { kind: "directive", type: i1$3.NgModel, selector: "[ngModel]:not([formControlName]):not([formControl])", inputs: ["name", "disabled", "ngModel", "ngModelOptions"], outputs: ["ngModelChange"], exportAs: ["ngModel"] }, { kind: "component", type: PraxisIconButtonComponent, selector: "button[praxisIconButton]", inputs: ["praxisIconButton", "size", "appearance", "presentation", "pressed", "busy"] }] });
|
|
26042
|
+
`, isInline: true, styles: [".layout-editor-wrapper{display:flex;flex-wrap:wrap;gap:16px;min-width:0;width:100%}.layout-editor-wrapper.no-available-fields{flex-direction:column;gap:0}.editor-toolbar{position:sticky;top:0;z-index:3;display:flex;flex-wrap:wrap;gap:16px;align-items:center;min-height:56px;background:var(--md-sys-color-surface-container);border-bottom:1px solid var(--md-sys-color-outline-variant);box-shadow:var(--md-sys-elevation-level1, var(--md-sys-elevation-level1));padding:0 12px;margin:0 0 var(--px-editor-section-gap, 16px) 0;width:100%;box-sizing:border-box;height:auto;white-space:normal}.editor-toolbar .title-block{display:flex;flex-direction:column;justify-content:center;gap:2px}.editor-toolbar .toolbar-title{font:var(--mdc-typography-title-small, 600 15px/20px system-ui);color:var(--md-sys-color-on-surface)}.editor-toolbar .toolbar-subtitle{font:var(--mdc-typography-body-small, 400 12px/16px system-ui);color:var(--md-sys-color-on-surface-variant)}.editor-toolbar .spacer{flex:1 1 auto}.editor-toolbar .toolbar-group{display:inline-flex;align-items:center;gap:8px;flex-wrap:wrap;min-width:0}.editor-toolbar .gap-group{align-items:center}.editor-toolbar .group-label{font:var(--mdc-typography-label-medium, 500 12px/16px system-ui);color:var(--md-sys-color-on-surface-variant)}.editor-toolbar .gap-group{align-items:center;gap:10px}.editor-toolbar .density-control{display:flex;align-items:center;gap:8px}.editor-toolbar .density-label{font:var(--mdc-typography-label-medium, 500 12px/16px system-ui);opacity:.9}.editor-toolbar .density-toggle,.editor-toolbar .toggle-icons-group{border:1px solid var(--md-sys-color-outline-variant);border-radius:999px;overflow:hidden;background:var(--md-sys-color-surface-container-low)}.editor-toolbar .density-toggle .mat-button-toggle,.editor-toolbar .toggle-icons-group .mat-button-toggle{background:var(--md-sys-color-surface-container-low);color:var(--md-sys-color-on-surface-variant)}.editor-toolbar .density-toggle .mat-button-toggle+.mat-button-toggle,.editor-toolbar .toggle-icons-group .mat-button-toggle+.mat-button-toggle{border-left:1px solid var(--md-sys-color-outline-variant)}.editor-toolbar .density-toggle .mat-button-toggle-button,.toggle-icons-group .mat-button-toggle-button{height:32px}.editor-toolbar .density-toggle .mat-icon,.toggle-icons-group .mat-icon{font-size:20px;width:20px;height:20px;line-height:20px}.editor-toolbar .density-toggle .mat-icon,.editor-toolbar .toggle-icons-group .mat-icon{color:inherit}.gap-chip{display:inline-flex;align-items:center;gap:2px;padding:0 4px;min-height:40px;border-radius:8px;border:1px solid var(--md-sys-color-outline-variant);background:var(--md-sys-color-surface-variant)}.gap-chip__input{width:42px;border:none;background:transparent;color:var(--md-sys-color-on-surface);font:var(--mdc-typography-body-medium, 600 13px/18px system-ui);text-align:center;outline:none;-moz-appearance:textfield}.gap-chip__input::-webkit-outer-spin-button,.gap-chip__input::-webkit-inner-spin-button{-webkit-appearance:none;margin:0}.gap-chip__suffix{color:var(--md-sys-color-on-surface-variant);font:var(--mdc-typography-label-medium, 500 12px/16px system-ui)}.pill{display:inline-flex;align-items:center;gap:6px;padding:4px 8px;border-radius:12px;background:var(--md-sys-color-surface-variant);color:var(--md-sys-color-on-surface-variant);font-size:12px}.pill.subtle{background:transparent;color:var(--md-sys-color-on-surface-variant);padding-left:0}.available-fields{width:250px;border:1px solid var(--md-sys-color-outline-variant);border-radius:12px;padding:10px;background:var(--md-sys-color-surface)}.collapse-toggle{float:right}.available-fields__hint{display:block;margin-bottom:8px;color:var(--md-sys-color-on-surface-variant);font-size:12px}.no-fields-chip{position:absolute;top:8px;right:8px;padding:4px 8px;border:1px dashed var(--md-sys-color-outline);border-radius:16px;color:var(--md-sys-color-outline);font-size:12px;background:var(--md-sys-color-surface);pointer-events:none}.layout-canvas{flex-grow:1;flex-basis:100%;min-width:0;width:100%;overflow:visible;max-height:none;position:relative}.field-list{min-height:100px}.section-list{display:flex;flex-direction:column;gap:var(--pfx-section-gap, 20px)}.section-list:empty{min-height:48px}.add-section-container{position:relative;padding-top:16px;margin-top:12px;border-top:1px solid var(--md-sys-color-outline-variant);min-height:28px}.fab-add-section{position:absolute;top:-30px;left:50%;transform:translate(-50%,calc(-50% - var(--pfx-divider-w, 1px)));z-index:2;--pfx-fab-size: var(--pfx-fab-size-section, 32px);--pfx-fab-icon: var(--pfx-fab-icon-section, 18px);width:var(--pfx-fab-size);height:var(--pfx-fab-size);border-radius:50%}.fab-add-section mat-icon{font-size:var(--pfx-fab-icon);width:var(--pfx-fab-icon);height:var(--pfx-fab-icon)}.fab-add-section.mat-mdc-fab{width:var(--pfx-fab-size);height:var(--pfx-fab-size);padding:0}.fab-add-section .mat-mdc-button-touch-target,.fab-add-section .mat-mdc-button-persistent-ripple,.fab-add-section .mat-mdc-button-ripple{width:var(--pfx-fab-size);height:var(--pfx-fab-size)}.cdk-drag-placeholder{opacity:.3;transition:opacity .2s ease}:host ::ng-deep .mdc-text-field--filled{--mdc-filled-text-field-container-color: var(--md-sys-color-surface-container)}:host ::ng-deep .mdc-text-field__input::placeholder{color:var(--md-sys-color-on-surface-variant)!important;opacity:.95}:host ::ng-deep .mat-mdc-form-field-subscript-wrapper,:host ::ng-deep .mat-mdc-hint{color:var(--md-sys-color-on-surface-variant)!important}:host ::ng-deep .mdc-text-field--disabled .mdc-text-field__input,:host ::ng-deep .mat-mdc-select-disabled .mat-mdc-select-value{color:var(--md-sys-color-on-surface-variant)!important}:host ::ng-deep .mat-button-toggle-checked{background:var(--md-sys-color-primary-container)!important;color:var(--md-sys-color-on-primary-container)!important}:host ::ng-deep .editor-toolbar .mat-button-toggle-appearance-standard{color:var(--md-sys-color-on-surface-variant)}:host ::ng-deep .editor-toolbar .mat-button-toggle-appearance-standard:hover{background:var(--md-sys-color-surface-container-high);color:var(--md-sys-color-on-surface)}:host ::ng-deep .editor-toolbar .mat-button-toggle-checked:hover{background:var(--md-sys-color-primary-container)!important;color:var(--md-sys-color-on-primary-container)!important}:host{display:block;container-type:inline-size;--px-editor-section-gap: 16px;--pfx-grid-gap: 12px;--pfx-section-gap: var(--px-editor-section-gap)}@container (min-width: 960px){.layout-editor-wrapper{--px-editor-section-gap: 20px;--pfx-grid-gap: 16px}}@container (min-width: 1280px){.layout-editor-wrapper{--px-editor-section-gap: 24px;--pfx-grid-gap: 20px}}@container (max-width: 700px){.editor-toolbar{position:static;align-items:flex-start;gap:12px;min-height:0;padding:12px;row-gap:12px}.editor-toolbar .spacer{display:none}.editor-toolbar .title-block,.editor-toolbar .toolbar-group{flex:1 1 100%}.editor-toolbar .title-block{gap:4px}.editor-toolbar .toolbar-group{align-items:flex-start;justify-content:flex-start}.editor-toolbar .group-label{flex:0 0 100%}.editor-toolbar .density-toggle,.editor-toolbar .toggle-icons-group{max-width:100%}}\n"], dependencies: [{ kind: "ngmodule", type: CommonModule }, { kind: "directive", type: i1$2.NgStyle, selector: "[ngStyle]", inputs: ["ngStyle"] }, { kind: "ngmodule", type: DragDropModule }, { kind: "directive", type: i2$2.CdkDropList, selector: "[cdkDropList], cdk-drop-list", inputs: ["cdkDropListConnectedTo", "cdkDropListData", "cdkDropListOrientation", "id", "cdkDropListLockAxis", "cdkDropListDisabled", "cdkDropListSortingDisabled", "cdkDropListEnterPredicate", "cdkDropListSortPredicate", "cdkDropListAutoScrollDisabled", "cdkDropListAutoScrollStep", "cdkDropListElementContainer", "cdkDropListHasAnchor"], outputs: ["cdkDropListDropped", "cdkDropListEntered", "cdkDropListExited", "cdkDropListSorted"], exportAs: ["cdkDropList"] }, { kind: "directive", type: i2$2.CdkDropListGroup, selector: "[cdkDropListGroup]", inputs: ["cdkDropListGroupDisabled"], exportAs: ["cdkDropListGroup"] }, { kind: "directive", type: i2$2.CdkDrag, selector: "[cdkDrag]", inputs: ["cdkDragData", "cdkDragLockAxis", "cdkDragRootElement", "cdkDragBoundary", "cdkDragStartDelay", "cdkDragFreeDragPosition", "cdkDragDisabled", "cdkDragConstrainPosition", "cdkDragPreviewClass", "cdkDragPreviewContainer", "cdkDragScale"], outputs: ["cdkDragStarted", "cdkDragReleased", "cdkDragEnded", "cdkDragEntered", "cdkDragExited", "cdkDragDropped", "cdkDragMoved"], exportAs: ["cdkDrag"] }, { kind: "ngmodule", type: ScrollingModule }, { kind: "component", type: SectionConfiguratorComponent, selector: "praxis-section-configurator", inputs: ["section", "sectionIndex", "allSections", "fieldMetadata", "availableFields", "selected", "availableFieldsListId", "columnDropListIds", "gapGlobal"], outputs: ["sectionChange", "applyStyleToAll", "remove", "select", "fieldDrop", "addVisualBlock", "addApiField", "addLocalField", "requestMoveField", "editField", "editVisualBlock", "moveVisualBlock", "moveVisualBlockToColumn", "removeVisualBlock"] }, { kind: "component", type: FieldConfiguratorComponent, selector: "praxis-field-configurator", inputs: ["field"] }, { kind: "ngmodule", type: MatButtonModule }, { kind: "component", type: i3.MatFabButton, selector: "button[mat-fab], a[mat-fab], button[matFab], a[matFab]", inputs: ["extended"], exportAs: ["matButton", "matAnchor"] }, { kind: "ngmodule", type: MatIconModule }, { kind: "component", type: i4.MatIcon, selector: "mat-icon", inputs: ["color", "inline", "svgIcon", "fontSet", "fontIcon"], exportAs: ["matIcon"] }, { kind: "ngmodule", type: MatTooltipModule }, { kind: "directive", type: i5.MatTooltip, selector: "[matTooltip]", inputs: ["matTooltipPosition", "matTooltipPositionAtOrigin", "matTooltipDisabled", "matTooltipShowDelay", "matTooltipHideDelay", "matTooltipTouchGestures", "matTooltip", "matTooltipClass"], exportAs: ["matTooltip"] }, { kind: "ngmodule", type: MatToolbarModule }, { kind: "component", type: i6$1.MatToolbar, selector: "mat-toolbar", inputs: ["color"], exportAs: ["matToolbar"] }, { kind: "ngmodule", type: MatButtonToggleModule }, { kind: "directive", type: i7$2.MatButtonToggleGroup, selector: "mat-button-toggle-group", inputs: ["appearance", "name", "vertical", "value", "multiple", "disabled", "disabledInteractive", "hideSingleSelectionIndicator", "hideMultipleSelectionIndicator"], outputs: ["valueChange", "change"], exportAs: ["matButtonToggleGroup"] }, { kind: "component", type: i7$2.MatButtonToggle, selector: "mat-button-toggle", inputs: ["aria-label", "aria-labelledby", "id", "name", "value", "tabIndex", "disableRipple", "appearance", "checked", "disabled", "disabledInteractive"], outputs: ["change"], exportAs: ["matButtonToggle"] }, { kind: "ngmodule", type: FormsModule }, { kind: "directive", type: i1$3.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: i1$3.NumberValueAccessor, selector: "input[type=number][formControlName],input[type=number][formControl],input[type=number][ngModel]" }, { kind: "directive", type: i1$3.NgControlStatus, selector: "[formControlName],[ngModel],[formControl]" }, { kind: "directive", type: i1$3.MinValidator, selector: "input[type=number][min][formControlName],input[type=number][min][formControl],input[type=number][min][ngModel]", inputs: ["min"] }, { kind: "directive", type: i1$3.NgModel, selector: "[ngModel]:not([formControlName]):not([formControl])", inputs: ["name", "disabled", "ngModel", "ngModelOptions"], outputs: ["ngModelChange"], exportAs: ["ngModel"] }, { kind: "component", type: PraxisIconButtonComponent, selector: "button[praxisIconButton]", inputs: ["praxisIconButton", "size", "appearance", "presentation", "pressed", "busy"] }] });
|
|
25802
26043
|
}
|
|
25803
26044
|
i0.ɵɵngDeclareClassMetadata({ minVersion: "12.0.0", version: "21.2.14", ngImport: i0, type: LayoutEditorComponent, decorators: [{
|
|
25804
26045
|
type: Component,
|
|
@@ -25991,7 +26232,7 @@ i0.ɵɵngDeclareClassMetadata({ minVersion: "12.0.0", version: "21.2.14", ngImpo
|
|
|
25991
26232
|
</div>
|
|
25992
26233
|
</div>
|
|
25993
26234
|
</div>
|
|
25994
|
-
`, providers: [DynamicFormLayoutService, providePraxisI18nConfig(LAYOUT_EDITOR_I18N_CONFIG)], styles: [".layout-editor-wrapper{display:flex;flex-wrap:wrap;gap:16px;min-width:0;width:100%}.layout-editor-wrapper.no-available-fields{flex-direction:column;gap:0}.editor-toolbar{position:sticky;top:0;z-index:3;display:flex;flex-wrap:wrap;gap:16px;align-items:center;min-height:56px;background:var(--md-sys-color-surface-container);border-bottom:1px solid var(--md-sys-color-outline-variant);box-shadow:var(--md-sys-elevation-level1, var(--md-sys-elevation-level1));padding:0 12px;margin:0 0 var(--px-editor-section-gap, 16px) 0;width:100%;box-sizing:border-box;height:auto;white-space:normal}.editor-toolbar .title-block{display:flex;flex-direction:column;justify-content:center;gap:2px}.editor-toolbar .toolbar-title{font:var(--mdc-typography-title-small, 600 15px/20px system-ui);color:var(--md-sys-color-on-surface)}.editor-toolbar .toolbar-subtitle{font:var(--mdc-typography-body-small, 400 12px/16px system-ui);color:var(--md-sys-color-on-surface-variant)}.editor-toolbar .spacer{flex:1 1 auto}.editor-toolbar .toolbar-group{display:inline-flex;align-items:center;gap:8px;flex-wrap:wrap;min-width:0}.editor-toolbar .gap-group{align-items:center}.editor-toolbar .group-label{font:var(--mdc-typography-label-medium, 500 12px/16px system-ui);color:var(--md-sys-color-on-surface-variant)}.editor-toolbar .gap-group{align-items:center;gap:10px}.editor-toolbar .density-control{display:flex;align-items:center;gap:8px}.editor-toolbar .density-label{font:var(--mdc-typography-label-medium, 500 12px/16px system-ui);opacity:.9}.editor-toolbar .density-toggle,.editor-toolbar .toggle-icons-group{border:1px solid var(--md-sys-color-outline-variant);border-radius:999px;overflow:hidden;background:var(--md-sys-color-surface-container-low)}.editor-toolbar .density-toggle .mat-button-toggle,.editor-toolbar .toggle-icons-group .mat-button-toggle{background:var(--md-sys-color-surface-container-low);color:var(--md-sys-color-on-surface-variant)}.editor-toolbar .density-toggle .mat-button-toggle+.mat-button-toggle,.editor-toolbar .toggle-icons-group .mat-button-toggle+.mat-button-toggle{border-left:1px solid var(--md-sys-color-outline-variant)}.editor-toolbar .density-toggle .mat-button-toggle-button,.toggle-icons-group .mat-button-toggle-button{height:32px}.editor-toolbar .density-toggle .mat-icon,.toggle-icons-group .mat-icon{font-size:20px;width:20px;height:20px;line-height:20px}.editor-toolbar .density-toggle .mat-icon,.editor-toolbar .toggle-icons-group .mat-icon{color:inherit}.gap-chip{display:inline-flex;align-items:center;gap:2px;padding:0 4px;min-height:40px;border-radius:8px;border:1px solid var(--md-sys-color-outline-variant);background:var(--md-sys-color-surface-variant)}.gap-chip__input{width:42px;border:none;background:transparent;color:var(--md-sys-color-on-surface);font:var(--mdc-typography-body-medium, 600 13px/18px system-ui);text-align:center;outline:none;-moz-appearance:textfield}.gap-chip__input::-webkit-outer-spin-button,.gap-chip__input::-webkit-inner-spin-button{-webkit-appearance:none;margin:0}.gap-chip__suffix{color:var(--md-sys-color-on-surface-variant);font:var(--mdc-typography-label-medium, 500 12px/16px system-ui)}.pill{display:inline-flex;align-items:center;gap:6px;padding:4px 8px;border-radius:12px;background:var(--md-sys-color-surface-variant);color:var(--md-sys-color-on-surface-variant);font-size:12px}.pill.subtle{background:transparent;color:var(--md-sys-color-on-surface-variant);padding-left:0}.available-fields{width:250px;border:1px solid var(--md-sys-color-outline-variant);border-radius:12px;padding:10px;background:var(--md-sys-color-surface)}.collapse-toggle{float:right}.available-fields__hint{display:block;margin-bottom:8px;color:var(--md-sys-color-on-surface-variant);font-size:12px}.no-fields-chip{position:absolute;top:8px;right:8px;padding:4px 8px;border:1px dashed var(--md-sys-color-outline);border-radius:16px;color:var(--md-sys-color-outline);font-size:12px;background:var(--md-sys-color-surface);pointer-events:none}.layout-canvas{flex-grow:1;flex-basis:100%;min-width:0;width:100%;overflow:visible;max-height:none;position:relative}.field-list{min-height:100px}.section-list{display:flex;flex-direction:column;gap:var(--pfx-section-gap, 20px)}.section-list:empty{min-height:48px}.add-section-container{position:relative;padding-top:16px;margin-top:12px;border-top:1px solid var(--md-sys-color-outline-variant);min-height:28px}.fab-add-section{position:absolute;top:-30px;left:50%;transform:translate(-50%,calc(-50% - var(--pfx-divider-w, 1px)));z-index:2;--pfx-fab-size: var(--pfx-fab-size-section, 32px);--pfx-fab-icon: var(--pfx-fab-icon-section, 18px);width:var(--pfx-fab-size);height:var(--pfx-fab-size);border-radius:50%}.fab-add-section mat-icon{font-size:var(--pfx-fab-icon);width:var(--pfx-fab-icon);height:var(--pfx-fab-icon)}.fab-add-section.mat-mdc-fab{width:var(--pfx-fab-size);height:var(--pfx-fab-size);padding:0}.fab-add-section .mat-mdc-button-touch-target,.fab-add-section .mat-mdc-button-persistent-ripple,.fab-add-section .mat-mdc-button-ripple{width:var(--pfx-fab-size);height:var(--pfx-fab-size)}.cdk-drag-placeholder{opacity:.3;transition:opacity .2s ease}:host ::ng-deep .mdc-text-field--filled{--mdc-filled-text-field-container-color: var(--md-sys-color-surface-container)}:host ::ng-deep .mdc-text-field__input::placeholder{color:var(--md-sys-color-on-surface-variant)!important;opacity:.95}:host ::ng-deep .mat-mdc-form-field-subscript-wrapper,:host ::ng-deep .mat-mdc-hint{color:var(--md-sys-color-on-surface-variant)!important}:host ::ng-deep .mdc-text-field--disabled .mdc-text-field__input,:host ::ng-deep .mat-mdc-select-disabled .mat-mdc-select-value{color:var(--md-sys-color-on-surface-variant)!important}:host ::ng-deep .mat-button-toggle-checked{background:var(--md-sys-color-primary-container)!important;color:var(--md-sys-color-on-primary-container)!important}:host ::ng-deep .editor-toolbar .mat-button-toggle-appearance-standard{color:var(--md-sys-color-on-surface-variant)}:host ::ng-deep .editor-toolbar .mat-button-toggle-appearance-standard:hover{background:var(--md-sys-color-surface-container-high);color:var(--md-sys-color-on-surface)}:host ::ng-deep .editor-toolbar .mat-button-toggle-checked:hover{background:var(--md-sys-color-primary-container)!important;color:var(--md-sys-color-on-primary-container)!important}:host{
|
|
26235
|
+
`, providers: [DynamicFormLayoutService, providePraxisI18nConfig(LAYOUT_EDITOR_I18N_CONFIG)], styles: [".layout-editor-wrapper{display:flex;flex-wrap:wrap;gap:16px;min-width:0;width:100%}.layout-editor-wrapper.no-available-fields{flex-direction:column;gap:0}.editor-toolbar{position:sticky;top:0;z-index:3;display:flex;flex-wrap:wrap;gap:16px;align-items:center;min-height:56px;background:var(--md-sys-color-surface-container);border-bottom:1px solid var(--md-sys-color-outline-variant);box-shadow:var(--md-sys-elevation-level1, var(--md-sys-elevation-level1));padding:0 12px;margin:0 0 var(--px-editor-section-gap, 16px) 0;width:100%;box-sizing:border-box;height:auto;white-space:normal}.editor-toolbar .title-block{display:flex;flex-direction:column;justify-content:center;gap:2px}.editor-toolbar .toolbar-title{font:var(--mdc-typography-title-small, 600 15px/20px system-ui);color:var(--md-sys-color-on-surface)}.editor-toolbar .toolbar-subtitle{font:var(--mdc-typography-body-small, 400 12px/16px system-ui);color:var(--md-sys-color-on-surface-variant)}.editor-toolbar .spacer{flex:1 1 auto}.editor-toolbar .toolbar-group{display:inline-flex;align-items:center;gap:8px;flex-wrap:wrap;min-width:0}.editor-toolbar .gap-group{align-items:center}.editor-toolbar .group-label{font:var(--mdc-typography-label-medium, 500 12px/16px system-ui);color:var(--md-sys-color-on-surface-variant)}.editor-toolbar .gap-group{align-items:center;gap:10px}.editor-toolbar .density-control{display:flex;align-items:center;gap:8px}.editor-toolbar .density-label{font:var(--mdc-typography-label-medium, 500 12px/16px system-ui);opacity:.9}.editor-toolbar .density-toggle,.editor-toolbar .toggle-icons-group{border:1px solid var(--md-sys-color-outline-variant);border-radius:999px;overflow:hidden;background:var(--md-sys-color-surface-container-low)}.editor-toolbar .density-toggle .mat-button-toggle,.editor-toolbar .toggle-icons-group .mat-button-toggle{background:var(--md-sys-color-surface-container-low);color:var(--md-sys-color-on-surface-variant)}.editor-toolbar .density-toggle .mat-button-toggle+.mat-button-toggle,.editor-toolbar .toggle-icons-group .mat-button-toggle+.mat-button-toggle{border-left:1px solid var(--md-sys-color-outline-variant)}.editor-toolbar .density-toggle .mat-button-toggle-button,.toggle-icons-group .mat-button-toggle-button{height:32px}.editor-toolbar .density-toggle .mat-icon,.toggle-icons-group .mat-icon{font-size:20px;width:20px;height:20px;line-height:20px}.editor-toolbar .density-toggle .mat-icon,.editor-toolbar .toggle-icons-group .mat-icon{color:inherit}.gap-chip{display:inline-flex;align-items:center;gap:2px;padding:0 4px;min-height:40px;border-radius:8px;border:1px solid var(--md-sys-color-outline-variant);background:var(--md-sys-color-surface-variant)}.gap-chip__input{width:42px;border:none;background:transparent;color:var(--md-sys-color-on-surface);font:var(--mdc-typography-body-medium, 600 13px/18px system-ui);text-align:center;outline:none;-moz-appearance:textfield}.gap-chip__input::-webkit-outer-spin-button,.gap-chip__input::-webkit-inner-spin-button{-webkit-appearance:none;margin:0}.gap-chip__suffix{color:var(--md-sys-color-on-surface-variant);font:var(--mdc-typography-label-medium, 500 12px/16px system-ui)}.pill{display:inline-flex;align-items:center;gap:6px;padding:4px 8px;border-radius:12px;background:var(--md-sys-color-surface-variant);color:var(--md-sys-color-on-surface-variant);font-size:12px}.pill.subtle{background:transparent;color:var(--md-sys-color-on-surface-variant);padding-left:0}.available-fields{width:250px;border:1px solid var(--md-sys-color-outline-variant);border-radius:12px;padding:10px;background:var(--md-sys-color-surface)}.collapse-toggle{float:right}.available-fields__hint{display:block;margin-bottom:8px;color:var(--md-sys-color-on-surface-variant);font-size:12px}.no-fields-chip{position:absolute;top:8px;right:8px;padding:4px 8px;border:1px dashed var(--md-sys-color-outline);border-radius:16px;color:var(--md-sys-color-outline);font-size:12px;background:var(--md-sys-color-surface);pointer-events:none}.layout-canvas{flex-grow:1;flex-basis:100%;min-width:0;width:100%;overflow:visible;max-height:none;position:relative}.field-list{min-height:100px}.section-list{display:flex;flex-direction:column;gap:var(--pfx-section-gap, 20px)}.section-list:empty{min-height:48px}.add-section-container{position:relative;padding-top:16px;margin-top:12px;border-top:1px solid var(--md-sys-color-outline-variant);min-height:28px}.fab-add-section{position:absolute;top:-30px;left:50%;transform:translate(-50%,calc(-50% - var(--pfx-divider-w, 1px)));z-index:2;--pfx-fab-size: var(--pfx-fab-size-section, 32px);--pfx-fab-icon: var(--pfx-fab-icon-section, 18px);width:var(--pfx-fab-size);height:var(--pfx-fab-size);border-radius:50%}.fab-add-section mat-icon{font-size:var(--pfx-fab-icon);width:var(--pfx-fab-icon);height:var(--pfx-fab-icon)}.fab-add-section.mat-mdc-fab{width:var(--pfx-fab-size);height:var(--pfx-fab-size);padding:0}.fab-add-section .mat-mdc-button-touch-target,.fab-add-section .mat-mdc-button-persistent-ripple,.fab-add-section .mat-mdc-button-ripple{width:var(--pfx-fab-size);height:var(--pfx-fab-size)}.cdk-drag-placeholder{opacity:.3;transition:opacity .2s ease}:host ::ng-deep .mdc-text-field--filled{--mdc-filled-text-field-container-color: var(--md-sys-color-surface-container)}:host ::ng-deep .mdc-text-field__input::placeholder{color:var(--md-sys-color-on-surface-variant)!important;opacity:.95}:host ::ng-deep .mat-mdc-form-field-subscript-wrapper,:host ::ng-deep .mat-mdc-hint{color:var(--md-sys-color-on-surface-variant)!important}:host ::ng-deep .mdc-text-field--disabled .mdc-text-field__input,:host ::ng-deep .mat-mdc-select-disabled .mat-mdc-select-value{color:var(--md-sys-color-on-surface-variant)!important}:host ::ng-deep .mat-button-toggle-checked{background:var(--md-sys-color-primary-container)!important;color:var(--md-sys-color-on-primary-container)!important}:host ::ng-deep .editor-toolbar .mat-button-toggle-appearance-standard{color:var(--md-sys-color-on-surface-variant)}:host ::ng-deep .editor-toolbar .mat-button-toggle-appearance-standard:hover{background:var(--md-sys-color-surface-container-high);color:var(--md-sys-color-on-surface)}:host ::ng-deep .editor-toolbar .mat-button-toggle-checked:hover{background:var(--md-sys-color-primary-container)!important;color:var(--md-sys-color-on-primary-container)!important}:host{display:block;container-type:inline-size;--px-editor-section-gap: 16px;--pfx-grid-gap: 12px;--pfx-section-gap: var(--px-editor-section-gap)}@container (min-width: 960px){.layout-editor-wrapper{--px-editor-section-gap: 20px;--pfx-grid-gap: 16px}}@container (min-width: 1280px){.layout-editor-wrapper{--px-editor-section-gap: 24px;--pfx-grid-gap: 20px}}@container (max-width: 700px){.editor-toolbar{position:static;align-items:flex-start;gap:12px;min-height:0;padding:12px;row-gap:12px}.editor-toolbar .spacer{display:none}.editor-toolbar .title-block,.editor-toolbar .toolbar-group{flex:1 1 100%}.editor-toolbar .title-block{gap:4px}.editor-toolbar .toolbar-group{align-items:flex-start;justify-content:flex-start}.editor-toolbar .group-label{flex:0 0 100%}.editor-toolbar .density-toggle,.editor-toolbar .toggle-icons-group{max-width:100%}}\n"] }]
|
|
25995
26236
|
}], propDecorators: { config: [{
|
|
25996
26237
|
type: Input
|
|
25997
26238
|
}], configChange: [{
|
|
@@ -31618,7 +31859,9 @@ class PraxisDynamicFormConfigEditor {
|
|
|
31618
31859
|
componentKeyId;
|
|
31619
31860
|
// Input patch: controls like mode (dados)
|
|
31620
31861
|
inputMode = 'create';
|
|
31862
|
+
inputLayoutScope = 'shared';
|
|
31621
31863
|
includeBindingsBlock = false;
|
|
31864
|
+
includeLayoutScopeBinding = false;
|
|
31622
31865
|
editorMode;
|
|
31623
31866
|
// Indica se o editor foi aberto com o formulário em modo apresentação
|
|
31624
31867
|
get isPresentationMode() { return this.supportsPresentationSettings; }
|
|
@@ -31841,7 +32084,9 @@ class PraxisDynamicFormConfigEditor {
|
|
|
31841
32084
|
this.formId = data?.formId;
|
|
31842
32085
|
this.componentKeyId = data?.componentKeyId;
|
|
31843
32086
|
this.includeBindingsBlock = Object.prototype.hasOwnProperty.call(initialDocument.bindings || {}, 'mode');
|
|
32087
|
+
this.includeLayoutScopeBinding = Object.prototype.hasOwnProperty.call(initialDocument.bindings || {}, 'layoutScope');
|
|
31844
32088
|
this.inputMode = this.normalizeMode(initialDocument.bindings?.mode);
|
|
32089
|
+
this.inputLayoutScope = this.normalizeLayoutScope(initialDocument.bindings?.layoutScope ?? formCfg?.metadata?.layoutScope);
|
|
31845
32090
|
this.editorMode = this.inputMode;
|
|
31846
32091
|
// Flag de contexto do host (praxis-dynamic-form)
|
|
31847
32092
|
this.inputPresentationMode = initialDocument.bindings?.presentationModeGlobal;
|
|
@@ -31889,7 +32134,9 @@ class PraxisDynamicFormConfigEditor {
|
|
|
31889
32134
|
this.includeBackConfigBlock = Object.prototype.hasOwnProperty.call(this.initialDocument.contextSnapshot || {}, 'backConfig');
|
|
31890
32135
|
this.backConfig = this.createBackConfigState(this.initialDocument.contextSnapshot?.backConfig);
|
|
31891
32136
|
this.includeBindingsBlock = Object.prototype.hasOwnProperty.call(this.initialDocument.bindings || {}, 'mode');
|
|
32137
|
+
this.includeLayoutScopeBinding = Object.prototype.hasOwnProperty.call(this.initialDocument.bindings || {}, 'layoutScope');
|
|
31892
32138
|
this.inputMode = this.normalizeMode(this.initialDocument.bindings?.mode);
|
|
32139
|
+
this.inputLayoutScope = this.normalizeLayoutScope(this.initialDocument.bindings?.layoutScope ?? this.initialConfig?.metadata?.layoutScope);
|
|
31893
32140
|
this.inputPresentationMode = this.initialDocument.bindings?.presentationModeGlobal;
|
|
31894
32141
|
this.inputEmptyState = structuredClone(this.initialDocument.bindings?.emptyState);
|
|
31895
32142
|
this.includePresentationBlock = Object.prototype.hasOwnProperty.call(this.initialDocument.contextSnapshot || {}, 'presentation');
|
|
@@ -31989,7 +32236,11 @@ class PraxisDynamicFormConfigEditor {
|
|
|
31989
32236
|
this.includeBindingsBlock = isCanonicalDocument
|
|
31990
32237
|
? Object.prototype.hasOwnProperty.call(document.bindings || {}, 'mode')
|
|
31991
32238
|
: this.includeBindingsBlock || !!document.bindings?.mode;
|
|
32239
|
+
this.includeLayoutScopeBinding = isCanonicalDocument
|
|
32240
|
+
? Object.prototype.hasOwnProperty.call(document.bindings || {}, 'layoutScope')
|
|
32241
|
+
: this.includeLayoutScopeBinding || !!document.bindings?.layoutScope;
|
|
31992
32242
|
this.inputMode = this.normalizeMode(document.bindings?.mode);
|
|
32243
|
+
this.inputLayoutScope = this.normalizeLayoutScope(document.bindings?.layoutScope ?? document.config?.metadata?.layoutScope);
|
|
31993
32244
|
this.inputPresentationMode = document.bindings?.presentationModeGlobal;
|
|
31994
32245
|
this.inputEmptyState = structuredClone(document.bindings?.emptyState);
|
|
31995
32246
|
this.includePresentationBlock = isCanonicalDocument
|
|
@@ -32796,7 +33047,9 @@ class PraxisDynamicFormConfigEditor {
|
|
|
32796
33047
|
this.updateDirtyState('back-config-change');
|
|
32797
33048
|
}
|
|
32798
33049
|
isBindingsBlockPersisted() {
|
|
32799
|
-
return this.includeBindingsBlock ||
|
|
33050
|
+
return (this.includeBindingsBlock ||
|
|
33051
|
+
this.includeLayoutScopeBinding ||
|
|
33052
|
+
this.inputPresentationMode !== undefined);
|
|
32800
33053
|
}
|
|
32801
33054
|
isPresentationBlockPersisted() {
|
|
32802
33055
|
return this.includePresentationBlock;
|
|
@@ -32824,6 +33077,28 @@ class PraxisDynamicFormConfigEditor {
|
|
|
32824
33077
|
this.includeBindingsBlock = true;
|
|
32825
33078
|
this.updateDirtyState('input-mode-change');
|
|
32826
33079
|
}
|
|
33080
|
+
onLayoutScopeChange(scope) {
|
|
33081
|
+
const nextScope = this.normalizeLayoutScope(scope);
|
|
33082
|
+
this.inputLayoutScope = nextScope;
|
|
33083
|
+
const baselineDoc = this.appliedDocument ?? this.initialDocument;
|
|
33084
|
+
const hadBaselineBinding = Object.prototype.hasOwnProperty.call(baselineDoc.bindings || {}, 'layoutScope');
|
|
33085
|
+
const baselineScope = this.normalizeLayoutScope(baselineDoc.bindings?.layoutScope ?? baselineDoc.config?.metadata?.layoutScope);
|
|
33086
|
+
this.includeLayoutScopeBinding = hadBaselineBinding || nextScope !== baselineScope;
|
|
33087
|
+
if (this.editedConfig?.metadata &&
|
|
33088
|
+
Object.prototype.hasOwnProperty.call(this.editedConfig.metadata, 'layoutScope')) {
|
|
33089
|
+
const hadBaselineMetadataScope = Object.prototype.hasOwnProperty.call(baselineDoc.config?.metadata || {}, 'layoutScope');
|
|
33090
|
+
if (hadBaselineMetadataScope) {
|
|
33091
|
+
this.editedConfig = {
|
|
33092
|
+
...this.editedConfig,
|
|
33093
|
+
metadata: {
|
|
33094
|
+
...this.editedConfig.metadata,
|
|
33095
|
+
layoutScope: nextScope,
|
|
33096
|
+
},
|
|
33097
|
+
};
|
|
33098
|
+
}
|
|
33099
|
+
}
|
|
33100
|
+
this.updateDirtyState('layout-scope-change');
|
|
33101
|
+
}
|
|
32827
33102
|
onPresentationPrefsChange(reason) {
|
|
32828
33103
|
this.includePresentationBlock = true;
|
|
32829
33104
|
this.updateDirtyState(reason);
|
|
@@ -33334,6 +33609,9 @@ class PraxisDynamicFormConfigEditor {
|
|
|
33334
33609
|
return value;
|
|
33335
33610
|
return 'create';
|
|
33336
33611
|
}
|
|
33612
|
+
normalizeLayoutScope(value) {
|
|
33613
|
+
return value === 'mode-only' ? 'mode-only' : 'shared';
|
|
33614
|
+
}
|
|
33337
33615
|
buildAuthoringDocument() {
|
|
33338
33616
|
const contextSnapshot = stripUndefinedContextSnapshot({
|
|
33339
33617
|
backConfig: this.includeBackConfigBlock
|
|
@@ -33350,6 +33628,9 @@ class PraxisDynamicFormConfigEditor {
|
|
|
33350
33628
|
config: this.stripLegacy(this.editedConfig),
|
|
33351
33629
|
bindings: {
|
|
33352
33630
|
mode: this.includeBindingsBlock ? this.inputMode : undefined,
|
|
33631
|
+
layoutScope: this.includeLayoutScopeBinding
|
|
33632
|
+
? this.inputLayoutScope
|
|
33633
|
+
: undefined,
|
|
33353
33634
|
presentationModeGlobal: this.inputPresentationMode,
|
|
33354
33635
|
emptyState: this.supportsPresentationSettings ? this.inputEmptyState : undefined,
|
|
33355
33636
|
},
|
|
@@ -33441,7 +33722,7 @@ class PraxisDynamicFormConfigEditor {
|
|
|
33441
33722
|
return Object.entries(params).reduce((text, [key, value]) => text.split(`{{${key}}}`).join(String(value)), fallback);
|
|
33442
33723
|
}
|
|
33443
33724
|
static ɵfac = i0.ɵɵngDeclareFactory({ minVersion: "12.0.0", version: "21.2.14", ngImport: i0, type: PraxisDynamicFormConfigEditor, deps: [{ token: ASYNC_CONFIG_STORAGE }, { token: FormConfigService }, { token: i7.SettingsPanelService }, { token: i0.ChangeDetectorRef }, { token: GLOBAL_ACTION_CATALOG, optional: true }, { token: SETTINGS_PANEL_DATA, optional: true }], target: i0.ɵɵFactoryTarget.Component });
|
|
33444
|
-
static ɵcmp = i0.ɵɵngDeclareComponent({ minVersion: "17.0.0", version: "21.2.14", type: PraxisDynamicFormConfigEditor, isStandalone: true, selector: "praxis-dynamic-form-config-editor", providers: [FormConfigService, providePraxisI18nConfig(PRAXIS_DYNAMIC_FORM_I18N_CONFIG)], viewQueries: [{ propertyName: "jsonEditor", first: true, predicate: JsonConfigEditorComponent, descendants: true }, { propertyName: "cascadeManager", first: true, predicate: CascadeManagerTabComponent, descendants: true }], ngImport: i0, template: "<div class=\"mobile-tab-selector\">\n <mat-form-field appearance=\"outline\" class=\"mobile-tab-selector__field\">\n <mat-label>{{ tx('config.tabs.mobileLabel', 'Se\u00E7\u00E3o do editor') }}</mat-label>\n <mat-select [(ngModel)]=\"selectedConfigTabIndex\" data-testid=\"dynamic-form-config-editor-mobile-tabs\">\n @for (tab of configTabOptions; track tab.key) {\n <mat-option [value]=\"tab.index\">{{ tab.label }}</mat-option>\n }\n </mat-select>\n </mat-form-field>\n</div>\n\n<mat-tab-group [preserveContent]=\"true\" class=\"config-tabs\" data-testid=\"dynamic-form-config-editor-tabs\" [(selectedIndex)]=\"selectedConfigTabIndex\">\n <mat-tab [label]=\"configTabLabel('general')\">\n <div class=\"tab-content\" data-testid=\"config-tab-panel-geral\">\n <mat-card class=\"section-card\">\n <mat-card-content>\n <div class=\"section-header\">\n <div>\n <h3>{{ tx('config.general.title', 'Dados do formul\u00E1rio') }}</h3>\n <p class=\"text-caption\">{{ tx('config.general.subtitle', 'Defina o modo de dados e o contexto de edi\u00E7\u00E3o.') }}</p>\n </div>\n </div>\n <div class=\"form-modes\">\n <div class=\"control\">\n <label class=\"control__label\">{{ tx('config.general.inputMode.label') }}</label>\n <mat-button-toggle-group [ngModel]=\"inputMode\" (ngModelChange)=\"inputMode = $event; onInputModeChange()\" [attr.aria-label]=\"tx('config.general.inputMode.label')\">\n <mat-button-toggle value=\"create\">{{ tx('config.general.inputMode.create') }}</mat-button-toggle>\n <mat-button-toggle value=\"edit\">{{ tx('config.general.inputMode.edit') }}</mat-button-toggle>\n <mat-button-toggle value=\"view\">{{ tx('config.general.inputMode.view') }}</mat-button-toggle>\n </mat-button-toggle-group>\n </div>\n @if (supportsPresentationSettings) {\n <div class=\"control\">\n <label class=\"control__label\">{{ tx('config.general.displayMode.label') }}</label>\n <mat-button-toggle-group [ngModel]=\"displayMode\" (ngModelChange)=\"onDisplayModeChange($event)\" [attr.aria-label]=\"tx('config.general.displayMode.label')\">\n <mat-button-toggle value=\"automatic\">{{ tx('config.general.displayMode.automatic') }}</mat-button-toggle>\n <mat-button-toggle value=\"fields\">{{ tx('config.general.displayMode.fields') }}</mat-button-toggle>\n <mat-button-toggle value=\"presentation\">{{ tx('config.general.displayMode.presentation') }}</mat-button-toggle>\n </mat-button-toggle-group>\n </div>\n <p class=\"display-result\" role=\"status\">{{ tx(displayModeHint) }}</p>\n @if (inputMode !== 'view' && inputMode !== 'presentation' && inputMode !== 'dossier' && inputPresentationMode === true) {\n <button mat-stroked-button type=\"button\" (click)=\"useViewMode()\">{{ tx('config.general.displayMode.useView') }}</button>\n }\n <button mat-button type=\"button\" (click)=\"openPresentationStyle()\">{{ tx('config.general.displayMode.openStyle') }}</button>\n }\n </div>\n </mat-card-content>\n </mat-card>\n\n @if (supportsPresentationSettings) {\n <mat-card class=\"section-card\" data-testid=\"form-empty-state-settings\">\n <mat-card-content>\n <h3>{{ tx('config.emptyState.heading') }}</h3>\n <p class=\"text-caption\">{{ tx('config.emptyState.help') }}</p>\n <mat-slide-toggle [ngModel]=\"!!inputEmptyState\" (ngModelChange)=\"setEmptyStateEnabled($event)\">{{ tx('config.emptyState.enabled') }}</mat-slide-toggle>\n @if (inputMode !== 'view' && inputMode !== 'presentation' && inputMode !== 'dossier') { <p class=\"text-caption\">{{ tx('config.emptyState.viewOnly') }}</p> }\n @if (inputEmptyState; as empty) {\n <div class=\"empty-state-fields empty-state-content\">\n <mat-form-field appearance=\"outline\"><mat-label>{{ tx('config.emptyState.title') }}</mat-label><input matInput required [(ngModel)]=\"empty.title\" (ngModelChange)=\"onEmptyStateChange()\" /><mat-hint *ngIf=\"!empty.title?.trim()\">{{ tx('config.emptyState.titleRequired') }}</mat-hint></mat-form-field>\n <mat-form-field appearance=\"outline\">\n <mat-label>{{ tx('config.emptyState.icon') }}</mat-label>\n @if (empty.icon) { <mat-icon matPrefix [praxisIcon]=\"empty.icon\" aria-hidden=\"true\"></mat-icon> }\n <input matInput [(ngModel)]=\"empty.icon\" (ngModelChange)=\"onEmptyStateChange()\" />\n <span matSuffix class=\"empty-state-icon-actions\">\n <button mat-icon-button type=\"button\" [attr.aria-label]=\"tx('config.emptyState.pickIcon')\" (click)=\"pickEmptyStateIcon()\"><mat-icon aria-hidden=\"true\">search</mat-icon></button>\n @if (empty.icon) { <button mat-icon-button type=\"button\" [attr.aria-label]=\"tx('config.emptyState.clearIcon')\" (click)=\"empty.icon = ''; onEmptyStateChange()\"><mat-icon aria-hidden=\"true\">close</mat-icon></button> }\n </span>\n </mat-form-field>\n <mat-form-field appearance=\"outline\" class=\"empty-state-description\"><mat-label>{{ tx('config.emptyState.description') }}</mat-label><textarea matInput rows=\"2\" [(ngModel)]=\"empty.description\" (ngModelChange)=\"onEmptyStateChange()\"></textarea></mat-form-field>\n </div>\n <details class=\"empty-state-appearance\"><summary>{{ tx('config.emptyState.appearance') }}</summary><div class=\"empty-state-fields\">\n <mat-form-field appearance=\"outline\"><mat-label>{{ tx('config.emptyState.tone') }}</mat-label><mat-select [(ngModel)]=\"empty.tone\" (ngModelChange)=\"onEmptyStateChange()\"><mat-option [value]=\"undefined\">{{ tx('config.emptyState.inherit') }}</mat-option>@for (value of emptyStateOptions.tone; track value) { <mat-option [value]=\"value\">{{ tx('config.emptyState.option.' + value) }}</mat-option> }</mat-select></mat-form-field>\n <mat-form-field appearance=\"outline\"><mat-label>{{ tx('config.emptyState.variant') }}</mat-label><mat-select [(ngModel)]=\"empty.variant\" (ngModelChange)=\"onEmptyStateChange()\"><mat-option [value]=\"undefined\">{{ tx('config.emptyState.inherit') }}</mat-option>@for (value of emptyStateOptions.variant; track value) { <mat-option [value]=\"value\">{{ tx('config.emptyState.option.' + value) }}</mat-option> }</mat-select></mat-form-field>\n <mat-form-field appearance=\"outline\"><mat-label>{{ tx('config.emptyState.alignment') }}</mat-label><mat-select [(ngModel)]=\"empty.alignment\" (ngModelChange)=\"onEmptyStateChange()\"><mat-option [value]=\"undefined\">{{ tx('config.emptyState.inherit') }}</mat-option>@for (value of emptyStateOptions.alignment; track value) { <mat-option [value]=\"value\">{{ tx('config.emptyState.option.' + value) }}</mat-option> }</mat-select></mat-form-field>\n <mat-form-field appearance=\"outline\"><mat-label>{{ tx('config.emptyState.density') }}</mat-label><mat-select [(ngModel)]=\"empty.density\" (ngModelChange)=\"onEmptyStateChange()\"><mat-option [value]=\"undefined\">{{ tx('config.emptyState.inherit') }}</mat-option>@for (value of emptyStateOptions.density; track value) { <mat-option [value]=\"value\">{{ tx('config.emptyState.option.' + value) }}</mat-option> }</mat-select></mat-form-field>\n <mat-form-field appearance=\"outline\"><mat-label>{{ tx('config.emptyState.iconContainer') }}</mat-label><mat-select [(ngModel)]=\"empty.iconContainer\" (ngModelChange)=\"onEmptyStateChange()\"><mat-option [value]=\"undefined\">{{ tx('config.emptyState.inherit') }}</mat-option>@for (value of emptyStateOptions.iconContainer; track value) { <mat-option [value]=\"value\">{{ tx('config.emptyState.option.' + value) }}</mat-option> }</mat-select></mat-form-field>\n </div></details>\n }\n </mat-card-content>\n </mat-card>\n }\n\n @if (hasResolvedRuntimeContract()) {\n <mat-card\n class=\"section-card\"\n data-testid=\"config-tab-runtime-contract\"\n >\n <mat-card-content>\n <div class=\"section-header\">\n <div>\n <h3>{{ tx('config.general.runtimeContract.title', 'Contrato Runtime Resolvido') }}</h3>\n <p class=\"text-caption\">\n {{ tx('config.general.runtimeContract.subtitle', 'Visualiza\u00E7\u00E3o somente leitura do contrato backend resolvido pelo host atual.') }}\n </p>\n </div>\n </div>\n <div class=\"block-status block-status--readonly\">\n <strong>{{ tx('config.general.runtimeContract.runtimeLabel', 'Runtime') }}</strong>\n <span>\n {{ tx('config.general.runtimeContract.readonly', 'Esses valores v\u00EAm do host/runtime atual e n\u00E3o s\u00E3o persistidos em `bindings` nem em `contextSnapshot`.') }}\n </span>\n </div>\n <div class=\"runtime-contract-grid\">\n <div class=\"runtime-contract-field\">\n <span class=\"runtime-contract-label\">{{ tx('config.general.runtimeContract.schemaUrl', 'Schema URL') }}</span>\n <code class=\"runtime-contract-code\">{{ runtimeContract?.schemaUrl || '\u2014' }}</code>\n </div>\n <div class=\"runtime-contract-field\">\n <span class=\"runtime-contract-label\">{{ tx('config.general.runtimeContract.schemaSource', 'Origem do schema') }}</span>\n <strong>{{ describeRuntimeSource(runtimeContract?.schemaSource) }}</strong>\n </div>\n <div class=\"runtime-contract-field\">\n <span class=\"runtime-contract-label\">{{ tx('config.general.runtimeContract.submitMethod', 'Submit method') }}</span>\n <strong>{{ runtimeContract?.submitMethod || '\u2014' }}</strong>\n </div>\n <div class=\"runtime-contract-field\">\n <span class=\"runtime-contract-label\">{{ tx('config.general.runtimeContract.submitUrl', 'Submit URL') }}</span>\n <code class=\"runtime-contract-code\">{{ runtimeContract?.submitUrl || '\u2014' }}</code>\n </div>\n <div class=\"runtime-contract-field\">\n <span class=\"runtime-contract-label\">{{ tx('config.general.runtimeContract.submitSource', 'Origem do submit') }}</span>\n <strong>{{ describeRuntimeSource(runtimeContract?.submitSource) }}</strong>\n </div>\n </div>\n </mat-card-content>\n </mat-card>\n }\n </div>\n </mat-tab>\n <mat-tab [label]=\"configTabLabel('schema')\">\n <div class=\"tab-content\" data-testid=\"config-tab-panel-schema\">\n <mat-card class=\"section-card\">\n <mat-card-content>\n <div class=\"section-header\">\n <div>\n <h3>{{ tx('config.schema.title', 'Valida\u00E7\u00E3o de schema') }}</h3>\n <p class=\"text-caption\">{{ tx('config.schema.subtitle', 'Controle avisos quando o schema do servidor mudar.') }}</p>\n </div>\n </div>\n <div class=\"form-grid\">\n <div class=\"form-row\">\n <mat-form-field appearance=\"fill\" class=\"w-100\">\n <mat-label>{{ tx('config.schema.notify.label', 'Notificar quando desatualizado') }}</mat-label>\n <mat-select [(ngModel)]=\"schemaPrefs.notifyIfOutdated\" (ngModelChange)=\"onSchemaPrefsChange('schema-prefs-notify')\">\n <mat-option value=\"both\">{{ tx('config.schema.notify.both', 'Banner + Snackbar') }}</mat-option>\n <mat-option value=\"inline\">{{ tx('config.schema.notify.inline', 'Somente Banner') }}</mat-option>\n <mat-option value=\"snackbar\">{{ tx('config.schema.notify.snackbar', 'Somente Snackbar') }}</mat-option>\n <mat-option value=\"none\">{{ tx('config.schema.notify.none', 'Nenhum') }}</mat-option>\n </mat-select>\n </mat-form-field>\n </div>\n <div class=\"form-row\">\n <mat-form-field appearance=\"fill\" class=\"w-100\">\n <mat-label>{{ tx('config.schema.snooze.label', 'Intervalo de sil\u00EAncio (ms)') }}</mat-label>\n <input matInput type=\"number\" [(ngModel)]=\"schemaPrefs.snoozeMs\" (ngModelChange)=\"onSchemaPrefsChange('schema-prefs-snooze')\" />\n </mat-form-field>\n </div>\n <div class=\"form-row\">\n <mat-slide-toggle [(ngModel)]=\"schemaPrefs.autoOpenSettingsOnOutdated\" (ngModelChange)=\"onSchemaPrefsChange('schema-prefs-auto-open')\">\n {{ tx('config.schema.autoOpenSettings', 'Abrir configura\u00E7\u00F5es automaticamente') }}\n </mat-slide-toggle>\n </div>\n @if (serverMeta) {\n <div class=\"form-row\">\n <div class=\"meta-card\">\n <div class=\"meta-row\">\n <span>{{ tx('config.schema.meta.serverHash', 'Server hash') }}</span>\n <strong>{{ serverMeta.serverHash || '\u2014' }}</strong>\n </div>\n <div class=\"meta-row\">\n <span>{{ tx('config.schema.meta.lastVerifiedAt', '\u00DAltima verifica\u00E7\u00E3o') }}</span>\n <strong>{{ serverMeta.lastVerifiedAt || '\u2014' }}</strong>\n </div>\n </div>\n </div>\n }\n <div class=\"block-status\" [class.block-status--implicit]=\"!isSchemaPrefsBlockPersisted()\">\n <strong>{{ tx('config.schema.prefs.label', 'Schema Prefs') }}</strong>\n @if (isSchemaPrefsBlockPersisted()) {\n <span>{{ tx('config.schema.prefs.persisted', '`contextSnapshot.schemaPrefs` ser\u00E1 persistido no documento can\u00F4nico.') }}</span>\n } @else {\n {{ tx('config.schema.prefs.implicit', 'Bloco ausente no documento can\u00F4nico. Os controles exibem fallback visual e n\u00E3o ser\u00E3o salvos at\u00E9 voc\u00EA editar.') }}\n }\n </div>\n </div>\n </mat-card-content>\n </mat-card>\n </div>\n </mat-tab>\n <mat-tab [label]=\"configTabLabel('layout')\">\n <div class=\"tab-content tab-content--full\" data-testid=\"config-tab-panel-layout\">\n <div class=\"section-header section-header--compact\">\n <div>\n <h3>{{ tx('config.layout.title', 'Layout do formul\u00E1rio') }}</h3>\n <p class=\"text-caption\">{{ tx('config.layout.subtitle', 'Organize se\u00E7\u00F5es, linhas e campos com drag & drop.') }}</p>\n </div>\n </div>\n <div class=\"section-body section-body--flex\">\n <praxis-layout-editor [config]=\"editedConfig\" (configChange)=\"onConfigChange($event)\"\n (select)=\"onLayoutSelect($event)\"></praxis-layout-editor>\n </div>\n </div>\n </mat-tab>\n <mat-tab [label]=\"configTabLabel('hooks')\">\n <div class=\"tab-content\" data-testid=\"config-tab-panel-hooks\">\n <mat-card class=\"section-card\">\n <mat-card-content>\n <div class=\"section-header\">\n <div>\n <h3>{{ tx('config.hooks.title', 'Hooks de ciclo de vida') }}</h3>\n <p class=\"text-caption\">{{ tx('config.hooks.subtitle', 'Automatize a\u00E7\u00F5es nos eventos do formul\u00E1rio.') }}</p>\n </div>\n </div>\n <praxis-hooks-editor [config]=\"editedConfig\" (configChange)=\"onConfigChange($event)\"></praxis-hooks-editor>\n </mat-card-content>\n </mat-card>\n </div>\n </mat-tab>\n @if (isPresentationMode) {\n <mat-tab [label]=\"configTabLabel('presentation')\">\n <div class=\"tab-content\" data-testid=\"config-tab-panel-presentation\">\n <mat-card class=\"section-card\">\n <mat-card-content>\n <div class=\"section-header\">\n <div>\n <h3>{{ tx('config.presentation.title', 'Modo Apresenta\u00E7\u00E3o') }}</h3>\n <p class=\"text-caption\">{{ tx('config.presentation.subtitle', 'Configura\u00E7\u00F5es de exibi\u00E7\u00E3o aplicadas somente ao modo apresenta\u00E7\u00E3o.') }}</p>\n </div>\n </div>\n <p class=\"display-result\" role=\"status\">{{ tx(displayModeHint) }}</p>\n <div class=\"presentation-layout\">\n <div class=\"presentation-controls\">\n <div class=\"block-status control-span\" [class.block-status--implicit]=\"!isPresentationBlockPersisted()\">\n <strong>{{ tx('config.presentation.block.label', 'Presentation') }}</strong>\n @if (isPresentationBlockPersisted()) {\n <span>{{ tx('config.presentation.block.persisted', '`contextSnapshot.presentation` ser\u00E1 persistido no documento can\u00F4nico.') }}</span>\n } @else {\n {{ tx('config.presentation.block.implicit', 'Bloco ausente no documento can\u00F4nico. A pr\u00E9-visualiza\u00E7\u00E3o usa fallback local e n\u00E3o ser\u00E1 salva at\u00E9 voc\u00EA editar.') }}\n }\n </div>\n <div class=\"control\">\n <label class=\"control__label\">{{ tx('config.presentation.labelPosition.label', 'Posi\u00E7\u00E3o do r\u00F3tulo') }}</label>\n <mat-button-toggle-group [(ngModel)]=\"presentationPrefs.labelPosition\" (ngModelChange)=\"onPresentationPrefsChange('presentation-label-position')\" [attr.aria-label]=\"tx('config.presentation.labelPosition.ariaLabel', 'Posi\u00E7\u00E3o do r\u00F3tulo')\"\n class=\"toggle-group\">\n <mat-button-toggle value=\"above\">\n <mat-icon>view_stream</mat-icon>\n <span class=\"sr-only\">{{ tx('config.presentation.labelPosition.above', 'Acima') }}</span>\n </mat-button-toggle>\n <mat-button-toggle value=\"left\">\n <mat-icon>view_column</mat-icon>\n <span class=\"sr-only\">{{ tx('config.presentation.labelPosition.left', '\u00C0 esquerda') }}</span>\n </mat-button-toggle>\n </mat-button-toggle-group>\n </div>\n <div class=\"control control-span\">\n <label class=\"control__label\">{{ tx('config.presentation.density.label', 'Densidade') }}</label>\n <mat-button-toggle-group [(ngModel)]=\"presentationPrefs.density\" (ngModelChange)=\"onPresentationPrefsChange('presentation-density')\" [attr.aria-label]=\"tx('config.presentation.density.ariaLabel', 'Densidade')\"\n class=\"toggle-group\">\n <mat-button-toggle value=\"comfortable\">{{ tx('config.presentation.density.comfortable', 'Confort\u00E1vel') }}</mat-button-toggle>\n <mat-button-toggle value=\"cozy\">{{ tx('config.presentation.density.cozy', 'Intermedi\u00E1ria') }}</mat-button-toggle>\n <mat-button-toggle value=\"compact\">{{ tx('config.presentation.density.compact', 'Compacta') }}</mat-button-toggle>\n </mat-button-toggle-group>\n </div>\n <div class=\"control\">\n <label class=\"control__label\">{{ tx('config.presentation.labelAlign.label', 'Alinhamento do r\u00F3tulo') }}</label>\n <mat-button-toggle-group [(ngModel)]=\"presentationPrefs.labelAlign\" (ngModelChange)=\"onPresentationPrefsChange('presentation-label-align')\" [attr.aria-label]=\"tx('config.presentation.labelAlign.ariaLabel', 'Alinhamento do r\u00F3tulo')\"\n class=\"toggle-group\">\n <mat-button-toggle value=\"start\" [aria-label]=\"tx('config.presentation.align.start')\" [matTooltip]=\"tx('config.presentation.align.start')\"><mat-icon>format_align_left</mat-icon></mat-button-toggle>\n <mat-button-toggle value=\"center\" [aria-label]=\"tx('config.presentation.align.center')\" [matTooltip]=\"tx('config.presentation.align.center')\"><mat-icon>format_align_center</mat-icon></mat-button-toggle>\n <mat-button-toggle value=\"end\" [aria-label]=\"tx('config.presentation.align.end')\" [matTooltip]=\"tx('config.presentation.align.end')\"><mat-icon>format_align_right</mat-icon></mat-button-toggle>\n </mat-button-toggle-group>\n </div>\n <div class=\"control\">\n <label class=\"control__label\">{{ tx('config.presentation.valueAlign.label', 'Alinhamento do valor') }}</label>\n <mat-button-toggle-group [(ngModel)]=\"presentationPrefs.valueAlign\" (ngModelChange)=\"onPresentationPrefsChange('presentation-value-align')\" [attr.aria-label]=\"tx('config.presentation.valueAlign.ariaLabel', 'Alinhamento do valor')\"\n class=\"toggle-group\">\n <mat-button-toggle value=\"start\" [aria-label]=\"tx('config.presentation.align.start')\" [matTooltip]=\"tx('config.presentation.align.start')\"><mat-icon>format_align_left</mat-icon></mat-button-toggle>\n <mat-button-toggle value=\"center\" [aria-label]=\"tx('config.presentation.align.center')\" [matTooltip]=\"tx('config.presentation.align.center')\"><mat-icon>format_align_center</mat-icon></mat-button-toggle>\n <mat-button-toggle value=\"end\" [aria-label]=\"tx('config.presentation.align.end')\" [matTooltip]=\"tx('config.presentation.align.end')\"><mat-icon>format_align_right</mat-icon></mat-button-toggle>\n </mat-button-toggle-group>\n </div>\n <div class=\"control\">\n <mat-form-field appearance=\"fill\" class=\"w-100\">\n <mat-label>{{ tx('config.presentation.labelFontSize.label', 'Tamanho do r\u00F3tulo') }}</mat-label>\n <input matInput type=\"number\" min=\"10\" step=\"any\" [(ngModel)]=\"presentationPrefs.labelFontSize\" (ngModelChange)=\"onPresentationPrefsChange('presentation-label-font-size')\"\n [placeholder]=\"tx('config.presentation.labelFontSize.placeholder', 'ex.: 12')\" />\n <span matSuffix>px</span>\n </mat-form-field>\n </div>\n <div class=\"control\">\n <mat-form-field appearance=\"fill\" class=\"w-100\">\n <mat-label>{{ tx('config.presentation.valueFontSize.label', 'Tamanho do valor') }}</mat-label>\n <input matInput type=\"number\" min=\"10\" step=\"any\" [(ngModel)]=\"presentationPrefs.valueFontSize\" (ngModelChange)=\"onPresentationPrefsChange('presentation-value-font-size')\"\n [placeholder]=\"tx('config.presentation.valueFontSize.placeholder', 'ex.: 16')\" />\n <span matSuffix>px</span>\n </mat-form-field>\n </div>\n <div class=\"control\">\n <mat-form-field appearance=\"fill\" class=\"w-100\">\n <mat-label>{{ tx('config.presentation.labelWidth.label', 'Largura do r\u00F3tulo (label \u00E0 esquerda)') }}</mat-label>\n <input matInput type=\"number\" min=\"60\" [disabled]=\"presentationPrefs.labelPosition !== 'left'\" [(ngModel)]=\"presentationPrefs.labelWidth\" (ngModelChange)=\"onPresentationPrefsChange('presentation-label-width')\"\n [placeholder]=\"tx('config.presentation.labelWidth.placeholder', 'ex.: 140')\" />\n <span matSuffix>px</span>\n </mat-form-field>\n </div>\n <div class=\"control control--inline\">\n <mat-slide-toggle [(ngModel)]=\"presentationPrefs.compact\" (ngModelChange)=\"onPresentationPrefsChange('presentation-compact')\">\n {{ tx('config.presentation.options.compactMode', 'Modo compacto') }}\n </mat-slide-toggle>\n <mat-checkbox [(ngModel)]=\"truncatePreview\">\n {{ tx('config.presentation.options.truncateValues', 'Truncar valores') }}\n </mat-checkbox>\n </div>\n </div>\n <div class=\"presentation-preview\">\n <h4>{{ tx('config.presentation.preview.title', 'Pr\u00E9-visualiza\u00E7\u00E3o') }}</h4>\n <p class=\"text-caption\">{{ tx('config.presentation.preview.sampleHint') }}</p>\n <div class=\"preview-card\">\n <div class=\"praxis-dynamic-form presentation-mode\" [ngClass]=\"{\n 'pres-compact': !!presentationPrefs.compact,\n 'pres-label-left': presentationPrefs.labelPosition === 'left',\n 'pres-label-above': presentationPrefs.labelPosition === 'above',\n 'pres-density-compact': presentationPrefs.density === 'compact',\n 'pres-density-cozy': presentationPrefs.density === 'cozy'\n }\" [style.--pfx-pres-label-size]=\"(presentationPrefs.labelFontSize || 12) + 'px'\"\n [style.--pfx-pres-value-size]=\"(presentationPrefs.valueFontSize || 16) + 'px'\"\n [style.--pfx-pres-label-width]=\"(presentationPrefs.labelWidth || 140) + 'px'\"\n [style.--pfx-pres-label-align]=\"presentationPrefs.labelAlign || 'start'\"\n [style.--pfx-pres-value-align]=\"presentationPrefs.valueAlign || 'start'\">\n @for (item of previewItems; track item) {\n <div class=\"preview-row\">\n <span class=\"praxis-presentation__label\">{{ item.label }}</span>\n <span class=\"praxis-presentation__value\" [attr.title]=\"truncatePreview ? item.value : null\"\n [style.maxWidth]=\"truncatePreview ? '280px' : null\"\n [style.overflow]=\"truncatePreview ? 'hidden' : null\"\n [style.textOverflow]=\"truncatePreview ? 'ellipsis' : null\"\n [style.whiteSpace]=\"truncatePreview ? 'nowrap' : 'normal'\">\n {{ item.value }}\n </span>\n </div>\n }\n </div>\n </div>\n </div>\n </div>\n\n </mat-card-content>\n </mat-card>\n </div>\n </mat-tab>\n }\n <mat-tab [label]=\"configTabLabel('behavior')\">\n <div class=\"tab-content\" data-testid=\"config-tab-panel-comportamento\">\n <mat-card class=\"section-card\">\n <mat-card-content>\n <div class=\"section-header\">\n <div>\n <h3>{{ tx('config.behavior.title', 'Comportamento') }}</h3>\n <p class=\"text-caption\">{{ tx('config.behavior.subtitle', 'Ajuste valida\u00E7\u00F5es e respostas do formul\u00E1rio.') }}</p>\n </div>\n </div>\n <praxis-behavior-editor [config]=\"editedConfig\" (configChange)=\"onConfigChange($event)\"></praxis-behavior-editor>\n </mat-card-content>\n </mat-card>\n </div>\n </mat-tab>\n <mat-tab [label]=\"configTabLabel('hints')\">\n <div class=\"tab-content tab-content--dense\" data-testid=\"config-tab-panel-hints\">\n <mat-card class=\"section-card\">\n <mat-card-content>\n <div class=\"section-header\">\n <div>\n <h3>{{ tx('config.hints.title', 'Dicas dos modos') }}</h3>\n <p class=\"text-caption\">{{ tx('config.hints.subtitle', 'Personalize textos de apoio para modos de dados e estados de UI.') }}</p>\n </div>\n </div>\n <p class=\"text-caption\">{{ tx('config.hints.description', 'Personalize os textos usados como tooltip/hint para modos de dados e modos globais de UI.') }}</p>\n\n <div class=\"grid-2-cols grid-2-cols--compact\">\n <section>\n <h4>{{ tx('config.hints.dataModes.title', 'Modos de dados') }}</h4>\n <mat-form-field appearance=\"fill\" class=\"w-100\">\n <mat-label>{{ tx('config.hints.dataModes.create.label', 'Criar') }}</mat-label>\n <input matInput [(ngModel)]=\"editedConfig.hints!.dataModes.create\"\n (ngModelChange)=\"updateDirtyState('hints-data-create')\" [placeholder]=\"tx('config.hints.dataModes.create.placeholder', 'Ex.: Preencha os campos obrigat\u00F3rios.')\" />\n </mat-form-field>\n <mat-form-field appearance=\"fill\" class=\"w-100\">\n <mat-label>{{ tx('config.hints.dataModes.edit.label', 'Editar') }}</mat-label>\n <input matInput [(ngModel)]=\"editedConfig.hints!.dataModes.edit\"\n (ngModelChange)=\"updateDirtyState('hints-data-edit')\" [placeholder]=\"tx('config.hints.dataModes.edit.placeholder', 'Ex.: Revise os dados antes de salvar.')\" />\n </mat-form-field>\n <mat-form-field appearance=\"fill\" class=\"w-100\">\n <mat-label>{{ tx('config.hints.dataModes.view.label', 'Visualizar') }}</mat-label>\n <input matInput [(ngModel)]=\"editedConfig.hints!.dataModes.view\"\n (ngModelChange)=\"updateDirtyState('hints-data-view')\" [placeholder]=\"tx('config.hints.dataModes.view.placeholder', 'Ex.: Visualiza\u00E7\u00E3o somente leitura.')\" />\n </mat-form-field>\n </section>\n\n <section>\n <h4>{{ tx('config.hints.uiModes.title', 'Modos de UI') }}</h4>\n <mat-form-field appearance=\"fill\" class=\"w-100\">\n <mat-label>{{ tx('config.hints.uiModes.presentation.label', 'Apresenta\u00E7\u00E3o') }}</mat-label>\n <textarea matInput rows=\"2\" [(ngModel)]=\"editedConfig.hints!.uiModes.presentation\"\n (ngModelChange)=\"updateDirtyState('hints-ui-presentation')\" [placeholder]=\"tx('config.hints.uiModes.presentation.placeholder', 'Ex.: Modo compacto para leitura r\u00E1pida.')\"></textarea>\n </mat-form-field>\n <mat-form-field appearance=\"fill\" class=\"w-100\">\n <mat-label>{{ tx('config.hints.uiModes.readonly.label', 'Leitura (readonly)') }}</mat-label>\n <textarea matInput rows=\"2\" [(ngModel)]=\"editedConfig.hints!.uiModes.readonly\"\n (ngModelChange)=\"updateDirtyState('hints-ui-readonly')\" [placeholder]=\"tx('config.hints.uiModes.readonly.placeholder', 'Ex.: Campos bloqueados para edi\u00E7\u00E3o.')\"></textarea>\n </mat-form-field>\n <mat-form-field appearance=\"fill\" class=\"w-100\">\n <mat-label>{{ tx('config.hints.uiModes.disabled.label', 'Desabilitado') }}</mat-label>\n <textarea matInput rows=\"2\" [(ngModel)]=\"editedConfig.hints!.uiModes.disabled\"\n (ngModelChange)=\"updateDirtyState('hints-ui-disabled')\" [placeholder]=\"tx('config.hints.uiModes.disabled.placeholder', 'Ex.: Fun\u00E7\u00E3o indispon\u00EDvel no momento.')\"></textarea>\n </mat-form-field>\n <mat-form-field appearance=\"fill\" class=\"w-100\">\n <mat-label>{{ tx('config.hints.uiModes.visible.label', 'Vis\u00EDvel') }}</mat-label>\n <textarea matInput rows=\"2\" [(ngModel)]=\"editedConfig.hints!.uiModes.visible\"\n (ngModelChange)=\"updateDirtyState('hints-ui-visible')\" [placeholder]=\"tx('config.hints.uiModes.visible.placeholder', 'Ex.: Campo exibido conforme permiss\u00F5es.')\"></textarea>\n </mat-form-field>\n </section>\n </div>\n\n <section>\n <h4>{{ tx('config.helpPresentation.title', 'Apresenta\u00E7\u00E3o das ajudas dos campos') }}</h4>\n <p class=\"text-caption\">{{ tx('config.helpPresentation.description', 'Controle como hint/helpText dos campos aparece em formul\u00E1rios densos. Erros de valida\u00E7\u00E3o continuam inline.') }}</p>\n <div class=\"grid-3-cols\">\n <mat-form-field appearance=\"fill\" class=\"w-100\">\n <mat-label>{{ tx('config.helpPresentation.display.label', 'Exibi\u00E7\u00E3o') }}</mat-label>\n <mat-select [ngModel]=\"helpPresentationDraft.display\" (ngModelChange)=\"onHelpPresentationDisplayChange($event)\">\n <mat-option value=\"inline\">{{ tx('config.helpPresentation.display.inline', 'Inline') }}</mat-option>\n <mat-option value=\"popover\">{{ tx('config.helpPresentation.display.popover', '\u00CDcone de ajuda') }}</mat-option>\n <mat-option value=\"auto\">{{ tx('config.helpPresentation.display.auto', 'Autom\u00E1tica') }}</mat-option>\n <mat-option value=\"hidden\">{{ tx('config.helpPresentation.display.hidden', 'Oculta') }}</mat-option>\n </mat-select>\n </mat-form-field>\n <mat-form-field appearance=\"fill\" class=\"w-100\">\n <mat-label>{{ tx('config.helpPresentation.inlineMaxLength.label', 'Limite inline') }}</mat-label>\n <input matInput type=\"number\" min=\"0\" [ngModel]=\"helpPresentationDraft.inlineMaxLength\"\n (ngModelChange)=\"onHelpPresentationInlineMaxLengthChange($event)\" />\n </mat-form-field>\n <mat-form-field appearance=\"fill\" class=\"w-100\">\n <mat-label>{{ tx('config.helpPresentation.preferPopoverForControls.label', 'Preferir \u00EDcone em') }}</mat-label>\n <input matInput [ngModel]=\"getHelpPreferPopoverControlsText()\"\n (ngModelChange)=\"onHelpPreferPopoverControlsChange($event)\"\n [placeholder]=\"tx('config.helpPresentation.preferPopoverForControls.placeholder', 'toggle, checkbox, select')\" />\n </mat-form-field>\n </div>\n </section>\n\n <div class=\"actions-row\">\n <button mat-stroked-button color=\"primary\" type=\"button\" (click)=\"restoreHintsDefaults()\">\n <mat-icon>restore</mat-icon>\n {{ tx('config.hints.actions.restoreDefaults', 'Restaurar padr\u00F5es') }}\n </button>\n </div>\n </mat-card-content>\n </mat-card>\n </div>\n </mat-tab>\n <mat-tab [label]=\"configTabLabel('actions')\">\n <div class=\"tab-content\" data-testid=\"config-tab-panel-acoes\">\n <mat-card class=\"section-card\">\n <mat-card-content>\n <div class=\"section-header\">\n <div>\n <h3>{{ tx('config.actions.title', 'A\u00E7\u00F5es do formul\u00E1rio') }}</h3>\n <p class=\"text-caption\">{{ tx('config.actions.subtitle', 'Configure bot\u00F5es padr\u00E3o e a\u00E7\u00F5es customizadas.') }}</p>\n </div>\n </div>\n <praxis-actions-editor #actionsDraft [config]=\"editedConfig\" (validationChange)=\"onSurfaceDraftValidity(actionsDraft, $event)\" (configChange)=\"onConfigChange($event)\"></praxis-actions-editor>\n </mat-card-content>\n </mat-card>\n </div>\n </mat-tab>\n <mat-tab [label]=\"configTabLabel('rules')\">\n <div class=\"tab-content visual-builder-content\" data-testid=\"config-tab-panel-regras\">\n <div class=\"builder-header\">\n <div>\n <h3>{{ tx('config.rules.title', 'Regras visuais') }}</h3>\n <p class=\"text-caption\">{{ tx('config.rules.subtitle', 'Defina visibilidade, estilos e rea\u00E7\u00F5es baseadas em condi\u00E7\u00F5es.') }}</p>\n </div>\n </div>\n @if (ruleDiagnostics.length) {\n <div class=\"rules-diagnostics\" data-testid=\"rules-diagnostics-panel\">\n <div class=\"rules-diagnostics__summary\">\n <span class=\"rules-diagnostics__pill rules-diagnostics__pill--total\">\n {{ tx('config.rules.summary.total', '{{count}} regras', { count: ruleDiagnosticsSummary.total }) }}\n </span>\n @if (ruleDiagnosticsSummary.invalid) {\n <span class=\"rules-diagnostics__pill rules-diagnostics__pill--error\">\n {{ tx('config.rules.summary.invalid', '{{count}} inv\u00E1lidas', { count: ruleDiagnosticsSummary.invalid }) }}\n </span>\n }\n @if (ruleDiagnosticsSummary.unsupported) {\n <span class=\"rules-diagnostics__pill rules-diagnostics__pill--warn\">\n {{ tx('config.rules.summary.unsupported', '{{count}} com propriedades rejeitadas', { count: ruleDiagnosticsSummary.unsupported }) }}\n </span>\n }\n @if (ruleDiagnosticsSummary.runtimeOnly) {\n <span class=\"rules-diagnostics__pill rules-diagnostics__pill--warn\">\n {{ tx('config.rules.summary.runtimeOnly', '{{count}} runtime only', { count: ruleDiagnosticsSummary.runtimeOnly }) }}\n </span>\n }\n @if (ruleDiagnosticsSummary.pendingReview) {\n <span class=\"rules-diagnostics__pill rules-diagnostics__pill--warn\">\n {{ tx('config.rules.summary.pendingReview', '{{count}} pendentes de revis\u00E3o', { count: ruleDiagnosticsSummary.pendingReview }) }}\n </span>\n }\n </div>\n <div class=\"rules-diagnostics__list\" [attr.aria-label]=\"tx('config.rules.diagnostics.ariaLabel', 'Diagn\u00F3stico das regras')\">\n @for (diagnostic of ruleDiagnostics; track diagnostic) {\n <article class=\"rules-diagnostics__item\"\n [class.rules-diagnostics__item--error]=\"getRuleStatusTone(diagnostic) === 'error'\"\n [class.rules-diagnostics__item--warn]=\"getRuleStatusTone(diagnostic) === 'warn'\">\n <div>\n <strong>{{ diagnostic.ruleName || diagnostic.ruleId }}</strong>\n <span>\n {{ tx('config.rules.diagnostics.targetConditionSummary', '{{targets}} alvo(s) \u00B7 {{conditions}} campo(s) na condi\u00E7\u00E3o', { targets: diagnostic.targetRefs.length, conditions: diagnostic.conditionRefs.length }) }}\n </span>\n @if (getRuleDiagnosticDetails(diagnostic).length) {\n <ul class=\"rules-diagnostics__details\">\n @for (detail of getRuleDiagnosticDetails(diagnostic); track detail) {\n <li>{{ detail }}</li>\n }\n </ul>\n }\n </div>\n <div class=\"rules-diagnostics__actions\">\n <span class=\"rules-diagnostics__status\">{{ getRuleStatusLabel(diagnostic) }}</span>\n @if (canApplyRulePropertyFix(diagnostic)) {\n <button\n mat-stroked-button\n type=\"button\"\n class=\"rules-diagnostics__action\"\n [matTooltip]=\"tx('config.rules.actions.fix.tooltip', 'Aplicar whitelist e saneamento de propriedades nesta regra')\"\n (click)=\"applyRulePropertyFix(diagnostic.ruleId)\">\n <mat-icon aria-hidden=\"true\">auto_fix_high</mat-icon>\n {{ tx('config.rules.actions.fix', 'Corrigir') }}\n </button>\n }\n @if (diagnostic.status.includes('llm-generated-pending-review')) {\n <button\n mat-stroked-button\n type=\"button\"\n class=\"rules-diagnostics__action\"\n [disabled]=\"!canAcceptPendingLlmRule(diagnostic)\"\n [matTooltip]=\"canAcceptPendingLlmRule(diagnostic) ? tx('config.rules.actions.accept.tooltip.ready', 'Aceitar sugest\u00E3o e atualizar estado visual') : tx('config.rules.actions.accept.tooltip.blocked', 'Corrija alvo, condi\u00E7\u00E3o e propriedades antes de aceitar')\"\n (click)=\"acceptPendingLlmRule(diagnostic.ruleId)\">\n <mat-icon aria-hidden=\"true\">check</mat-icon>\n {{ tx('config.rules.actions.accept', 'Aceitar') }}\n </button>\n }\n @if (canOpenRuleJsonReview(diagnostic)) {\n <button\n mat-stroked-button\n type=\"button\"\n class=\"rules-diagnostics__action\"\n [matTooltip]=\"tx('config.rules.actions.reviewJson.tooltip', 'Abrir a aba JSON para revisar esta regra sem convers\u00E3o visual')\"\n (click)=\"openRuleJsonReview(diagnostic.ruleId)\">\n <mat-icon aria-hidden=\"true\">data_object</mat-icon>\n {{ tx('config.rules.actions.reviewJson', 'Ver JSON') }}\n </button>\n }\n </div>\n </article>\n }\n </div>\n </div>\n } @else {\n <div class=\"rules-diagnostics rules-diagnostics--empty\" data-testid=\"rules-diagnostics-empty\">\n {{ tx('config.rules.empty', 'Nenhuma regra definida ainda. Crie uma regra para ver alvos, condi\u00E7\u00E3o, propriedades e compatibilidade do builder.') }}\n </div>\n }\n <praxis-visual-builder [config]=\"ruleBuilderConfig\" [initialRules]=\"ruleBuilderState\"\n (rulesChanged)=\"onRulesChanged($event)\"></praxis-visual-builder>\n <praxis-rule-properties-panel\n [rules]=\"currentRules\"\n [visualBlockNodes]=\"visualBlockNodeOptions\"\n (rulesChange)=\"onRulePropertiesChanged($event)\"\n ></praxis-rule-properties-panel>\n <mat-card class=\"command-rules-card\" data-testid=\"form-command-rules-editor\">\n <mat-card-title>{{ tx('config.commandRules.title', 'Comandos condicionais') }}</mat-card-title>\n <mat-card-subtitle>{{ tx('config.commandRules.subtitle', 'Execute a\u00E7\u00F5es globais quando uma condi\u00E7\u00E3o do formul\u00E1rio for satisfeita.') }}</mat-card-subtitle>\n <mat-card-content>\n <div class=\"command-rules-grid\">\n <div class=\"command-rules-toolbar\">\n <mat-form-field appearance=\"fill\" class=\"command-rules-select\">\n <mat-label>{{ tx('config.commandRules.command.label', 'Comando') }}</mat-label>\n <mat-select [disabled]=\"hasInvalidSurfaceDraft\" [(ngModel)]=\"selectedCommandRuleId\" (selectionChange)=\"onCommandRuleSelectionChange()\">\n @for (rule of commandRules; track rule) {\n <mat-option [value]=\"rule.id\">\n {{ rule.id }}\n </mat-option>\n }\n </mat-select>\n </mat-form-field>\n <button mat-stroked-button type=\"button\" [disabled]=\"hasInvalidSurfaceDraft\" (click)=\"addCommandRule()\">\n <mat-icon aria-hidden=\"true\">add</mat-icon>\n {{ tx('config.commandRules.actions.add', 'Adicionar') }}\n </button>\n <button mat-stroked-button color=\"warn\" type=\"button\" (click)=\"deleteCommandRule()\" [disabled]=\"hasInvalidSurfaceDraft || !selectedCommandRuleId\">\n <mat-icon aria-hidden=\"true\">delete</mat-icon>\n {{ tx('config.commandRules.actions.remove', 'Remover') }}\n </button>\n </div>\n\n @if (selectedCommandRuleId) {\n <div class=\"command-rule-condition-builder command-rules-full\">\n <praxis-visual-builder\n mode=\"condition\"\n [config]=\"ruleBuilderConfig\"\n [initialCondition]=\"commandRuleCondition\"\n (conditionChanged)=\"onCommandConditionChanged($event)\"\n ></praxis-visual-builder>\n </div>\n }\n\n <mat-form-field appearance=\"fill\" class=\"command-rules-full\">\n <mat-label>{{ tx('config.commandRules.conditionJson.label', 'Condi\u00E7\u00E3o JSON Logic') }}</mat-label>\n <textarea\n matInput\n rows=\"5\"\n [(ngModel)]=\"commandRuleConditionJson\"\n [attr.aria-label]=\"tx('config.commandRules.conditionJson.ariaLabel', 'Condi\u00E7\u00E3o JSON Logic do comando condicional')\"\n ></textarea>\n </mat-form-field>\n\n <mat-form-field appearance=\"fill\">\n <mat-label>{{ tx('config.commandRules.globalAction.label', 'A\u00E7\u00E3o global') }}</mat-label>\n <mat-select [disabled]=\"hasInvalidSurfaceDraft\" [(ngModel)]=\"commandRuleActionId\" (selectionChange)=\"onCommandActionChange()\">\n @for (action of globalActionCatalog; track action) {\n <mat-option [value]=\"action.id\">\n {{ action.label || action.id }}\n </mat-option>\n }\n </mat-select>\n </mat-form-field>\n\n <mat-form-field appearance=\"fill\">\n <mat-label>{{ tx('config.commandRules.distinctBy.label', 'distinctBy') }}</mat-label>\n <input matInput [(ngModel)]=\"commandRuleDistinctBy\" [placeholder]=\"tx('config.commandRules.distinctBy.placeholder', 'ex.: idade')\" />\n </mat-form-field>\n\n @if (commandRuleActionSchema; as actionSchema) {\n <div\n class=\"command-rules-payload-fields command-rules-full\"\n >\n <div class=\"command-rules-section-title\">{{ tx('config.commandRules.structuredPayload.title', 'Payload estruturado') }}</div>\n @if (actionSchema.editorMode !== 'surface-open') {\n @for (field of actionSchema.fields; track field) {\n @if (shouldShowCommandActionField(field)) {\n @if (field.type === 'toggle') {\n <mat-slide-toggle\n [ngModel]=\"getCommandActionFieldValue(field)\"\n (ngModelChange)=\"onCommandActionFieldChange(field, $event)\"\n [ngModelOptions]=\"{ standalone: true }\"\n >\n {{ field.label }}\n </mat-slide-toggle>\n } @else {\n <mat-form-field appearance=\"fill\">\n <mat-label>{{ field.label }}</mat-label>\n @if (field.type === 'textarea' || field.type === 'json') {\n <textarea\n matInput\n [rows]=\"field.rows || (field.type === 'json' ? 3 : 2)\"\n [ngModel]=\"getCommandActionFieldValue(field)\"\n (ngModelChange)=\"onCommandActionFieldChange(field, $event)\"\n [ngModelOptions]=\"{ standalone: true }\"\n [placeholder]=\"field.placeholder || (field.type === 'json' ? '{ }' : '')\"\n [required]=\"isCommandActionFieldRequired(field)\"\n ></textarea>\n } @else {\n @if (field.type === 'select') {\n <mat-select\n [ngModel]=\"getCommandActionFieldValue(field)\"\n (ngModelChange)=\"onCommandActionFieldChange(field, $event)\"\n [ngModelOptions]=\"{ standalone: true }\"\n [required]=\"isCommandActionFieldRequired(field)\"\n >\n @for (option of field.options || []; track option) {\n <mat-option [value]=\"option.value\">\n {{ option.label }}\n </mat-option>\n }\n </mat-select>\n } @else {\n <input\n matInput\n [type]=\"field.type === 'number' ? 'number' : 'text'\"\n [ngModel]=\"getCommandActionFieldValue(field)\"\n (ngModelChange)=\"onCommandActionFieldChange(field, $event)\"\n [ngModelOptions]=\"{ standalone: true }\"\n [placeholder]=\"field.placeholder || ''\"\n [required]=\"isCommandActionFieldRequired(field)\"\n />\n }\n }\n @if (field.hint) {\n <mat-hint>{{ field.hint }}</mat-hint>\n }\n @if (hasCommandActionFieldError(field.key)) {\n <mat-error>\n {{ getCommandActionFieldError(field.key) }}\n </mat-error>\n }\n @if (!hasCommandActionFieldError(field.key) && isCommandActionFieldMissing(field)) {\n <mat-error>\n {{ tx('config.commandRules.validation.requiredField', 'Campo obrigat\u00F3rio.') }}\n </mat-error>\n }\n </mat-form-field>\n }\n }\n }\n } @else {\n <praxis-surface-open-action-editor #commandSurfaceDraft\n class=\"command-rules-surface-editor\"\n data-testid=\"form-command-rule-surface-open-editor\"\n [value]=\"commandRuleSurfaceOpenPayload\"\n hostKind=\"dynamic-form\"\n (valueChange)=\"onCommandSurfaceOpenPayloadChange($event)\"\n (validationChange)=\"onSurfaceDraftValidity(commandSurfaceDraft, $event)\"\n ></praxis-surface-open-action-editor>\n }\n </div>\n }\n\n <mat-form-field appearance=\"fill\" class=\"command-rules-full\">\n <mat-label>{{ tx('config.commandRules.advancedPayload.label', 'Payload JSON avan\u00E7ado') }}</mat-label>\n <textarea\n matInput\n rows=\"4\"\n [(ngModel)]=\"commandRulePayloadJson\"\n [attr.aria-label]=\"tx('config.commandRules.advancedPayload.ariaLabel', 'Payload JSON da a\u00E7\u00E3o global')\"\n ></textarea>\n </mat-form-field>\n\n <div class=\"command-rules-options\">\n <mat-slide-toggle [(ngModel)]=\"commandRuleDistinct\">{{ tx('config.commandRules.options.distinct', 'Evitar repeti\u00E7\u00E3o enquanto a condi\u00E7\u00E3o permanecer verdadeira') }}</mat-slide-toggle>\n <mat-slide-toggle [(ngModel)]=\"commandRuleRunOnInitialEvaluation\">{{ tx('config.commandRules.options.runOnInitialEvaluation', 'Executar tamb\u00E9m na avalia\u00E7\u00E3o inicial') }}</mat-slide-toggle>\n </div>\n\n @if (commandRuleAuthoringError) {\n <div class=\"preview-error command-rules-full\">\n <mat-icon aria-hidden=\"true\">warning</mat-icon>\n <span>{{ commandRuleAuthoringError }}</span>\n </div>\n }\n\n <div\n class=\"command-rule-preview command-rules-full\"\n [class.command-rule-preview--invalid]=\"commandRulePreview.state === 'invalid'\"\n data-testid=\"command-rule-preview\"\n >\n <div class=\"command-rules-section-title\">{{ tx('config.commandRules.preview.title', 'Preview do comando') }}</div>\n <div class=\"command-rule-preview__row\">\n <span>{{ tx('config.commandRules.preview.mode', 'Modo') }}</span>\n <strong>{{ commandRulePreview.executionMode }}</strong>\n </div>\n <div class=\"command-rule-preview__row\">\n <span>{{ tx('config.commandRules.preview.action', 'A\u00E7\u00E3o') }}</span>\n <strong>{{ commandRulePreview.actionId || '\u2014' }}</strong>\n </div>\n <div class=\"command-rule-preview__row\">\n <span>{{ tx('config.commandRules.preview.policy', 'Policy') }}</span>\n <code>{{ commandRulePreview.policy | json }}</code>\n </div>\n @if (commandRulePreview.diagnostics.length) {\n <div class=\"command-rule-preview__diagnostics\">\n <mat-icon aria-hidden=\"true\">{{ commandRulePreview.state === 'invalid' ? 'warning' : 'visibility' }}</mat-icon>\n <span>{{ commandRulePreview.diagnostics[0] }}</span>\n </div>\n }\n </div>\n\n <div class=\"command-rules-actions\">\n <button mat-flat-button color=\"primary\" type=\"button\" (click)=\"applyCommandRule()\">\n <mat-icon aria-hidden=\"true\">check</mat-icon>\n {{ tx('config.commandRules.actions.apply', 'Aplicar comando') }}\n </button>\n </div>\n </div>\n </mat-card-content>\n </mat-card>\n </div>\n </mat-tab>\n <mat-tab [label]=\"configTabLabel('cascades')\">\n <div class=\"tab-content\" data-testid=\"config-tab-panel-cascatas\">\n <mat-card class=\"section-card\">\n <mat-card-content>\n <div class=\"section-header\">\n <div>\n <h3>{{ tx('config.cascades.title', 'Depend\u00EAncias entre campos') }}</h3>\n <p class=\"text-caption\">{{ tx('config.cascades.subtitle', 'Configure cascatas e carregamento entre campos.') }}</p>\n </div>\n </div>\n <praxis-cascade-manager-tab [fields]=\"editedConfig.fieldMetadata || []\"\n (apply)=\"onCascadeApply($event)\"></praxis-cascade-manager-tab>\n </mat-card-content>\n </mat-card>\n </div>\n </mat-tab>\n <mat-tab [label]=\"configTabLabel('messages')\">\n <div class=\"tab-content\" data-testid=\"config-tab-panel-mensagens\">\n <mat-card class=\"section-card\">\n <mat-card-content>\n <div class=\"section-header\">\n <div>\n <h3>{{ tx('config.messages.title', 'Mensagens e feedback') }}</h3>\n <p class=\"text-caption\">{{ tx('config.messages.subtitle', 'Padronize textos de sucesso, erro e confirma\u00E7\u00F5es.') }}</p>\n </div>\n </div>\n <praxis-messages-editor [config]=\"editedConfig\" (configChange)=\"onConfigChange($event)\"></praxis-messages-editor>\n </mat-card-content>\n </mat-card>\n </div>\n </mat-tab>\n <mat-tab [label]=\"configTabLabel('navigation')\">\n <div class=\"tab-content\" data-testid=\"config-tab-panel-navegacao\">\n <mat-card class=\"section-card\">\n <mat-card-content>\n <div class=\"section-header\">\n <div>\n <h3>{{ tx('config.navigation.title', 'Navega\u00E7\u00E3o de retorno') }}</h3>\n <p class=\"text-caption\">{{ tx('config.navigation.subtitle', 'Defina o comportamento do bot\u00E3o Voltar em fluxos CRUD.') }}</p>\n </div>\n </div>\n <div class=\"form-grid\">\n <div class=\"form-row\">\n <mat-form-field appearance=\"fill\" class=\"w-100\">\n <mat-label>{{ tx('config.navigation.returnTo.label', 'Rota de retorno') }}</mat-label>\n <input matInput id=\"returnTo\" [(ngModel)]=\"backConfig!.returnTo\" (ngModelChange)=\"onBackConfigChange()\" [placeholder]=\"tx('config.navigation.returnTo.placeholder', '/funcionarios')\" />\n </mat-form-field>\n </div>\n <div class=\"form-row\">\n <mat-slide-toggle [(ngModel)]=\"backConfig!.confirmOnDirty\" (ngModelChange)=\"onBackConfigChange()\">\n {{ tx('config.navigation.confirmOnDirty.label', 'Confirmar ao sair com altera\u00E7\u00F5es') }}\n </mat-slide-toggle>\n </div>\n <div class=\"block-status\" [class.block-status--implicit]=\"!isBackConfigBlockPersisted()\">\n <strong>{{ tx('config.navigation.backConfig.label', 'Back Config') }}</strong>\n @if (isBackConfigBlockPersisted()) {\n <span>{{ tx('config.navigation.backConfig.persisted', '`contextSnapshot.backConfig` ser\u00E1 persistido no documento can\u00F4nico.') }}</span>\n } @else {\n {{ tx('config.navigation.backConfig.implicit', 'Bloco ausente no documento can\u00F4nico. Os valores exibidos s\u00E3o fallback visual e n\u00E3o ser\u00E3o salvos at\u00E9 voc\u00EA editar.') }}\n }\n </div>\n </div>\n <div class=\"section-help\">\n <span class=\"section-help__label\">{{ tx('config.navigation.note.label', 'Observa\u00E7\u00E3o:') }}</span>\n <button\n praxisIconButton=\"help_outline\"\n size=\"dense\"\n class=\"help-icon-button\"\n type=\"button\"\n [matTooltip]=\"tx('config.navigation.note.tooltip', 'Afeta o fluxo de navega\u00E7\u00E3o do CRUD e pode ser sobreposto por metadados do recurso.')\"\n matTooltipPosition=\"above\"\n >\n </button>\n </div>\n </mat-card-content>\n </mat-card>\n </div>\n </mat-tab>\n <mat-tab [label]=\"configTabLabel('json')\">\n <div class=\"tab-content json-tab-content\" data-testid=\"config-tab-panel-json\">\n <mat-card class=\"section-card section-card--json\">\n <mat-card-content>\n <div class=\"section-header\">\n <div>\n <h3>{{ tx('config.json.title', 'Configura\u00E7\u00E3o JSON') }}</h3>\n <p class=\"text-caption\">{{ tx('config.json.subtitle', 'Edi\u00E7\u00E3o avan\u00E7ada do documento can\u00F4nico de autoria do formul\u00E1rio.') }}</p>\n </div>\n </div>\n <form-json-config-editor [document]=\"jsonDocument\" (documentChange)=\"onJsonConfigChange($event)\"\n (validationChange)=\"onJsonValidationChange($event)\" (editorEvent)=\"onJsonEditorEvent($event)\">\n </form-json-config-editor>\n </mat-card-content>\n </mat-card>\n </div>\n </mat-tab>\n</mat-tab-group>\n", styles: [":host{container:praxis-authoring-editor/inline-size;display:flex;flex-direction:column;height:100%;min-width:0}.mobile-tab-selector{display:none;flex:0 0 auto;padding:8px 16px 0;background:var(--md-sys-color-surface)}.mobile-tab-selector__field{width:100%}.config-tabs{flex:1 1 auto;min-height:0;min-width:0}::ng-deep .mat-mdc-tab-group.config-tabs{display:flex;flex-direction:column}::ng-deep .mat-mdc-tab-group.config-tabs .mat-mdc-tab-body-wrapper{flex:1;min-height:0;min-width:0}::ng-deep .mat-mdc-tab-group.config-tabs .mat-mdc-tab-body-content{height:100%;overflow-y:auto;overflow-x:hidden;display:flex;flex-direction:column;padding:0!important}.tab-content{padding:16px 20px 20px;flex:1;min-width:0;box-sizing:border-box}.json-tab-content{min-width:0;padding:12px 16px 16px}.section-card--json{display:flex;flex:1;min-height:calc(100vh - 180px);border:1px solid var(--md-sys-color-outline-variant);background:var(--md-sys-color-surface-container-low)}.section-card--json>mat-card-content{display:flex;flex:1;min-width:0;min-height:0;flex-direction:column}.section-card--json form-json-config-editor{display:block;flex:1;min-width:0;min-height:0}.form-row{display:block;margin-bottom:12px}.form-grid{display:grid;gap:12px}.section-help{display:inline-flex;align-items:center;gap:8px;color:var(--md-sys-color-on-surface-variant);font-size:12px}.section-help__label{font-weight:500}.grid-2-cols{display:grid;grid-template-columns:repeat(auto-fit,minmax(260px,1fr));gap:16px}.grid-2-cols--compact{gap:12px}.w-100{width:100%}.visual-builder-content{padding:0!important;height:100%;min-width:0;overflow-y:auto;overflow-x:hidden;display:flex;flex-direction:column;gap:16px}.visual-builder-content>praxis-visual-builder{flex:0 0 auto;min-width:0;min-height:clamp(360px,48vh,560px)}.visual-builder-content>praxis-rule-properties-panel{flex:0 0 auto;display:block;min-width:0;padding:0 16px 24px;box-sizing:border-box}.rules-diagnostics{flex:0 0 auto;display:grid;gap:10px;padding:12px 16px;border-bottom:1px solid var(--md-sys-color-outline-variant);background:var(--md-sys-color-surface-container-low)}.rules-diagnostics--empty{color:var(--md-sys-color-on-surface-variant);font-size:12px;line-height:1.45}.rules-diagnostics__summary,.rules-diagnostics__list{display:flex;flex-wrap:wrap;gap:8px}.rules-diagnostics__pill{display:inline-flex;align-items:center;min-height:24px;padding:3px 9px;border-radius:999px;background:var(--md-sys-color-surface-container-high);color:var(--md-sys-color-on-surface);font-size:12px;font-weight:600}.rules-diagnostics__pill--warn{background:color-mix(in srgb,var(--md-sys-color-tertiary-container) 72%,transparent);color:var(--md-sys-color-on-tertiary-container)}.rules-diagnostics__pill--error{background:var(--md-sys-color-error-container);color:var(--md-sys-color-on-error-container)}.rules-diagnostics__item{display:flex;align-items:flex-start;justify-content:space-between;gap:14px;min-width:min(100%,280px);padding:8px 10px;border:1px solid var(--md-sys-color-outline-variant);border-radius:8px;background:var(--md-sys-color-surface-container)}.rules-diagnostics__item>div{display:grid;gap:2px;min-width:0}.rules-diagnostics__item strong{color:var(--md-sys-color-on-surface);font-size:12px;line-height:1.25;overflow:hidden;text-overflow:ellipsis;white-space:nowrap}.rules-diagnostics__item span{color:var(--md-sys-color-on-surface-variant);font-size:11px}.rules-diagnostics__actions{flex:0 0 auto;display:flex;align-items:center;gap:8px}.rules-diagnostics__details{display:grid;gap:2px;margin:4px 0 0;padding-left:16px;color:var(--md-sys-color-on-surface-variant);font-size:11px;line-height:1.35}.rules-diagnostics__details li{overflow-wrap:anywhere}.rules-diagnostics__item--warn{border-color:color-mix(in srgb,var(--md-sys-color-tertiary) 52%,var(--md-sys-color-outline-variant))}.rules-diagnostics__item--error{border-color:var(--md-sys-color-error)}.rules-diagnostics__status{font-weight:600;margin-top:1px}.rules-diagnostics__action{min-width:0;height:28px;padding:0 10px;border-radius:999px;font-size:12px;line-height:1}.rules-diagnostics__action mat-icon{width:16px;height:16px;margin:0 4px 0 0;font-size:16px}.json-field{width:100%}.presentation-layout{display:grid;grid-template-columns:minmax(0,1fr);gap:20px;align-items:start}.presentation-controls{display:grid;grid-template-columns:repeat(auto-fit,minmax(min(100%,240px),1fr));gap:14px 18px}.control{display:flex;flex-direction:column}.control-span{grid-column:1/-1}.block-status{grid-column:1/-1;display:flex;gap:8px;align-items:flex-start;padding:10px 12px;border-radius:10px;background:color-mix(in srgb,var(--md-sys-color-primary-container) 35%,transparent);color:var(--md-sys-color-on-surface);font-size:12px;line-height:1.45}.block-status strong{min-width:112px;font-size:11px;letter-spacing:.04em;text-transform:uppercase;color:var(--md-sys-color-on-surface-variant)}.block-status--implicit{background:color-mix(in srgb,var(--md-sys-color-surface-variant) 42%,transparent);border:1px dashed var(--md-sys-color-outline)}.block-status--readonly{margin-bottom:12px}.block-status code{font-family:var(--md-ref-typeface-mono, \"Courier New\", monospace);font-size:11px}.control__label{font-size:12px;color:var(--md-sys-color-on-surface-variant);margin-bottom:6px}.toggle-group{max-width:100%;flex-wrap:wrap}.control--inline{grid-column:1/-1;display:flex;gap:16px;align-items:center}.presentation-preview{min-width:0;order:-1}.preview-card{border:1px solid var(--md-sys-color-outline);border-radius:12px;padding:14px;background:var(--md-sys-color-surface-container)}.preview-row{display:flex;gap:8px;padding:6px 0;border-bottom:1px dashed var(--md-sys-color-outline-variant)}.preview-row:last-child{border-bottom:none}.sr-only{position:absolute;width:1px;height:1px;padding:0;margin:-1px;overflow:hidden;clip:rect(0,0,0,0);white-space:nowrap;border:0}.presentation-preview .praxis-presentation__label{color:var(--md-sys-color-on-surface-variant);font-size:var(--pfx-pres-label-size, 12px)}.presentation-preview .praxis-presentation__value{min-width:0;overflow-wrap:anywhere;font-size:var(--pfx-pres-value-size, 16px);color:var(--md-sys-color-on-surface)}.presentation-preview .presentation-mode.pres-density-cozy .preview-row{padding:6px 0}.presentation-preview .presentation-mode.pres-density-compact .preview-row,.presentation-preview .presentation-mode.pres-compact .preview-row{padding:2px 0}.presentation-preview .presentation-mode.pres-label-left .preview-row{display:grid;grid-template-columns:var(--pfx-pres-label-width, 140px) 1fr;align-items:baseline;column-gap:10px}.presentation-preview .presentation-mode.pres-label-left .praxis-presentation__label{margin:0;text-align:var(--pfx-pres-label-align, start)}.presentation-preview .presentation-mode .praxis-presentation__value{text-align:var(--pfx-pres-value-align, start)}.presentation-preview h4{margin:0 0 8px;color:var(--md-sys-color-on-surface);font-size:1rem}.section-card{border:1px solid var(--md-sys-color-outline-variant);background:var(--md-sys-color-surface-container);box-shadow:var(--md-sys-elevation-level1, none)}.section-header{display:flex;align-items:flex-start;justify-content:space-between;gap:12px;margin-bottom:12px}.tab-content--dense{padding:12px 16px 16px}.tab-content--dense .section-header,.tab-content--dense .form-row{margin-bottom:8px}.section-header h3{margin:0;font-size:1.05rem;color:var(--md-sys-color-on-surface)}.text-caption{margin:6px 0 0;font-size:.9rem;color:var(--md-sys-color-on-surface-variant)}.section-header--compact{margin-bottom:8px}.section-body{display:block}.section-body--flex{flex:1;min-height:0;display:flex;flex-direction:column}.builder-header{padding:12px 16px;border-bottom:1px solid var(--md-sys-color-outline-variant);background:var(--md-sys-color-surface)}.builder-header h3{margin:0;font-size:1rem;color:var(--md-sys-color-on-surface)}.hint{margin:8px 0 0;padding:10px 12px;border-radius:10px;border:1px dashed var(--md-sys-color-outline-variant);background:var(--md-sys-color-surface-container);color:var(--md-sys-color-on-surface-variant)}.meta-card{display:grid;gap:6px;padding:10px 12px;border-radius:10px;border:1px solid var(--md-sys-color-outline-variant);background:var(--md-sys-color-surface);color:var(--md-sys-color-on-surface)}.meta-row{display:flex;align-items:center;justify-content:space-between;gap:12px;font-size:.9rem;color:var(--md-sys-color-on-surface-variant)}.meta-row strong{color:var(--md-sys-color-on-surface);font-weight:600}.runtime-contract-grid{display:grid;grid-template-columns:repeat(auto-fit,minmax(220px,1fr));gap:12px}.runtime-contract-field{display:grid;gap:6px;padding:12px;border-radius:10px;border:1px solid var(--md-sys-color-outline-variant);background:var(--md-sys-color-surface)}.runtime-contract-label{font-size:12px;color:var(--md-sys-color-on-surface-variant)}.runtime-contract-code{display:block;font-family:var(--md-ref-typeface-mono, \"Courier New\", monospace);font-size:12px;line-height:1.45;color:var(--md-sys-color-on-surface);word-break:break-word;white-space:normal}.command-rules-card{margin:16px;min-width:0;border:1px solid var(--md-sys-color-outline-variant);background:var(--md-sys-color-surface-container)}.command-rules-grid{display:grid;grid-template-columns:repeat(auto-fit,minmax(min(260px,100%),1fr));gap:12px;align-items:start;min-width:0}.command-rules-toolbar,.command-rules-options,.command-rules-actions{grid-column:1/-1;display:flex;align-items:center;gap:12px;flex-wrap:wrap}.command-rules-select{min-width:min(320px,100%)}.command-rules-full{grid-column:1/-1}.command-rule-condition-builder{min-height:420px;overflow:hidden;border:1px solid var(--md-sys-color-outline-variant);border-radius:8px;background:var(--md-sys-color-surface-container-low)}.command-rules-payload-fields{display:grid;grid-template-columns:repeat(auto-fit,minmax(min(220px,100%),1fr));gap:12px;min-width:0;padding:12px;border:1px dashed var(--md-sys-color-outline-variant);border-radius:8px;background:var(--md-sys-color-surface-container-low)}.command-rules-section-title{grid-column:1/-1;font-size:12px;font-weight:600;color:var(--md-sys-color-on-surface-variant);text-transform:uppercase}.command-rules-surface-editor{grid-column:1/-1}.command-rule-preview{display:grid;gap:8px;padding:12px;border:1px solid var(--md-sys-color-outline-variant);border-radius:8px;background:var(--md-sys-color-surface)}.command-rule-preview--invalid{border-color:var(--md-sys-color-error)}.command-rule-preview__row{display:grid;grid-template-columns:minmax(96px,.35fr) minmax(0,1fr);gap:8px;align-items:start;min-width:0}.command-rule-preview__row span{color:var(--md-sys-color-on-surface-variant);font-size:12px;font-weight:600}.command-rule-preview__row strong,.command-rule-preview__row code{min-width:0;overflow-wrap:anywhere}.command-rule-preview__diagnostics{display:flex;gap:8px;align-items:flex-start;color:var(--md-sys-color-on-surface-variant)}@container praxis-authoring-editor (max-width: 768px){.mobile-tab-selector{display:block}::ng-deep .mat-mdc-tab-group.config-tabs>.mat-mdc-tab-header{display:none}.tab-content{padding:12px}.json-tab-content{padding:8px}.section-card--json{min-height:auto}}.form-modes{display:flex;flex-direction:column;align-items:flex-start;gap:16px}.form-modes mat-button-toggle-group{max-width:100%;flex-wrap:wrap}.display-result{margin:0;padding-block:12px;color:var(--md-sys-color-on-surface);font:var(--md-sys-typescale-body-medium)}.presentation-preview .presentation-mode.pres-label-above .preview-row{flex-direction:column;gap:4px}.presentation-controls,.control{min-width:0}.block-status{flex-wrap:wrap}:host{container-type:inline-size}@container (min-width: 900px){.presentation-layout{grid-template-columns:minmax(0,1fr) minmax(280px,.8fr)}.presentation-preview{order:1;position:sticky;top:16px}}.empty-state-fields{display:grid;align-items:start;grid-template-columns:repeat(auto-fit,minmax(min(100%,240px),1fr));gap:var(--p-space-3, 12px);margin-block-start:var(--p-space-4, 16px)}.empty-state-appearance summary{cursor:pointer;padding-block:var(--p-space-3, 12px);color:var(--md-sys-color-on-surface)}.empty-state-content{grid-template-columns:repeat(auto-fit,minmax(min(100%,320px),1fr))}.empty-state-description{grid-column:1/-1}.empty-state-content mat-form-field{min-width:0}.empty-state-icon-actions{display:inline-flex;align-items:center}\n"], dependencies: [{ kind: "ngmodule", type: CommonModule }, { kind: "directive", type: i1$2.NgClass, selector: "[ngClass]", inputs: ["class", "ngClass"] }, { kind: "directive", type: i1$2.NgIf, selector: "[ngIf]", inputs: ["ngIf", "ngIfThen", "ngIfElse"] }, { kind: "ngmodule", type: FormsModule }, { kind: "directive", type: i1$3.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: i1$3.NumberValueAccessor, selector: "input[type=number][formControlName],input[type=number][formControl],input[type=number][ngModel]" }, { kind: "directive", type: i1$3.NgControlStatus, selector: "[formControlName],[ngModel],[formControl]" }, { kind: "directive", type: i1$3.RequiredValidator, selector: ":not([type=checkbox])[required][formControlName],:not([type=checkbox])[required][formControl],:not([type=checkbox])[required][ngModel]", inputs: ["required"] }, { kind: "directive", type: i1$3.MinValidator, selector: "input[type=number][min][formControlName],input[type=number][min][formControl],input[type=number][min][ngModel]", inputs: ["min"] }, { kind: "directive", type: i1$3.NgModel, selector: "[ngModel]:not([formControlName]):not([formControl])", inputs: ["name", "disabled", "ngModel", "ngModelOptions"], outputs: ["ngModelChange"], exportAs: ["ngModel"] }, { kind: "ngmodule", type: MatTabsModule }, { kind: "component", type: i6$2.MatTab, selector: "mat-tab", inputs: ["disabled", "label", "aria-label", "aria-labelledby", "labelClass", "bodyClass", "id"], exportAs: ["matTab"] }, { kind: "component", type: i6$2.MatTabGroup, selector: "mat-tab-group", inputs: ["color", "fitInkBarToContent", "mat-stretch-tabs", "mat-align-tabs", "dynamicHeight", "selectedIndex", "headerPosition", "animationDuration", "contentTabIndex", "disablePagination", "disableRipple", "preserveContent", "backgroundColor", "aria-label", "aria-labelledby"], outputs: ["selectedIndexChange", "focusChange", "animationDone", "selectedTabChange"], exportAs: ["matTabGroup"] }, { kind: "ngmodule", type: MatIconModule }, { kind: "component", type: i4.MatIcon, selector: "mat-icon", inputs: ["color", "inline", "svgIcon", "fontSet", "fontIcon"], exportAs: ["matIcon"] }, { kind: "ngmodule", type: MatCardModule }, { kind: "component", type: i7$1.MatCard, selector: "mat-card", inputs: ["appearance"], exportAs: ["matCard"] }, { kind: "directive", type: i7$1.MatCardContent, selector: "mat-card-content" }, { kind: "directive", type: i7$1.MatCardSubtitle, selector: "mat-card-subtitle, [mat-card-subtitle], [matCardSubtitle]" }, { kind: "directive", type: i7$1.MatCardTitle, selector: "mat-card-title, [mat-card-title], [matCardTitle]" }, { kind: "ngmodule", type: MatButtonModule }, { kind: "component", type: i3.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: i3.MatIconButton, selector: "button[mat-icon-button], a[mat-icon-button], button[matIconButton], a[matIconButton]", exportAs: ["matButton", "matAnchor"] }, { kind: "ngmodule", type: MatFormFieldModule }, { kind: "component", type: i4$1.MatFormField, selector: "mat-form-field", inputs: ["hideRequiredMarker", "color", "floatLabel", "appearance", "subscriptSizing", "hintLabel"], exportAs: ["matFormField"] }, { kind: "directive", type: i4$1.MatLabel, selector: "mat-label" }, { kind: "directive", type: i4$1.MatHint, selector: "mat-hint", inputs: ["align", "id"] }, { kind: "directive", type: i4$1.MatError, selector: "mat-error, [matError]", inputs: ["id"] }, { kind: "directive", type: i4$1.MatPrefix, selector: "[matPrefix], [matIconPrefix], [matTextPrefix]", inputs: ["matTextPrefix"] }, { kind: "directive", type: i4$1.MatSuffix, selector: "[matSuffix], [matIconSuffix], [matTextSuffix]", inputs: ["matTextSuffix"] }, { kind: "ngmodule", type: MatSelectModule }, { kind: "component", type: i5$1.MatSelect, selector: "mat-select", inputs: ["aria-describedby", "panelClass", "disabled", "disableRipple", "tabIndex", "hideSingleSelectionIndicator", "placeholder", "required", "multiple", "disableOptionCentering", "compareWith", "value", "aria-label", "aria-labelledby", "errorStateMatcher", "typeaheadDebounceInterval", "sortComparator", "id", "panelWidth", "canSelectNullableOptions"], outputs: ["openedChange", "opened", "closed", "selectionChange", "valueChange"], exportAs: ["matSelect"] }, { kind: "component", type: i5$1.MatOption, selector: "mat-option", inputs: ["value", "id", "disabled"], outputs: ["onSelectionChange"], exportAs: ["matOption"] }, { kind: "ngmodule", type: MatInputModule }, { kind: "directive", type: i4$2.MatInput, selector: "input[matInput], textarea[matInput], select[matNativeControl], input[matNativeControl], textarea[matNativeControl]", inputs: ["disabled", "id", "placeholder", "name", "required", "type", "errorStateMatcher", "aria-describedby", "value", "readonly", "disabledInteractive"], exportAs: ["matInput"] }, { kind: "ngmodule", type: MatCheckboxModule }, { kind: "component", type: i12.MatCheckbox, selector: "mat-checkbox", inputs: ["aria-label", "aria-labelledby", "aria-describedby", "aria-expanded", "aria-controls", "aria-owns", "id", "required", "labelPosition", "name", "value", "disableRipple", "tabIndex", "color", "disabledInteractive", "checked", "disabled", "indeterminate"], outputs: ["change", "indeterminateChange"], exportAs: ["matCheckbox"] }, { kind: "ngmodule", type: MatSlideToggleModule }, { kind: "component", type: i5$2.MatSlideToggle, selector: "mat-slide-toggle", inputs: ["name", "id", "labelPosition", "aria-label", "aria-labelledby", "aria-describedby", "required", "color", "disabled", "disableRipple", "tabIndex", "checked", "hideIcon", "disabledInteractive"], outputs: ["change", "toggleChange"], exportAs: ["matSlideToggle"] }, { kind: "ngmodule", type: MatButtonToggleModule }, { kind: "directive", type: i7$2.MatButtonToggleGroup, selector: "mat-button-toggle-group", inputs: ["appearance", "name", "vertical", "value", "multiple", "disabled", "disabledInteractive", "hideSingleSelectionIndicator", "hideMultipleSelectionIndicator"], outputs: ["valueChange", "change"], exportAs: ["matButtonToggleGroup"] }, { kind: "component", type: i7$2.MatButtonToggle, selector: "mat-button-toggle", inputs: ["aria-label", "aria-labelledby", "id", "name", "value", "tabIndex", "disableRipple", "appearance", "checked", "disabled", "disabledInteractive"], outputs: ["change"], exportAs: ["matButtonToggle"] }, { kind: "ngmodule", type: MatTooltipModule }, { kind: "directive", type: i5.MatTooltip, selector: "[matTooltip]", inputs: ["matTooltipPosition", "matTooltipPositionAtOrigin", "matTooltipDisabled", "matTooltipShowDelay", "matTooltipHideDelay", "matTooltipTouchGestures", "matTooltip", "matTooltipClass"], exportAs: ["matTooltip"] }, { kind: "directive", type: PraxisIconDirective, selector: "mat-icon[praxisIcon]", inputs: ["praxisIcon"] }, { kind: "component", type: PraxisIconButtonComponent, selector: "button[praxisIconButton]", inputs: ["praxisIconButton", "size", "appearance", "presentation", "pressed", "busy"] }, { kind: "component", type: JsonConfigEditorComponent, selector: "form-json-config-editor", inputs: ["config", "document"], outputs: ["configChange", "documentChange", "validationChange", "editorEvent"] }, { kind: "component", type: LayoutEditorComponent, selector: "praxis-layout-editor", inputs: ["config"], outputs: ["configChange", "select"] }, { kind: "component", type: BehaviorEditorComponent, selector: "praxis-behavior-editor", inputs: ["config"], outputs: ["configChange"] }, { kind: "component", type: ActionsEditorComponent$1, selector: "praxis-actions-editor", inputs: ["config"], outputs: ["configChange", "validationChange"] }, { kind: "component", type: MessagesEditorComponent, selector: "praxis-messages-editor", inputs: ["config"], outputs: ["configChange"] }, { kind: "component", type: HooksEditorComponent, selector: "praxis-hooks-editor", inputs: ["config"], outputs: ["configChange"] }, { kind: "component", type: RulePropertiesPanelComponent, selector: "praxis-rule-properties-panel", inputs: ["rules", "visualBlockNodes"], outputs: ["rulesChange"] }, { kind: "component", type: PraxisVisualBuilder, selector: "praxis-visual-builder", inputs: ["mode", "config", "initialRules", "initialCondition"], outputs: ["rulesChanged", "conditionChanged", "exportRequested", "importRequested"] }, { kind: "component", type: CascadeManagerTabComponent, selector: "praxis-cascade-manager-tab", inputs: ["fields", "connections"], outputs: ["apply", "cancel"] }, { kind: "component", type: SurfaceOpenActionEditorComponent, selector: "praxis-surface-open-action-editor", inputs: ["value", "hostKind"], outputs: ["valueChange", "validationChange"] }, { kind: "pipe", type: i1$2.JsonPipe, name: "json" }] });
|
|
33725
|
+
static ɵcmp = i0.ɵɵngDeclareComponent({ minVersion: "17.0.0", version: "21.2.14", type: PraxisDynamicFormConfigEditor, isStandalone: true, selector: "praxis-dynamic-form-config-editor", providers: [FormConfigService, providePraxisI18nConfig(PRAXIS_DYNAMIC_FORM_I18N_CONFIG)], viewQueries: [{ propertyName: "jsonEditor", first: true, predicate: JsonConfigEditorComponent, descendants: true }, { propertyName: "cascadeManager", first: true, predicate: CascadeManagerTabComponent, descendants: true }], ngImport: i0, template: "<div class=\"mobile-tab-selector\">\n <mat-form-field appearance=\"outline\" class=\"mobile-tab-selector__field\">\n <mat-label>{{ tx('config.tabs.mobileLabel', 'Se\u00E7\u00E3o do editor') }}</mat-label>\n <mat-select [(ngModel)]=\"selectedConfigTabIndex\" data-testid=\"dynamic-form-config-editor-mobile-tabs\">\n @for (tab of configTabOptions; track tab.key) {\n <mat-option [value]=\"tab.index\">{{ tab.label }}</mat-option>\n }\n </mat-select>\n </mat-form-field>\n</div>\n\n<mat-tab-group [preserveContent]=\"true\" class=\"config-tabs\" data-testid=\"dynamic-form-config-editor-tabs\" [(selectedIndex)]=\"selectedConfigTabIndex\">\n <mat-tab [label]=\"configTabLabel('general')\">\n <div class=\"tab-content\" data-testid=\"config-tab-panel-geral\">\n <mat-card class=\"section-card\">\n <mat-card-content>\n <div class=\"section-header\">\n <div>\n <h3>{{ tx('config.general.title', 'Dados do formul\u00E1rio') }}</h3>\n <p class=\"text-caption\">{{ tx('config.general.subtitle', 'Defina o modo de dados e o contexto de edi\u00E7\u00E3o.') }}</p>\n </div>\n </div>\n <div class=\"form-modes\">\n <div class=\"control\">\n <label class=\"control__label\">{{ tx('config.general.inputMode.label') }}</label>\n <mat-button-toggle-group [ngModel]=\"inputMode\" (ngModelChange)=\"inputMode = $event; onInputModeChange()\" [attr.aria-label]=\"tx('config.general.inputMode.label')\">\n <mat-button-toggle value=\"create\">{{ tx('config.general.inputMode.create') }}</mat-button-toggle>\n <mat-button-toggle value=\"edit\">{{ tx('config.general.inputMode.edit') }}</mat-button-toggle>\n <mat-button-toggle value=\"view\">{{ tx('config.general.inputMode.view') }}</mat-button-toggle>\n </mat-button-toggle-group>\n </div>\n <div class=\"control\">\n <label class=\"control__label\">{{ tx('config.general.layoutScope.label', 'Escopo de persist\u00EAncia do layout') }}</label>\n <mat-button-toggle-group\n data-testid=\"dynamic-form-layout-scope-toggle\"\n [ngModel]=\"inputLayoutScope\"\n (ngModelChange)=\"onLayoutScopeChange($event)\"\n [attr.aria-label]=\"tx('config.general.layoutScope.label', 'Escopo de persist\u00EAncia do layout')\">\n <mat-button-toggle value=\"shared\" data-testid=\"dynamic-form-layout-scope-shared\">\n {{ tx('config.general.layoutScope.shared', 'Todos os modos (Criar / Editar / Visualizar)') }}\n </mat-button-toggle>\n <mat-button-toggle value=\"mode-only\" data-testid=\"dynamic-form-layout-scope-mode-only\">\n {{ tx('config.general.layoutScope.modeOnly', 'Somente este modo ({{mode}})', { mode: tx('config.general.inputMode.' + inputMode, inputMode) }) }}\n </mat-button-toggle>\n </mat-button-toggle-group>\n <p class=\"control__hint\" data-testid=\"dynamic-form-layout-scope-hint\" role=\"status\">\n {{ inputLayoutScope === 'mode-only'\n ? tx('config.general.layoutScope.modeOnlyHint', 'Ao salvar, aplica este layout exclusivamente ao modo atual, sem alterar os demais modos.')\n : tx('config.general.layoutScope.sharedHint', 'Ao salvar, replica se\u00E7\u00F5es e grade nos demais modos que ainda compartilham layout.') }}\n </p>\n </div>\n @if (supportsPresentationSettings) {\n <div class=\"control\">\n <label class=\"control__label\">{{ tx('config.general.displayMode.label') }}</label>\n <mat-button-toggle-group [ngModel]=\"displayMode\" (ngModelChange)=\"onDisplayModeChange($event)\" [attr.aria-label]=\"tx('config.general.displayMode.label')\">\n <mat-button-toggle value=\"automatic\">{{ tx('config.general.displayMode.automatic') }}</mat-button-toggle>\n <mat-button-toggle value=\"fields\">{{ tx('config.general.displayMode.fields') }}</mat-button-toggle>\n <mat-button-toggle value=\"presentation\">{{ tx('config.general.displayMode.presentation') }}</mat-button-toggle>\n </mat-button-toggle-group>\n </div>\n <p class=\"display-result\" role=\"status\">{{ tx(displayModeHint) }}</p>\n @if (inputMode !== 'view' && inputMode !== 'presentation' && inputMode !== 'dossier' && inputPresentationMode === true) {\n <button mat-stroked-button type=\"button\" (click)=\"useViewMode()\">{{ tx('config.general.displayMode.useView') }}</button>\n }\n <button mat-button type=\"button\" (click)=\"openPresentationStyle()\">{{ tx('config.general.displayMode.openStyle') }}</button>\n }\n </div>\n </mat-card-content>\n </mat-card>\n\n @if (supportsPresentationSettings) {\n <mat-card class=\"section-card\" data-testid=\"form-empty-state-settings\">\n <mat-card-content>\n <h3>{{ tx('config.emptyState.heading') }}</h3>\n <p class=\"text-caption\">{{ tx('config.emptyState.help') }}</p>\n <mat-slide-toggle [ngModel]=\"!!inputEmptyState\" (ngModelChange)=\"setEmptyStateEnabled($event)\">{{ tx('config.emptyState.enabled') }}</mat-slide-toggle>\n @if (inputMode !== 'view' && inputMode !== 'presentation' && inputMode !== 'dossier') { <p class=\"text-caption\">{{ tx('config.emptyState.viewOnly') }}</p> }\n @if (inputEmptyState; as empty) {\n <div class=\"empty-state-fields empty-state-content\">\n <mat-form-field appearance=\"outline\"><mat-label>{{ tx('config.emptyState.title') }}</mat-label><input matInput required [(ngModel)]=\"empty.title\" (ngModelChange)=\"onEmptyStateChange()\" /><mat-hint *ngIf=\"!empty.title?.trim()\">{{ tx('config.emptyState.titleRequired') }}</mat-hint></mat-form-field>\n <mat-form-field appearance=\"outline\">\n <mat-label>{{ tx('config.emptyState.icon') }}</mat-label>\n @if (empty.icon) { <mat-icon matPrefix [praxisIcon]=\"empty.icon\" aria-hidden=\"true\"></mat-icon> }\n <input matInput [(ngModel)]=\"empty.icon\" (ngModelChange)=\"onEmptyStateChange()\" />\n <span matSuffix class=\"empty-state-icon-actions\">\n <button mat-icon-button type=\"button\" [attr.aria-label]=\"tx('config.emptyState.pickIcon')\" (click)=\"pickEmptyStateIcon()\"><mat-icon aria-hidden=\"true\">search</mat-icon></button>\n @if (empty.icon) { <button mat-icon-button type=\"button\" [attr.aria-label]=\"tx('config.emptyState.clearIcon')\" (click)=\"empty.icon = ''; onEmptyStateChange()\"><mat-icon aria-hidden=\"true\">close</mat-icon></button> }\n </span>\n </mat-form-field>\n <mat-form-field appearance=\"outline\" class=\"empty-state-description\"><mat-label>{{ tx('config.emptyState.description') }}</mat-label><textarea matInput rows=\"2\" [(ngModel)]=\"empty.description\" (ngModelChange)=\"onEmptyStateChange()\"></textarea></mat-form-field>\n </div>\n <details class=\"empty-state-appearance\"><summary>{{ tx('config.emptyState.appearance') }}</summary><div class=\"empty-state-fields\">\n <mat-form-field appearance=\"outline\"><mat-label>{{ tx('config.emptyState.tone') }}</mat-label><mat-select [(ngModel)]=\"empty.tone\" (ngModelChange)=\"onEmptyStateChange()\"><mat-option [value]=\"undefined\">{{ tx('config.emptyState.inherit') }}</mat-option>@for (value of emptyStateOptions.tone; track value) { <mat-option [value]=\"value\">{{ tx('config.emptyState.option.' + value) }}</mat-option> }</mat-select></mat-form-field>\n <mat-form-field appearance=\"outline\"><mat-label>{{ tx('config.emptyState.variant') }}</mat-label><mat-select [(ngModel)]=\"empty.variant\" (ngModelChange)=\"onEmptyStateChange()\"><mat-option [value]=\"undefined\">{{ tx('config.emptyState.inherit') }}</mat-option>@for (value of emptyStateOptions.variant; track value) { <mat-option [value]=\"value\">{{ tx('config.emptyState.option.' + value) }}</mat-option> }</mat-select></mat-form-field>\n <mat-form-field appearance=\"outline\"><mat-label>{{ tx('config.emptyState.alignment') }}</mat-label><mat-select [(ngModel)]=\"empty.alignment\" (ngModelChange)=\"onEmptyStateChange()\"><mat-option [value]=\"undefined\">{{ tx('config.emptyState.inherit') }}</mat-option>@for (value of emptyStateOptions.alignment; track value) { <mat-option [value]=\"value\">{{ tx('config.emptyState.option.' + value) }}</mat-option> }</mat-select></mat-form-field>\n <mat-form-field appearance=\"outline\"><mat-label>{{ tx('config.emptyState.density') }}</mat-label><mat-select [(ngModel)]=\"empty.density\" (ngModelChange)=\"onEmptyStateChange()\"><mat-option [value]=\"undefined\">{{ tx('config.emptyState.inherit') }}</mat-option>@for (value of emptyStateOptions.density; track value) { <mat-option [value]=\"value\">{{ tx('config.emptyState.option.' + value) }}</mat-option> }</mat-select></mat-form-field>\n <mat-form-field appearance=\"outline\"><mat-label>{{ tx('config.emptyState.iconContainer') }}</mat-label><mat-select [(ngModel)]=\"empty.iconContainer\" (ngModelChange)=\"onEmptyStateChange()\"><mat-option [value]=\"undefined\">{{ tx('config.emptyState.inherit') }}</mat-option>@for (value of emptyStateOptions.iconContainer; track value) { <mat-option [value]=\"value\">{{ tx('config.emptyState.option.' + value) }}</mat-option> }</mat-select></mat-form-field>\n </div></details>\n }\n </mat-card-content>\n </mat-card>\n }\n\n @if (hasResolvedRuntimeContract()) {\n <mat-card\n class=\"section-card\"\n data-testid=\"config-tab-runtime-contract\"\n >\n <mat-card-content>\n <div class=\"section-header\">\n <div>\n <h3>{{ tx('config.general.runtimeContract.title', 'Contrato Runtime Resolvido') }}</h3>\n <p class=\"text-caption\">\n {{ tx('config.general.runtimeContract.subtitle', 'Visualiza\u00E7\u00E3o somente leitura do contrato backend resolvido pelo host atual.') }}\n </p>\n </div>\n </div>\n <div class=\"block-status block-status--readonly\">\n <strong>{{ tx('config.general.runtimeContract.runtimeLabel', 'Runtime') }}</strong>\n <span>\n {{ tx('config.general.runtimeContract.readonly', 'Esses valores v\u00EAm do host/runtime atual e n\u00E3o s\u00E3o persistidos em `bindings` nem em `contextSnapshot`.') }}\n </span>\n </div>\n <div class=\"runtime-contract-grid\">\n <div class=\"runtime-contract-field\">\n <span class=\"runtime-contract-label\">{{ tx('config.general.runtimeContract.schemaUrl', 'Schema URL') }}</span>\n <code class=\"runtime-contract-code\">{{ runtimeContract?.schemaUrl || '\u2014' }}</code>\n </div>\n <div class=\"runtime-contract-field\">\n <span class=\"runtime-contract-label\">{{ tx('config.general.runtimeContract.schemaSource', 'Origem do schema') }}</span>\n <strong>{{ describeRuntimeSource(runtimeContract?.schemaSource) }}</strong>\n </div>\n <div class=\"runtime-contract-field\">\n <span class=\"runtime-contract-label\">{{ tx('config.general.runtimeContract.submitMethod', 'Submit method') }}</span>\n <strong>{{ runtimeContract?.submitMethod || '\u2014' }}</strong>\n </div>\n <div class=\"runtime-contract-field\">\n <span class=\"runtime-contract-label\">{{ tx('config.general.runtimeContract.submitUrl', 'Submit URL') }}</span>\n <code class=\"runtime-contract-code\">{{ runtimeContract?.submitUrl || '\u2014' }}</code>\n </div>\n <div class=\"runtime-contract-field\">\n <span class=\"runtime-contract-label\">{{ tx('config.general.runtimeContract.submitSource', 'Origem do submit') }}</span>\n <strong>{{ describeRuntimeSource(runtimeContract?.submitSource) }}</strong>\n </div>\n </div>\n </mat-card-content>\n </mat-card>\n }\n </div>\n </mat-tab>\n <mat-tab [label]=\"configTabLabel('schema')\">\n <div class=\"tab-content\" data-testid=\"config-tab-panel-schema\">\n <mat-card class=\"section-card\">\n <mat-card-content>\n <div class=\"section-header\">\n <div>\n <h3>{{ tx('config.schema.title', 'Valida\u00E7\u00E3o de schema') }}</h3>\n <p class=\"text-caption\">{{ tx('config.schema.subtitle', 'Controle avisos quando o schema do servidor mudar.') }}</p>\n </div>\n </div>\n <div class=\"form-grid\">\n <div class=\"form-row\">\n <mat-form-field appearance=\"outline\" class=\"w-100\">\n <mat-label>{{ tx('config.schema.notify.label', 'Notificar quando desatualizado') }}</mat-label>\n <mat-select [(ngModel)]=\"schemaPrefs.notifyIfOutdated\" (ngModelChange)=\"onSchemaPrefsChange('schema-prefs-notify')\">\n <mat-option value=\"both\">{{ tx('config.schema.notify.both', 'Banner + Snackbar') }}</mat-option>\n <mat-option value=\"inline\">{{ tx('config.schema.notify.inline', 'Somente Banner') }}</mat-option>\n <mat-option value=\"snackbar\">{{ tx('config.schema.notify.snackbar', 'Somente Snackbar') }}</mat-option>\n <mat-option value=\"none\">{{ tx('config.schema.notify.none', 'Nenhum') }}</mat-option>\n </mat-select>\n </mat-form-field>\n </div>\n <div class=\"form-row\">\n <mat-form-field appearance=\"outline\" class=\"w-100\">\n <mat-label>{{ tx('config.schema.snooze.label', 'Intervalo de sil\u00EAncio (ms)') }}</mat-label>\n <input matInput type=\"number\" [(ngModel)]=\"schemaPrefs.snoozeMs\" (ngModelChange)=\"onSchemaPrefsChange('schema-prefs-snooze')\" />\n </mat-form-field>\n </div>\n <div class=\"form-row\">\n <mat-slide-toggle [(ngModel)]=\"schemaPrefs.autoOpenSettingsOnOutdated\" (ngModelChange)=\"onSchemaPrefsChange('schema-prefs-auto-open')\">\n {{ tx('config.schema.autoOpenSettings', 'Abrir configura\u00E7\u00F5es automaticamente') }}\n </mat-slide-toggle>\n </div>\n @if (serverMeta) {\n <div class=\"form-row\">\n <div class=\"meta-card\">\n <div class=\"meta-row\">\n <span>{{ tx('config.schema.meta.serverHash', 'Server hash') }}</span>\n <strong>{{ serverMeta.serverHash || '\u2014' }}</strong>\n </div>\n <div class=\"meta-row\">\n <span>{{ tx('config.schema.meta.lastVerifiedAt', '\u00DAltima verifica\u00E7\u00E3o') }}</span>\n <strong>{{ serverMeta.lastVerifiedAt || '\u2014' }}</strong>\n </div>\n </div>\n </div>\n }\n <div class=\"block-status\" [class.block-status--implicit]=\"!isSchemaPrefsBlockPersisted()\">\n <strong>{{ tx('config.schema.prefs.label', 'Schema Prefs') }}</strong>\n @if (isSchemaPrefsBlockPersisted()) {\n <span>{{ tx('config.schema.prefs.persisted', '`contextSnapshot.schemaPrefs` ser\u00E1 persistido no documento can\u00F4nico.') }}</span>\n } @else {\n {{ tx('config.schema.prefs.implicit', 'Bloco ausente no documento can\u00F4nico. Os controles exibem fallback visual e n\u00E3o ser\u00E3o salvos at\u00E9 voc\u00EA editar.') }}\n }\n </div>\n </div>\n </mat-card-content>\n </mat-card>\n </div>\n </mat-tab>\n <mat-tab [label]=\"configTabLabel('layout')\">\n <div class=\"tab-content tab-content--full\" data-testid=\"config-tab-panel-layout\">\n <div class=\"section-body section-body--flex\">\n <praxis-layout-editor [config]=\"editedConfig\" (configChange)=\"onConfigChange($event)\"\n (select)=\"onLayoutSelect($event)\"></praxis-layout-editor>\n </div>\n </div>\n </mat-tab>\n <mat-tab [label]=\"configTabLabel('hooks')\">\n <div class=\"tab-content\" data-testid=\"config-tab-panel-hooks\">\n <mat-card class=\"section-card\">\n <mat-card-content>\n <div class=\"section-header\">\n <div>\n <h3>{{ tx('config.hooks.title', 'Hooks de ciclo de vida') }}</h3>\n <p class=\"text-caption\">{{ tx('config.hooks.subtitle', 'Automatize a\u00E7\u00F5es nos eventos do formul\u00E1rio.') }}</p>\n </div>\n </div>\n <praxis-hooks-editor [config]=\"editedConfig\" (configChange)=\"onConfigChange($event)\"></praxis-hooks-editor>\n </mat-card-content>\n </mat-card>\n </div>\n </mat-tab>\n @if (isPresentationMode) {\n <mat-tab [label]=\"configTabLabel('presentation')\">\n <div class=\"tab-content\" data-testid=\"config-tab-panel-presentation\">\n <mat-card class=\"section-card\">\n <mat-card-content>\n <div class=\"section-header\">\n <div>\n <h3>{{ tx('config.presentation.title', 'Modo Apresenta\u00E7\u00E3o') }}</h3>\n <p class=\"text-caption\">{{ tx('config.presentation.subtitle', 'Configura\u00E7\u00F5es de exibi\u00E7\u00E3o aplicadas somente ao modo apresenta\u00E7\u00E3o.') }}</p>\n </div>\n </div>\n <p class=\"display-result\" role=\"status\">{{ tx(displayModeHint) }}</p>\n <div class=\"presentation-layout\">\n <div class=\"presentation-controls\">\n <div class=\"block-status control-span\" [class.block-status--implicit]=\"!isPresentationBlockPersisted()\">\n <strong>{{ tx('config.presentation.block.label', 'Presentation') }}</strong>\n @if (isPresentationBlockPersisted()) {\n <span>{{ tx('config.presentation.block.persisted', '`contextSnapshot.presentation` ser\u00E1 persistido no documento can\u00F4nico.') }}</span>\n } @else {\n {{ tx('config.presentation.block.implicit', 'Bloco ausente no documento can\u00F4nico. A pr\u00E9-visualiza\u00E7\u00E3o usa fallback local e n\u00E3o ser\u00E1 salva at\u00E9 voc\u00EA editar.') }}\n }\n </div>\n <div class=\"control\">\n <label class=\"control__label\">{{ tx('config.presentation.labelPosition.label', 'Posi\u00E7\u00E3o do r\u00F3tulo') }}</label>\n <mat-button-toggle-group [(ngModel)]=\"presentationPrefs.labelPosition\" (ngModelChange)=\"onPresentationPrefsChange('presentation-label-position')\" [attr.aria-label]=\"tx('config.presentation.labelPosition.ariaLabel', 'Posi\u00E7\u00E3o do r\u00F3tulo')\"\n class=\"toggle-group\">\n <mat-button-toggle value=\"above\">\n <mat-icon>view_stream</mat-icon>\n <span class=\"sr-only\">{{ tx('config.presentation.labelPosition.above', 'Acima') }}</span>\n </mat-button-toggle>\n <mat-button-toggle value=\"left\">\n <mat-icon>view_column</mat-icon>\n <span class=\"sr-only\">{{ tx('config.presentation.labelPosition.left', '\u00C0 esquerda') }}</span>\n </mat-button-toggle>\n </mat-button-toggle-group>\n </div>\n <div class=\"control control-span\">\n <label class=\"control__label\">{{ tx('config.presentation.density.label', 'Densidade') }}</label>\n <mat-button-toggle-group [(ngModel)]=\"presentationPrefs.density\" (ngModelChange)=\"onPresentationPrefsChange('presentation-density')\" [attr.aria-label]=\"tx('config.presentation.density.ariaLabel', 'Densidade')\"\n class=\"toggle-group\">\n <mat-button-toggle value=\"comfortable\">{{ tx('config.presentation.density.comfortable', 'Confort\u00E1vel') }}</mat-button-toggle>\n <mat-button-toggle value=\"cozy\">{{ tx('config.presentation.density.cozy', 'Intermedi\u00E1ria') }}</mat-button-toggle>\n <mat-button-toggle value=\"compact\">{{ tx('config.presentation.density.compact', 'Compacta') }}</mat-button-toggle>\n </mat-button-toggle-group>\n </div>\n <div class=\"control\">\n <label class=\"control__label\">{{ tx('config.presentation.labelAlign.label', 'Alinhamento do r\u00F3tulo') }}</label>\n <mat-button-toggle-group [(ngModel)]=\"presentationPrefs.labelAlign\" (ngModelChange)=\"onPresentationPrefsChange('presentation-label-align')\" [attr.aria-label]=\"tx('config.presentation.labelAlign.ariaLabel', 'Alinhamento do r\u00F3tulo')\"\n class=\"toggle-group\">\n <mat-button-toggle value=\"start\" [aria-label]=\"tx('config.presentation.align.start')\" [matTooltip]=\"tx('config.presentation.align.start')\"><mat-icon>format_align_left</mat-icon></mat-button-toggle>\n <mat-button-toggle value=\"center\" [aria-label]=\"tx('config.presentation.align.center')\" [matTooltip]=\"tx('config.presentation.align.center')\"><mat-icon>format_align_center</mat-icon></mat-button-toggle>\n <mat-button-toggle value=\"end\" [aria-label]=\"tx('config.presentation.align.end')\" [matTooltip]=\"tx('config.presentation.align.end')\"><mat-icon>format_align_right</mat-icon></mat-button-toggle>\n </mat-button-toggle-group>\n </div>\n <div class=\"control\">\n <label class=\"control__label\">{{ tx('config.presentation.valueAlign.label', 'Alinhamento do valor') }}</label>\n <mat-button-toggle-group [(ngModel)]=\"presentationPrefs.valueAlign\" (ngModelChange)=\"onPresentationPrefsChange('presentation-value-align')\" [attr.aria-label]=\"tx('config.presentation.valueAlign.ariaLabel', 'Alinhamento do valor')\"\n class=\"toggle-group\">\n <mat-button-toggle value=\"start\" [aria-label]=\"tx('config.presentation.align.start')\" [matTooltip]=\"tx('config.presentation.align.start')\"><mat-icon>format_align_left</mat-icon></mat-button-toggle>\n <mat-button-toggle value=\"center\" [aria-label]=\"tx('config.presentation.align.center')\" [matTooltip]=\"tx('config.presentation.align.center')\"><mat-icon>format_align_center</mat-icon></mat-button-toggle>\n <mat-button-toggle value=\"end\" [aria-label]=\"tx('config.presentation.align.end')\" [matTooltip]=\"tx('config.presentation.align.end')\"><mat-icon>format_align_right</mat-icon></mat-button-toggle>\n </mat-button-toggle-group>\n </div>\n <div class=\"control\">\n <mat-form-field appearance=\"outline\" class=\"w-100\">\n <mat-label>{{ tx('config.presentation.labelFontSize.label', 'Tamanho do r\u00F3tulo') }}</mat-label>\n <input matInput type=\"number\" min=\"10\" step=\"any\" [(ngModel)]=\"presentationPrefs.labelFontSize\" (ngModelChange)=\"onPresentationPrefsChange('presentation-label-font-size')\"\n [placeholder]=\"tx('config.presentation.labelFontSize.placeholder', 'ex.: 12')\" />\n <span matSuffix>px</span>\n </mat-form-field>\n </div>\n <div class=\"control\">\n <mat-form-field appearance=\"outline\" class=\"w-100\">\n <mat-label>{{ tx('config.presentation.valueFontSize.label', 'Tamanho do valor') }}</mat-label>\n <input matInput type=\"number\" min=\"10\" step=\"any\" [(ngModel)]=\"presentationPrefs.valueFontSize\" (ngModelChange)=\"onPresentationPrefsChange('presentation-value-font-size')\"\n [placeholder]=\"tx('config.presentation.valueFontSize.placeholder', 'ex.: 16')\" />\n <span matSuffix>px</span>\n </mat-form-field>\n </div>\n <div class=\"control\">\n <mat-form-field appearance=\"outline\" class=\"w-100\">\n <mat-label>{{ tx('config.presentation.labelWidth.label', 'Largura do r\u00F3tulo (label \u00E0 esquerda)') }}</mat-label>\n <input matInput type=\"number\" min=\"60\" [disabled]=\"presentationPrefs.labelPosition !== 'left'\" [(ngModel)]=\"presentationPrefs.labelWidth\" (ngModelChange)=\"onPresentationPrefsChange('presentation-label-width')\"\n [placeholder]=\"tx('config.presentation.labelWidth.placeholder', 'ex.: 140')\" />\n <span matSuffix>px</span>\n </mat-form-field>\n </div>\n <div class=\"control control--inline\">\n <mat-slide-toggle [(ngModel)]=\"presentationPrefs.compact\" (ngModelChange)=\"onPresentationPrefsChange('presentation-compact')\">\n {{ tx('config.presentation.options.compactMode', 'Modo compacto') }}\n </mat-slide-toggle>\n <mat-checkbox [(ngModel)]=\"truncatePreview\">\n {{ tx('config.presentation.options.truncateValues', 'Truncar valores') }}\n </mat-checkbox>\n </div>\n </div>\n <div class=\"presentation-preview\">\n <h4>{{ tx('config.presentation.preview.title', 'Pr\u00E9-visualiza\u00E7\u00E3o') }}</h4>\n <p class=\"text-caption\">{{ tx('config.presentation.preview.sampleHint') }}</p>\n <div class=\"preview-card\">\n <div class=\"praxis-dynamic-form presentation-mode\" [ngClass]=\"{\n 'pres-compact': !!presentationPrefs.compact,\n 'pres-label-left': presentationPrefs.labelPosition === 'left',\n 'pres-label-above': presentationPrefs.labelPosition === 'above',\n 'pres-density-compact': presentationPrefs.density === 'compact',\n 'pres-density-cozy': presentationPrefs.density === 'cozy'\n }\" [style.--pfx-pres-label-size]=\"(presentationPrefs.labelFontSize || 12) + 'px'\"\n [style.--pfx-pres-value-size]=\"(presentationPrefs.valueFontSize || 16) + 'px'\"\n [style.--pfx-pres-label-width]=\"(presentationPrefs.labelWidth || 140) + 'px'\"\n [style.--pfx-pres-label-align]=\"presentationPrefs.labelAlign || 'start'\"\n [style.--pfx-pres-value-align]=\"presentationPrefs.valueAlign || 'start'\">\n @for (item of previewItems; track item) {\n <div class=\"preview-row\">\n <span class=\"praxis-presentation__label\">{{ item.label }}</span>\n <span class=\"praxis-presentation__value\" [attr.title]=\"truncatePreview ? item.value : null\"\n [style.maxWidth]=\"truncatePreview ? '280px' : null\"\n [style.overflow]=\"truncatePreview ? 'hidden' : null\"\n [style.textOverflow]=\"truncatePreview ? 'ellipsis' : null\"\n [style.whiteSpace]=\"truncatePreview ? 'nowrap' : 'normal'\">\n {{ item.value }}\n </span>\n </div>\n }\n </div>\n </div>\n </div>\n </div>\n\n </mat-card-content>\n </mat-card>\n </div>\n </mat-tab>\n }\n <mat-tab [label]=\"configTabLabel('behavior')\">\n <div class=\"tab-content\" data-testid=\"config-tab-panel-comportamento\">\n <mat-card class=\"section-card\">\n <mat-card-content>\n <div class=\"section-header\">\n <div>\n <h3>{{ tx('config.behavior.title', 'Comportamento') }}</h3>\n <p class=\"text-caption\">{{ tx('config.behavior.subtitle', 'Ajuste valida\u00E7\u00F5es e respostas do formul\u00E1rio.') }}</p>\n </div>\n </div>\n <praxis-behavior-editor [config]=\"editedConfig\" (configChange)=\"onConfigChange($event)\"></praxis-behavior-editor>\n </mat-card-content>\n </mat-card>\n </div>\n </mat-tab>\n <mat-tab [label]=\"configTabLabel('hints')\">\n <div class=\"tab-content tab-content--dense\" data-testid=\"config-tab-panel-hints\">\n <mat-card class=\"section-card\">\n <mat-card-content>\n <div class=\"section-header\">\n <div>\n <h3>{{ tx('config.hints.title', 'Dicas dos modos') }}</h3>\n <p class=\"text-caption\">{{ tx('config.hints.subtitle', 'Personalize textos de apoio para modos de dados e estados de UI.') }}</p>\n </div>\n </div>\n <p class=\"text-caption\">{{ tx('config.hints.description', 'Personalize os textos usados como tooltip/hint para modos de dados e modos globais de UI.') }}</p>\n\n <div class=\"grid-2-cols grid-2-cols--compact\">\n <section>\n <h4>{{ tx('config.hints.dataModes.title', 'Modos de dados') }}</h4>\n <mat-form-field appearance=\"outline\" class=\"w-100\">\n <mat-label>{{ tx('config.hints.dataModes.create.label', 'Criar') }}</mat-label>\n <input matInput [(ngModel)]=\"editedConfig.hints!.dataModes.create\"\n (ngModelChange)=\"updateDirtyState('hints-data-create')\" [placeholder]=\"tx('config.hints.dataModes.create.placeholder', 'Ex.: Preencha os campos obrigat\u00F3rios.')\" />\n </mat-form-field>\n <mat-form-field appearance=\"outline\" class=\"w-100\">\n <mat-label>{{ tx('config.hints.dataModes.edit.label', 'Editar') }}</mat-label>\n <input matInput [(ngModel)]=\"editedConfig.hints!.dataModes.edit\"\n (ngModelChange)=\"updateDirtyState('hints-data-edit')\" [placeholder]=\"tx('config.hints.dataModes.edit.placeholder', 'Ex.: Revise os dados antes de salvar.')\" />\n </mat-form-field>\n <mat-form-field appearance=\"outline\" class=\"w-100\">\n <mat-label>{{ tx('config.hints.dataModes.view.label', 'Visualizar') }}</mat-label>\n <input matInput [(ngModel)]=\"editedConfig.hints!.dataModes.view\"\n (ngModelChange)=\"updateDirtyState('hints-data-view')\" [placeholder]=\"tx('config.hints.dataModes.view.placeholder', 'Ex.: Visualiza\u00E7\u00E3o somente leitura.')\" />\n </mat-form-field>\n </section>\n\n <section>\n <h4>{{ tx('config.hints.uiModes.title', 'Modos de UI') }}</h4>\n <mat-form-field appearance=\"outline\" class=\"w-100\">\n <mat-label>{{ tx('config.hints.uiModes.presentation.label', 'Apresenta\u00E7\u00E3o') }}</mat-label>\n <textarea matInput rows=\"2\" [(ngModel)]=\"editedConfig.hints!.uiModes.presentation\"\n (ngModelChange)=\"updateDirtyState('hints-ui-presentation')\" [placeholder]=\"tx('config.hints.uiModes.presentation.placeholder', 'Ex.: Modo compacto para leitura r\u00E1pida.')\"></textarea>\n </mat-form-field>\n <mat-form-field appearance=\"outline\" class=\"w-100\">\n <mat-label>{{ tx('config.hints.uiModes.readonly.label', 'Leitura (readonly)') }}</mat-label>\n <textarea matInput rows=\"2\" [(ngModel)]=\"editedConfig.hints!.uiModes.readonly\"\n (ngModelChange)=\"updateDirtyState('hints-ui-readonly')\" [placeholder]=\"tx('config.hints.uiModes.readonly.placeholder', 'Ex.: Campos bloqueados para edi\u00E7\u00E3o.')\"></textarea>\n </mat-form-field>\n <mat-form-field appearance=\"outline\" class=\"w-100\">\n <mat-label>{{ tx('config.hints.uiModes.disabled.label', 'Desabilitado') }}</mat-label>\n <textarea matInput rows=\"2\" [(ngModel)]=\"editedConfig.hints!.uiModes.disabled\"\n (ngModelChange)=\"updateDirtyState('hints-ui-disabled')\" [placeholder]=\"tx('config.hints.uiModes.disabled.placeholder', 'Ex.: Fun\u00E7\u00E3o indispon\u00EDvel no momento.')\"></textarea>\n </mat-form-field>\n <mat-form-field appearance=\"outline\" class=\"w-100\">\n <mat-label>{{ tx('config.hints.uiModes.visible.label', 'Vis\u00EDvel') }}</mat-label>\n <textarea matInput rows=\"2\" [(ngModel)]=\"editedConfig.hints!.uiModes.visible\"\n (ngModelChange)=\"updateDirtyState('hints-ui-visible')\" [placeholder]=\"tx('config.hints.uiModes.visible.placeholder', 'Ex.: Campo exibido conforme permiss\u00F5es.')\"></textarea>\n </mat-form-field>\n </section>\n </div>\n\n <section>\n <h4>{{ tx('config.helpPresentation.title', 'Apresenta\u00E7\u00E3o das ajudas dos campos') }}</h4>\n <p class=\"text-caption\">{{ tx('config.helpPresentation.description', 'Controle como hint/helpText dos campos aparece em formul\u00E1rios densos. Erros de valida\u00E7\u00E3o continuam inline.') }}</p>\n <div class=\"grid-3-cols\">\n <mat-form-field appearance=\"outline\" class=\"w-100\">\n <mat-label>{{ tx('config.helpPresentation.display.label', 'Exibi\u00E7\u00E3o') }}</mat-label>\n <mat-select [ngModel]=\"helpPresentationDraft.display\" (ngModelChange)=\"onHelpPresentationDisplayChange($event)\">\n <mat-option value=\"inline\">{{ tx('config.helpPresentation.display.inline', 'Inline') }}</mat-option>\n <mat-option value=\"popover\">{{ tx('config.helpPresentation.display.popover', '\u00CDcone de ajuda') }}</mat-option>\n <mat-option value=\"auto\">{{ tx('config.helpPresentation.display.auto', 'Autom\u00E1tica') }}</mat-option>\n <mat-option value=\"hidden\">{{ tx('config.helpPresentation.display.hidden', 'Oculta') }}</mat-option>\n </mat-select>\n </mat-form-field>\n <mat-form-field appearance=\"outline\" class=\"w-100\">\n <mat-label>{{ tx('config.helpPresentation.inlineMaxLength.label', 'Limite inline') }}</mat-label>\n <input matInput type=\"number\" min=\"0\" [ngModel]=\"helpPresentationDraft.inlineMaxLength\"\n (ngModelChange)=\"onHelpPresentationInlineMaxLengthChange($event)\" />\n </mat-form-field>\n <mat-form-field appearance=\"outline\" class=\"w-100\">\n <mat-label>{{ tx('config.helpPresentation.preferPopoverForControls.label', 'Preferir \u00EDcone em') }}</mat-label>\n <input matInput [ngModel]=\"getHelpPreferPopoverControlsText()\"\n (ngModelChange)=\"onHelpPreferPopoverControlsChange($event)\"\n [placeholder]=\"tx('config.helpPresentation.preferPopoverForControls.placeholder', 'toggle, checkbox, select')\" />\n </mat-form-field>\n </div>\n </section>\n\n <div class=\"actions-row\">\n <button mat-stroked-button color=\"primary\" type=\"button\" (click)=\"restoreHintsDefaults()\">\n <mat-icon>restore</mat-icon>\n {{ tx('config.hints.actions.restoreDefaults', 'Restaurar padr\u00F5es') }}\n </button>\n </div>\n </mat-card-content>\n </mat-card>\n </div>\n </mat-tab>\n <mat-tab [label]=\"configTabLabel('actions')\">\n <div class=\"tab-content\" data-testid=\"config-tab-panel-acoes\">\n <mat-card class=\"section-card\">\n <mat-card-content>\n <div class=\"section-header\">\n <div>\n <h3>{{ tx('config.actions.title', 'A\u00E7\u00F5es do formul\u00E1rio') }}</h3>\n <p class=\"text-caption\">{{ tx('config.actions.subtitle', 'Configure bot\u00F5es padr\u00E3o e a\u00E7\u00F5es customizadas.') }}</p>\n </div>\n </div>\n <praxis-actions-editor #actionsDraft [config]=\"editedConfig\" (validationChange)=\"onSurfaceDraftValidity(actionsDraft, $event)\" (configChange)=\"onConfigChange($event)\"></praxis-actions-editor>\n </mat-card-content>\n </mat-card>\n </div>\n </mat-tab>\n <mat-tab [label]=\"configTabLabel('rules')\">\n <div class=\"tab-content visual-builder-content\" data-testid=\"config-tab-panel-regras\">\n <div class=\"builder-header\">\n <div>\n <h3>{{ tx('config.rules.title', 'Regras visuais') }}</h3>\n <p class=\"text-caption\">{{ tx('config.rules.subtitle', 'Defina visibilidade, estilos e rea\u00E7\u00F5es baseadas em condi\u00E7\u00F5es.') }}</p>\n </div>\n </div>\n @if (ruleDiagnostics.length) {\n <div class=\"rules-diagnostics\" data-testid=\"rules-diagnostics-panel\">\n <div class=\"rules-diagnostics__summary\">\n <span class=\"rules-diagnostics__pill rules-diagnostics__pill--total\">\n {{ tx('config.rules.summary.total', '{{count}} regras', { count: ruleDiagnosticsSummary.total }) }}\n </span>\n @if (ruleDiagnosticsSummary.invalid) {\n <span class=\"rules-diagnostics__pill rules-diagnostics__pill--error\">\n {{ tx('config.rules.summary.invalid', '{{count}} inv\u00E1lidas', { count: ruleDiagnosticsSummary.invalid }) }}\n </span>\n }\n @if (ruleDiagnosticsSummary.unsupported) {\n <span class=\"rules-diagnostics__pill rules-diagnostics__pill--warn\">\n {{ tx('config.rules.summary.unsupported', '{{count}} com propriedades rejeitadas', { count: ruleDiagnosticsSummary.unsupported }) }}\n </span>\n }\n @if (ruleDiagnosticsSummary.runtimeOnly) {\n <span class=\"rules-diagnostics__pill rules-diagnostics__pill--warn\">\n {{ tx('config.rules.summary.runtimeOnly', '{{count}} runtime only', { count: ruleDiagnosticsSummary.runtimeOnly }) }}\n </span>\n }\n @if (ruleDiagnosticsSummary.pendingReview) {\n <span class=\"rules-diagnostics__pill rules-diagnostics__pill--warn\">\n {{ tx('config.rules.summary.pendingReview', '{{count}} pendentes de revis\u00E3o', { count: ruleDiagnosticsSummary.pendingReview }) }}\n </span>\n }\n </div>\n <div class=\"rules-diagnostics__list\" [attr.aria-label]=\"tx('config.rules.diagnostics.ariaLabel', 'Diagn\u00F3stico das regras')\">\n @for (diagnostic of ruleDiagnostics; track diagnostic) {\n <article class=\"rules-diagnostics__item\"\n [class.rules-diagnostics__item--error]=\"getRuleStatusTone(diagnostic) === 'error'\"\n [class.rules-diagnostics__item--warn]=\"getRuleStatusTone(diagnostic) === 'warn'\">\n <div>\n <strong>{{ diagnostic.ruleName || diagnostic.ruleId }}</strong>\n <span>\n {{ tx('config.rules.diagnostics.targetConditionSummary', '{{targets}} alvo(s) \u00B7 {{conditions}} campo(s) na condi\u00E7\u00E3o', { targets: diagnostic.targetRefs.length, conditions: diagnostic.conditionRefs.length }) }}\n </span>\n @if (getRuleDiagnosticDetails(diagnostic).length) {\n <ul class=\"rules-diagnostics__details\">\n @for (detail of getRuleDiagnosticDetails(diagnostic); track detail) {\n <li>{{ detail }}</li>\n }\n </ul>\n }\n </div>\n <div class=\"rules-diagnostics__actions\">\n <span class=\"rules-diagnostics__status\">{{ getRuleStatusLabel(diagnostic) }}</span>\n @if (canApplyRulePropertyFix(diagnostic)) {\n <button\n mat-stroked-button\n type=\"button\"\n class=\"rules-diagnostics__action\"\n [matTooltip]=\"tx('config.rules.actions.fix.tooltip', 'Aplicar whitelist e saneamento de propriedades nesta regra')\"\n (click)=\"applyRulePropertyFix(diagnostic.ruleId)\">\n <mat-icon aria-hidden=\"true\">auto_fix_high</mat-icon>\n {{ tx('config.rules.actions.fix', 'Corrigir') }}\n </button>\n }\n @if (diagnostic.status.includes('llm-generated-pending-review')) {\n <button\n mat-stroked-button\n type=\"button\"\n class=\"rules-diagnostics__action\"\n [disabled]=\"!canAcceptPendingLlmRule(diagnostic)\"\n [matTooltip]=\"canAcceptPendingLlmRule(diagnostic) ? tx('config.rules.actions.accept.tooltip.ready', 'Aceitar sugest\u00E3o e atualizar estado visual') : tx('config.rules.actions.accept.tooltip.blocked', 'Corrija alvo, condi\u00E7\u00E3o e propriedades antes de aceitar')\"\n (click)=\"acceptPendingLlmRule(diagnostic.ruleId)\">\n <mat-icon aria-hidden=\"true\">check</mat-icon>\n {{ tx('config.rules.actions.accept', 'Aceitar') }}\n </button>\n }\n @if (canOpenRuleJsonReview(diagnostic)) {\n <button\n mat-stroked-button\n type=\"button\"\n class=\"rules-diagnostics__action\"\n [matTooltip]=\"tx('config.rules.actions.reviewJson.tooltip', 'Abrir a aba JSON para revisar esta regra sem convers\u00E3o visual')\"\n (click)=\"openRuleJsonReview(diagnostic.ruleId)\">\n <mat-icon aria-hidden=\"true\">data_object</mat-icon>\n {{ tx('config.rules.actions.reviewJson', 'Ver JSON') }}\n </button>\n }\n </div>\n </article>\n }\n </div>\n </div>\n } @else {\n <div class=\"rules-diagnostics rules-diagnostics--empty\" data-testid=\"rules-diagnostics-empty\">\n {{ tx('config.rules.empty', 'Nenhuma regra definida ainda. Crie uma regra para ver alvos, condi\u00E7\u00E3o, propriedades e compatibilidade do builder.') }}\n </div>\n }\n <praxis-visual-builder [config]=\"ruleBuilderConfig\" [initialRules]=\"ruleBuilderState\"\n (rulesChanged)=\"onRulesChanged($event)\"></praxis-visual-builder>\n <praxis-rule-properties-panel\n [rules]=\"currentRules\"\n [visualBlockNodes]=\"visualBlockNodeOptions\"\n (rulesChange)=\"onRulePropertiesChanged($event)\"\n ></praxis-rule-properties-panel>\n <mat-card class=\"command-rules-card\" data-testid=\"form-command-rules-editor\">\n <mat-card-title>{{ tx('config.commandRules.title', 'Comandos condicionais') }}</mat-card-title>\n <mat-card-subtitle>{{ tx('config.commandRules.subtitle', 'Execute a\u00E7\u00F5es globais quando uma condi\u00E7\u00E3o do formul\u00E1rio for satisfeita.') }}</mat-card-subtitle>\n <mat-card-content>\n <div class=\"command-rules-grid\">\n <div class=\"command-rules-toolbar\">\n <mat-form-field appearance=\"outline\" class=\"command-rules-select\">\n <mat-label>{{ tx('config.commandRules.command.label', 'Comando') }}</mat-label>\n <mat-select [disabled]=\"hasInvalidSurfaceDraft\" [(ngModel)]=\"selectedCommandRuleId\" (selectionChange)=\"onCommandRuleSelectionChange()\">\n @for (rule of commandRules; track rule) {\n <mat-option [value]=\"rule.id\">\n {{ rule.id }}\n </mat-option>\n }\n </mat-select>\n </mat-form-field>\n <button mat-stroked-button type=\"button\" [disabled]=\"hasInvalidSurfaceDraft\" (click)=\"addCommandRule()\">\n <mat-icon aria-hidden=\"true\">add</mat-icon>\n {{ tx('config.commandRules.actions.add', 'Adicionar') }}\n </button>\n <button mat-stroked-button color=\"warn\" type=\"button\" (click)=\"deleteCommandRule()\" [disabled]=\"hasInvalidSurfaceDraft || !selectedCommandRuleId\">\n <mat-icon aria-hidden=\"true\">delete</mat-icon>\n {{ tx('config.commandRules.actions.remove', 'Remover') }}\n </button>\n </div>\n\n @if (selectedCommandRuleId) {\n <div class=\"command-rule-condition-builder command-rules-full\">\n <praxis-visual-builder\n mode=\"condition\"\n [config]=\"ruleBuilderConfig\"\n [initialCondition]=\"commandRuleCondition\"\n (conditionChanged)=\"onCommandConditionChanged($event)\"\n ></praxis-visual-builder>\n </div>\n }\n\n <mat-form-field appearance=\"outline\" class=\"command-rules-full\">\n <mat-label>{{ tx('config.commandRules.conditionJson.label', 'Condi\u00E7\u00E3o JSON Logic') }}</mat-label>\n <textarea\n matInput\n rows=\"5\"\n [(ngModel)]=\"commandRuleConditionJson\"\n [attr.aria-label]=\"tx('config.commandRules.conditionJson.ariaLabel', 'Condi\u00E7\u00E3o JSON Logic do comando condicional')\"\n ></textarea>\n </mat-form-field>\n\n <mat-form-field appearance=\"outline\">\n <mat-label>{{ tx('config.commandRules.globalAction.label', 'A\u00E7\u00E3o global') }}</mat-label>\n <mat-select [disabled]=\"hasInvalidSurfaceDraft\" [(ngModel)]=\"commandRuleActionId\" (selectionChange)=\"onCommandActionChange()\">\n @for (action of globalActionCatalog; track action) {\n <mat-option [value]=\"action.id\">\n {{ action.label || action.id }}\n </mat-option>\n }\n </mat-select>\n </mat-form-field>\n\n <mat-form-field appearance=\"outline\">\n <mat-label>{{ tx('config.commandRules.distinctBy.label', 'distinctBy') }}</mat-label>\n <input matInput [(ngModel)]=\"commandRuleDistinctBy\" [placeholder]=\"tx('config.commandRules.distinctBy.placeholder', 'ex.: idade')\" />\n </mat-form-field>\n\n @if (commandRuleActionSchema; as actionSchema) {\n <div\n class=\"command-rules-payload-fields command-rules-full\"\n >\n <div class=\"command-rules-section-title\">{{ tx('config.commandRules.structuredPayload.title', 'Payload estruturado') }}</div>\n @if (actionSchema.editorMode !== 'surface-open') {\n @for (field of actionSchema.fields; track field) {\n @if (shouldShowCommandActionField(field)) {\n @if (field.type === 'toggle') {\n <mat-slide-toggle\n [ngModel]=\"getCommandActionFieldValue(field)\"\n (ngModelChange)=\"onCommandActionFieldChange(field, $event)\"\n [ngModelOptions]=\"{ standalone: true }\"\n >\n {{ field.label }}\n </mat-slide-toggle>\n } @else {\n <mat-form-field appearance=\"outline\">\n <mat-label>{{ field.label }}</mat-label>\n @if (field.type === 'textarea' || field.type === 'json') {\n <textarea\n matInput\n [rows]=\"field.rows || (field.type === 'json' ? 3 : 2)\"\n [ngModel]=\"getCommandActionFieldValue(field)\"\n (ngModelChange)=\"onCommandActionFieldChange(field, $event)\"\n [ngModelOptions]=\"{ standalone: true }\"\n [placeholder]=\"field.placeholder || (field.type === 'json' ? '{ }' : '')\"\n [required]=\"isCommandActionFieldRequired(field)\"\n ></textarea>\n } @else {\n @if (field.type === 'select') {\n <mat-select\n [ngModel]=\"getCommandActionFieldValue(field)\"\n (ngModelChange)=\"onCommandActionFieldChange(field, $event)\"\n [ngModelOptions]=\"{ standalone: true }\"\n [required]=\"isCommandActionFieldRequired(field)\"\n >\n @for (option of field.options || []; track option) {\n <mat-option [value]=\"option.value\">\n {{ option.label }}\n </mat-option>\n }\n </mat-select>\n } @else {\n <input\n matInput\n [type]=\"field.type === 'number' ? 'number' : 'text'\"\n [ngModel]=\"getCommandActionFieldValue(field)\"\n (ngModelChange)=\"onCommandActionFieldChange(field, $event)\"\n [ngModelOptions]=\"{ standalone: true }\"\n [placeholder]=\"field.placeholder || ''\"\n [required]=\"isCommandActionFieldRequired(field)\"\n />\n }\n }\n @if (field.hint) {\n <mat-hint>{{ field.hint }}</mat-hint>\n }\n @if (hasCommandActionFieldError(field.key)) {\n <mat-error>\n {{ getCommandActionFieldError(field.key) }}\n </mat-error>\n }\n @if (!hasCommandActionFieldError(field.key) && isCommandActionFieldMissing(field)) {\n <mat-error>\n {{ tx('config.commandRules.validation.requiredField', 'Campo obrigat\u00F3rio.') }}\n </mat-error>\n }\n </mat-form-field>\n }\n }\n }\n } @else {\n <praxis-surface-open-action-editor #commandSurfaceDraft\n class=\"command-rules-surface-editor\"\n data-testid=\"form-command-rule-surface-open-editor\"\n [value]=\"commandRuleSurfaceOpenPayload\"\n hostKind=\"dynamic-form\"\n (valueChange)=\"onCommandSurfaceOpenPayloadChange($event)\"\n (validationChange)=\"onSurfaceDraftValidity(commandSurfaceDraft, $event)\"\n ></praxis-surface-open-action-editor>\n }\n </div>\n }\n\n <mat-form-field appearance=\"outline\" class=\"command-rules-full\">\n <mat-label>{{ tx('config.commandRules.advancedPayload.label', 'Payload JSON avan\u00E7ado') }}</mat-label>\n <textarea\n matInput\n rows=\"4\"\n [(ngModel)]=\"commandRulePayloadJson\"\n [attr.aria-label]=\"tx('config.commandRules.advancedPayload.ariaLabel', 'Payload JSON da a\u00E7\u00E3o global')\"\n ></textarea>\n </mat-form-field>\n\n <div class=\"command-rules-options\">\n <mat-slide-toggle [(ngModel)]=\"commandRuleDistinct\">{{ tx('config.commandRules.options.distinct', 'Evitar repeti\u00E7\u00E3o enquanto a condi\u00E7\u00E3o permanecer verdadeira') }}</mat-slide-toggle>\n <mat-slide-toggle [(ngModel)]=\"commandRuleRunOnInitialEvaluation\">{{ tx('config.commandRules.options.runOnInitialEvaluation', 'Executar tamb\u00E9m na avalia\u00E7\u00E3o inicial') }}</mat-slide-toggle>\n </div>\n\n @if (commandRuleAuthoringError) {\n <div class=\"preview-error command-rules-full\">\n <mat-icon aria-hidden=\"true\">warning</mat-icon>\n <span>{{ commandRuleAuthoringError }}</span>\n </div>\n }\n\n <div\n class=\"command-rule-preview command-rules-full\"\n [class.command-rule-preview--invalid]=\"commandRulePreview.state === 'invalid'\"\n data-testid=\"command-rule-preview\"\n >\n <div class=\"command-rules-section-title\">{{ tx('config.commandRules.preview.title', 'Preview do comando') }}</div>\n <div class=\"command-rule-preview__row\">\n <span>{{ tx('config.commandRules.preview.mode', 'Modo') }}</span>\n <strong>{{ commandRulePreview.executionMode }}</strong>\n </div>\n <div class=\"command-rule-preview__row\">\n <span>{{ tx('config.commandRules.preview.action', 'A\u00E7\u00E3o') }}</span>\n <strong>{{ commandRulePreview.actionId || '\u2014' }}</strong>\n </div>\n <div class=\"command-rule-preview__row\">\n <span>{{ tx('config.commandRules.preview.policy', 'Policy') }}</span>\n <code>{{ commandRulePreview.policy | json }}</code>\n </div>\n @if (commandRulePreview.diagnostics.length) {\n <div class=\"command-rule-preview__diagnostics\">\n <mat-icon aria-hidden=\"true\">{{ commandRulePreview.state === 'invalid' ? 'warning' : 'visibility' }}</mat-icon>\n <span>{{ commandRulePreview.diagnostics[0] }}</span>\n </div>\n }\n </div>\n\n <div class=\"command-rules-actions\">\n <button mat-flat-button color=\"primary\" type=\"button\" (click)=\"applyCommandRule()\">\n <mat-icon aria-hidden=\"true\">check</mat-icon>\n {{ tx('config.commandRules.actions.apply', 'Aplicar comando') }}\n </button>\n </div>\n </div>\n </mat-card-content>\n </mat-card>\n </div>\n </mat-tab>\n <mat-tab [label]=\"configTabLabel('cascades')\">\n <div class=\"tab-content\" data-testid=\"config-tab-panel-cascatas\">\n <mat-card class=\"section-card\">\n <mat-card-content>\n <div class=\"section-header\">\n <div>\n <h3>{{ tx('config.cascades.title', 'Depend\u00EAncias entre campos') }}</h3>\n <p class=\"text-caption\">{{ tx('config.cascades.subtitle', 'Configure cascatas e carregamento entre campos.') }}</p>\n </div>\n </div>\n <praxis-cascade-manager-tab [fields]=\"editedConfig.fieldMetadata || []\"\n (apply)=\"onCascadeApply($event)\"></praxis-cascade-manager-tab>\n </mat-card-content>\n </mat-card>\n </div>\n </mat-tab>\n <mat-tab [label]=\"configTabLabel('messages')\">\n <div class=\"tab-content\" data-testid=\"config-tab-panel-mensagens\">\n <mat-card class=\"section-card\">\n <mat-card-content>\n <div class=\"section-header\">\n <div>\n <h3>{{ tx('config.messages.title', 'Mensagens e feedback') }}</h3>\n <p class=\"text-caption\">{{ tx('config.messages.subtitle', 'Padronize textos de sucesso, erro e confirma\u00E7\u00F5es.') }}</p>\n </div>\n </div>\n <praxis-messages-editor [config]=\"editedConfig\" (configChange)=\"onConfigChange($event)\"></praxis-messages-editor>\n </mat-card-content>\n </mat-card>\n </div>\n </mat-tab>\n <mat-tab [label]=\"configTabLabel('navigation')\">\n <div class=\"tab-content\" data-testid=\"config-tab-panel-navegacao\">\n <mat-card class=\"section-card\">\n <mat-card-content>\n <div class=\"section-header\">\n <div>\n <h3>{{ tx('config.navigation.title', 'Navega\u00E7\u00E3o de retorno') }}</h3>\n <p class=\"text-caption\">{{ tx('config.navigation.subtitle', 'Defina o comportamento do bot\u00E3o Voltar em fluxos CRUD.') }}</p>\n </div>\n </div>\n <div class=\"form-grid\">\n <div class=\"form-row\">\n <mat-form-field appearance=\"outline\" class=\"w-100\">\n <mat-label>{{ tx('config.navigation.returnTo.label', 'Rota de retorno') }}</mat-label>\n <input matInput id=\"returnTo\" [(ngModel)]=\"backConfig!.returnTo\" (ngModelChange)=\"onBackConfigChange()\" [placeholder]=\"tx('config.navigation.returnTo.placeholder', '/funcionarios')\" />\n </mat-form-field>\n </div>\n <div class=\"form-row\">\n <mat-slide-toggle [(ngModel)]=\"backConfig!.confirmOnDirty\" (ngModelChange)=\"onBackConfigChange()\">\n {{ tx('config.navigation.confirmOnDirty.label', 'Confirmar ao sair com altera\u00E7\u00F5es') }}\n </mat-slide-toggle>\n </div>\n <div class=\"block-status\" [class.block-status--implicit]=\"!isBackConfigBlockPersisted()\">\n <strong>{{ tx('config.navigation.backConfig.label', 'Back Config') }}</strong>\n @if (isBackConfigBlockPersisted()) {\n <span>{{ tx('config.navigation.backConfig.persisted', '`contextSnapshot.backConfig` ser\u00E1 persistido no documento can\u00F4nico.') }}</span>\n } @else {\n {{ tx('config.navigation.backConfig.implicit', 'Bloco ausente no documento can\u00F4nico. Os valores exibidos s\u00E3o fallback visual e n\u00E3o ser\u00E3o salvos at\u00E9 voc\u00EA editar.') }}\n }\n </div>\n </div>\n <div class=\"section-help\">\n <span class=\"section-help__label\">{{ tx('config.navigation.note.label', 'Observa\u00E7\u00E3o:') }}</span>\n <button\n praxisIconButton=\"help_outline\"\n size=\"dense\"\n class=\"help-icon-button\"\n type=\"button\"\n [matTooltip]=\"tx('config.navigation.note.tooltip', 'Afeta o fluxo de navega\u00E7\u00E3o do CRUD e pode ser sobreposto por metadados do recurso.')\"\n matTooltipPosition=\"above\"\n >\n </button>\n </div>\n </mat-card-content>\n </mat-card>\n </div>\n </mat-tab>\n <mat-tab [label]=\"configTabLabel('json')\">\n <div class=\"tab-content json-tab-content\" data-testid=\"config-tab-panel-json\">\n <mat-card class=\"section-card section-card--json\">\n <mat-card-content>\n <div class=\"section-header\">\n <div>\n <h3>{{ tx('config.json.title', 'Configura\u00E7\u00E3o JSON') }}</h3>\n <p class=\"text-caption\">{{ tx('config.json.subtitle', 'Edi\u00E7\u00E3o avan\u00E7ada do documento can\u00F4nico de autoria do formul\u00E1rio.') }}</p>\n </div>\n </div>\n <form-json-config-editor [document]=\"jsonDocument\" (documentChange)=\"onJsonConfigChange($event)\"\n (validationChange)=\"onJsonValidationChange($event)\" (editorEvent)=\"onJsonEditorEvent($event)\">\n </form-json-config-editor>\n </mat-card-content>\n </mat-card>\n </div>\n </mat-tab>\n</mat-tab-group>\n", styles: [":host{container:praxis-authoring-editor/inline-size;display:flex;flex-direction:column;height:100%;min-width:0}.mobile-tab-selector{display:none;flex:0 0 auto;padding:8px 16px 0;background:var(--md-sys-color-surface)}.mobile-tab-selector__field{width:100%}.config-tabs{flex:1 1 auto;min-height:0;min-width:0}::ng-deep .mat-mdc-tab-group.config-tabs{display:flex;flex-direction:column}::ng-deep .mat-mdc-tab-group.config-tabs .mat-mdc-tab-body-wrapper{flex:1;min-height:0;min-width:0}::ng-deep .mat-mdc-tab-group.config-tabs .mat-mdc-tab-body-content{height:100%;overflow-y:auto;overflow-x:hidden;display:flex;flex-direction:column;padding:0!important}.tab-content{padding:20px 24px 28px;flex:1;min-width:0;box-sizing:border-box;display:flex;flex-direction:column;gap:24px}.json-tab-content{min-width:0;padding:12px 16px 16px}.section-card.section-card--json{display:flex;flex:1;min-height:calc(100vh - 180px);border:1px solid var(--md-sys-color-outline-variant);border-radius:12px;background:var(--md-sys-color-surface-container-low)}.section-card.section-card--json>mat-card-content,.section-card.section-card--json>.mat-mdc-card-content{display:flex;flex:1;min-width:0;min-height:0;flex-direction:column;padding:16px!important}.section-card--json form-json-config-editor{display:block;flex:1;min-width:0;min-height:0}.form-row{display:block;margin-bottom:12px}.form-grid{display:grid;gap:12px}.section-help{display:inline-flex;align-items:center;gap:8px;color:var(--md-sys-color-on-surface-variant);font-size:12px}.section-help__label{font-weight:500}.grid-2-cols{display:grid;grid-template-columns:repeat(auto-fit,minmax(260px,1fr));gap:16px}.grid-2-cols--compact{gap:12px}.w-100{width:100%}.visual-builder-content{padding:0!important;height:100%;min-width:0;overflow-y:auto;overflow-x:hidden;display:flex;flex-direction:column;gap:16px}.visual-builder-content>praxis-visual-builder{flex:0 0 auto;min-width:0;min-height:clamp(360px,48vh,560px)}.visual-builder-content>praxis-rule-properties-panel{flex:0 0 auto;display:block;min-width:0;padding:0 16px 24px;box-sizing:border-box}.rules-diagnostics{flex:0 0 auto;display:grid;gap:10px;padding:12px 16px;border-bottom:1px solid var(--md-sys-color-outline-variant);background:var(--md-sys-color-surface-container-low)}.rules-diagnostics--empty{color:var(--md-sys-color-on-surface-variant);font-size:12px;line-height:1.45}.rules-diagnostics__summary,.rules-diagnostics__list{display:flex;flex-wrap:wrap;gap:8px}.rules-diagnostics__pill{display:inline-flex;align-items:center;min-height:24px;padding:3px 9px;border-radius:999px;background:var(--md-sys-color-surface-container-high);color:var(--md-sys-color-on-surface);font-size:12px;font-weight:600}.rules-diagnostics__pill--warn{background:color-mix(in srgb,var(--md-sys-color-tertiary-container) 72%,transparent);color:var(--md-sys-color-on-tertiary-container)}.rules-diagnostics__pill--error{background:var(--md-sys-color-error-container);color:var(--md-sys-color-on-error-container)}.rules-diagnostics__item{display:flex;align-items:flex-start;justify-content:space-between;gap:14px;min-width:min(100%,280px);padding:8px 10px;border:1px solid var(--md-sys-color-outline-variant);border-radius:8px;background:var(--md-sys-color-surface-container)}.rules-diagnostics__item>div{display:grid;gap:2px;min-width:0}.rules-diagnostics__item strong{color:var(--md-sys-color-on-surface);font-size:12px;line-height:1.25;overflow:hidden;text-overflow:ellipsis;white-space:nowrap}.rules-diagnostics__item span{color:var(--md-sys-color-on-surface-variant);font-size:11px}.rules-diagnostics__actions{flex:0 0 auto;display:flex;align-items:center;gap:8px}.rules-diagnostics__details{display:grid;gap:2px;margin:4px 0 0;padding-left:16px;color:var(--md-sys-color-on-surface-variant);font-size:11px;line-height:1.35}.rules-diagnostics__details li{overflow-wrap:anywhere}.rules-diagnostics__item--warn{border-color:color-mix(in srgb,var(--md-sys-color-tertiary) 52%,var(--md-sys-color-outline-variant))}.rules-diagnostics__item--error{border-color:var(--md-sys-color-error)}.rules-diagnostics__status{font-weight:600;margin-top:1px}.rules-diagnostics__action{min-width:0;height:28px;padding:0 10px;border-radius:999px;font-size:12px;line-height:1}.rules-diagnostics__action mat-icon{width:16px;height:16px;margin:0 4px 0 0;font-size:16px}.json-field{width:100%}.presentation-layout{display:grid;grid-template-columns:minmax(0,1fr);gap:20px;align-items:start}.presentation-controls{display:grid;grid-template-columns:repeat(auto-fit,minmax(min(100%,240px),1fr));gap:14px 18px}.control{display:flex;flex-direction:column}.control-span{grid-column:1/-1}.block-status{grid-column:1/-1;display:flex;gap:8px;align-items:flex-start;padding:10px 12px;border-radius:10px;background:color-mix(in srgb,var(--md-sys-color-primary-container) 35%,transparent);color:var(--md-sys-color-on-surface);font-size:12px;line-height:1.45}.block-status strong{min-width:112px;font-size:11px;letter-spacing:.04em;text-transform:uppercase;color:var(--md-sys-color-on-surface-variant)}.block-status--implicit{background:color-mix(in srgb,var(--md-sys-color-surface-variant) 42%,transparent);border:1px dashed var(--md-sys-color-outline)}.block-status--readonly{margin-bottom:12px}.block-status code{font-family:var(--md-ref-typeface-mono, \"Courier New\", monospace);font-size:11px}.control__label{font-size:12px;color:var(--md-sys-color-on-surface-variant);margin-bottom:6px}.toggle-group{max-width:100%;flex-wrap:wrap}.control--inline{grid-column:1/-1;display:flex;gap:16px;align-items:center}.presentation-preview{min-width:0;order:-1}.preview-card{border:1px solid var(--md-sys-color-outline);border-radius:12px;padding:14px;background:var(--md-sys-color-surface-container)}.preview-row{display:flex;gap:8px;padding:6px 0;border-bottom:1px dashed var(--md-sys-color-outline-variant)}.preview-row:last-child{border-bottom:none}.sr-only{position:absolute;width:1px;height:1px;padding:0;margin:-1px;overflow:hidden;clip:rect(0,0,0,0);white-space:nowrap;border:0}.presentation-preview .praxis-presentation__label{color:var(--md-sys-color-on-surface-variant);font-size:var(--pfx-pres-label-size, 12px)}.presentation-preview .praxis-presentation__value{min-width:0;overflow-wrap:anywhere;font-size:var(--pfx-pres-value-size, 16px);color:var(--md-sys-color-on-surface)}.presentation-preview .presentation-mode.pres-density-cozy .preview-row{padding:6px 0}.presentation-preview .presentation-mode.pres-density-compact .preview-row,.presentation-preview .presentation-mode.pres-compact .preview-row{padding:2px 0}.presentation-preview .presentation-mode.pres-label-left .preview-row{display:grid;grid-template-columns:var(--pfx-pres-label-width, 140px) 1fr;align-items:baseline;column-gap:10px}.presentation-preview .presentation-mode.pres-label-left .praxis-presentation__label{margin:0;text-align:var(--pfx-pres-label-align, start)}.presentation-preview .presentation-mode .praxis-presentation__value{text-align:var(--pfx-pres-value-align, start)}.presentation-preview h4{margin:0 0 8px;color:var(--md-sys-color-on-surface);font-size:1rem}.section-card:not(.section-card--json),.section-card:not(.section-card--json).mat-mdc-card,.section-card:not(.section-card--json).mat-mdc-card-outlined{border:none!important;border-width:0!important;border-radius:0!important;background:transparent!important;box-shadow:none!important;margin:0!important;padding:0!important;--mdc-outlined-card-outline-width: 0px;--mdc-outlined-card-outline-color: transparent;--mdc-elevated-card-container-color: transparent;--mdc-outlined-card-container-color: transparent}.section-card:not(.section-card--json)>mat-card-content,.section-card:not(.section-card--json)>.mat-mdc-card-content{padding:0!important}.section-card:not(.section-card--json)+.section-card:not(.section-card--json),.section-card:not(.section-card--json).mat-mdc-card+.section-card:not(.section-card--json).mat-mdc-card{padding-top:24px!important;border-top:1px solid color-mix(in srgb,var(--md-sys-color-outline-variant) 65%,transparent)!important}.section-header{display:flex;align-items:flex-start;justify-content:space-between;gap:12px;margin-bottom:16px}.tab-content--dense{padding:16px 20px 24px;gap:20px}.tab-content--dense .section-header{margin-bottom:10px}.tab-content--dense .form-row{margin-bottom:8px}.section-header h3{margin:0;font-size:1rem;font-weight:600;letter-spacing:-.01em;color:var(--md-sys-color-on-surface)}.text-caption{margin:4px 0 0;font-size:.85rem;line-height:1.45;color:var(--md-sys-color-on-surface-variant)}.section-header--compact{margin-bottom:10px}.section-body{display:block}.section-body--flex{flex:1;min-height:0;display:flex;flex-direction:column}.builder-header{padding:12px 16px;border-bottom:1px solid var(--md-sys-color-outline-variant);background:var(--md-sys-color-surface)}.builder-header h3{margin:0;font-size:1rem;color:var(--md-sys-color-on-surface)}.hint{margin:8px 0 0;padding:10px 12px;border-radius:8px;border:1px dashed color-mix(in srgb,var(--md-sys-color-outline-variant) 70%,transparent);background:color-mix(in srgb,var(--md-sys-color-surface-container-low) 75%,transparent);color:var(--md-sys-color-on-surface-variant)}.meta-card{display:grid;gap:8px;padding:12px 14px;border-radius:8px;border:1px solid color-mix(in srgb,var(--md-sys-color-outline-variant) 50%,transparent);background:color-mix(in srgb,var(--md-sys-color-surface-container-low) 70%,transparent);color:var(--md-sys-color-on-surface)}.meta-row{display:flex;align-items:center;justify-content:space-between;gap:12px;font-size:.875rem;color:var(--md-sys-color-on-surface-variant)}.meta-row strong{color:var(--md-sys-color-on-surface);font-weight:600}.runtime-contract-grid{display:grid;grid-template-columns:repeat(auto-fit,minmax(200px,1fr));gap:10px 14px}.runtime-contract-field{display:grid;gap:4px;padding:10px 12px;border-radius:8px;border:1px solid color-mix(in srgb,var(--md-sys-color-outline-variant) 45%,transparent);background:color-mix(in srgb,var(--md-sys-color-surface-container-low) 65%,transparent)}.runtime-contract-label{font-size:11px;font-weight:600;letter-spacing:.02em;color:var(--md-sys-color-on-surface-variant)}.runtime-contract-code{display:block;font-family:var(--md-ref-typeface-mono, \"Courier New\", monospace);font-size:12px;line-height:1.45;color:var(--md-sys-color-on-surface);word-break:break-word;white-space:normal}.command-rules-card,.command-rules-card.mat-mdc-card,.command-rules-card.mat-mdc-card-outlined{margin:0!important;padding:20px 16px 24px!important;min-width:0;border:none!important;border-top:1px solid color-mix(in srgb,var(--md-sys-color-outline-variant) 65%,transparent)!important;border-radius:0!important;background:transparent!important;box-shadow:none!important;--mdc-outlined-card-outline-width: 0px;--mdc-outlined-card-outline-color: transparent;--mdc-elevated-card-container-color: transparent;--mdc-outlined-card-container-color: transparent}.command-rules-card>mat-card-content,.command-rules-card>.mat-mdc-card-content{padding:12px 0 0!important}.command-rules-grid{display:grid;grid-template-columns:repeat(auto-fit,minmax(min(260px,100%),1fr));gap:12px;align-items:start;min-width:0}.command-rules-toolbar,.command-rules-options,.command-rules-actions{grid-column:1/-1;display:flex;align-items:center;gap:12px;flex-wrap:wrap}.command-rules-select{min-width:min(320px,100%)}.command-rules-full{grid-column:1/-1}.command-rule-condition-builder{min-height:420px;overflow:hidden;border:1px solid var(--md-sys-color-outline-variant);border-radius:8px;background:var(--md-sys-color-surface-container-low)}.command-rules-payload-fields{display:grid;grid-template-columns:repeat(auto-fit,minmax(min(220px,100%),1fr));gap:12px;min-width:0;padding:12px;border:1px dashed var(--md-sys-color-outline-variant);border-radius:8px;background:var(--md-sys-color-surface-container-low)}.command-rules-section-title{grid-column:1/-1;font-size:12px;font-weight:600;color:var(--md-sys-color-on-surface-variant);text-transform:uppercase}.command-rules-surface-editor{grid-column:1/-1}.command-rule-preview{display:grid;gap:8px;padding:12px;border:1px solid var(--md-sys-color-outline-variant);border-radius:8px;background:var(--md-sys-color-surface)}.command-rule-preview--invalid{border-color:var(--md-sys-color-error)}.command-rule-preview__row{display:grid;grid-template-columns:minmax(96px,.35fr) minmax(0,1fr);gap:8px;align-items:start;min-width:0}.command-rule-preview__row span{color:var(--md-sys-color-on-surface-variant);font-size:12px;font-weight:600}.command-rule-preview__row strong,.command-rule-preview__row code{min-width:0;overflow-wrap:anywhere}.command-rule-preview__diagnostics{display:flex;gap:8px;align-items:flex-start;color:var(--md-sys-color-on-surface-variant)}@container praxis-authoring-editor (max-width: 768px){.mobile-tab-selector{display:block}::ng-deep .mat-mdc-tab-group.config-tabs>.mat-mdc-tab-header{display:none}.tab-content{padding:12px}.json-tab-content{padding:8px}.section-card--json{min-height:auto}}.form-modes{display:flex;flex-direction:column;align-items:flex-start;gap:16px}.form-modes mat-button-toggle-group{max-width:100%;flex-wrap:wrap}.display-result{margin:0;padding-block:12px;color:var(--md-sys-color-on-surface);font:var(--md-sys-typescale-body-medium)}.presentation-preview .presentation-mode.pres-label-above .preview-row{flex-direction:column;gap:4px}.presentation-controls,.control{min-width:0}.control__hint{margin:6px 0 0;color:var(--md-sys-color-on-surface-variant);font:var(--md-sys-typescale-body-small, 400 12px/1.45 sans-serif)}.block-status{flex-wrap:wrap}:host{container-type:inline-size}@container (min-width: 900px){.presentation-layout{grid-template-columns:minmax(0,1fr) minmax(280px,.8fr)}.presentation-preview{order:1;position:sticky;top:16px}}.empty-state-fields{display:grid;align-items:start;grid-template-columns:repeat(auto-fit,minmax(min(100%,240px),1fr));gap:var(--p-space-3, 12px);margin-block-start:var(--p-space-4, 16px)}.empty-state-appearance summary{cursor:pointer;padding-block:var(--p-space-3, 12px);color:var(--md-sys-color-on-surface)}.empty-state-content{grid-template-columns:repeat(auto-fit,minmax(min(100%,320px),1fr))}.empty-state-description{grid-column:1/-1}.empty-state-content mat-form-field{min-width:0}.empty-state-icon-actions{display:inline-flex;align-items:center}\n"], dependencies: [{ kind: "ngmodule", type: CommonModule }, { kind: "directive", type: i1$2.NgClass, selector: "[ngClass]", inputs: ["class", "ngClass"] }, { kind: "directive", type: i1$2.NgIf, selector: "[ngIf]", inputs: ["ngIf", "ngIfThen", "ngIfElse"] }, { kind: "ngmodule", type: FormsModule }, { kind: "directive", type: i1$3.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: i1$3.NumberValueAccessor, selector: "input[type=number][formControlName],input[type=number][formControl],input[type=number][ngModel]" }, { kind: "directive", type: i1$3.NgControlStatus, selector: "[formControlName],[ngModel],[formControl]" }, { kind: "directive", type: i1$3.RequiredValidator, selector: ":not([type=checkbox])[required][formControlName],:not([type=checkbox])[required][formControl],:not([type=checkbox])[required][ngModel]", inputs: ["required"] }, { kind: "directive", type: i1$3.MinValidator, selector: "input[type=number][min][formControlName],input[type=number][min][formControl],input[type=number][min][ngModel]", inputs: ["min"] }, { kind: "directive", type: i1$3.NgModel, selector: "[ngModel]:not([formControlName]):not([formControl])", inputs: ["name", "disabled", "ngModel", "ngModelOptions"], outputs: ["ngModelChange"], exportAs: ["ngModel"] }, { kind: "ngmodule", type: MatTabsModule }, { kind: "component", type: i6$2.MatTab, selector: "mat-tab", inputs: ["disabled", "label", "aria-label", "aria-labelledby", "labelClass", "bodyClass", "id"], exportAs: ["matTab"] }, { kind: "component", type: i6$2.MatTabGroup, selector: "mat-tab-group", inputs: ["color", "fitInkBarToContent", "mat-stretch-tabs", "mat-align-tabs", "dynamicHeight", "selectedIndex", "headerPosition", "animationDuration", "contentTabIndex", "disablePagination", "disableRipple", "preserveContent", "backgroundColor", "aria-label", "aria-labelledby"], outputs: ["selectedIndexChange", "focusChange", "animationDone", "selectedTabChange"], exportAs: ["matTabGroup"] }, { kind: "ngmodule", type: MatIconModule }, { kind: "component", type: i4.MatIcon, selector: "mat-icon", inputs: ["color", "inline", "svgIcon", "fontSet", "fontIcon"], exportAs: ["matIcon"] }, { kind: "ngmodule", type: MatCardModule }, { kind: "component", type: i7$1.MatCard, selector: "mat-card", inputs: ["appearance"], exportAs: ["matCard"] }, { kind: "directive", type: i7$1.MatCardContent, selector: "mat-card-content" }, { kind: "directive", type: i7$1.MatCardSubtitle, selector: "mat-card-subtitle, [mat-card-subtitle], [matCardSubtitle]" }, { kind: "directive", type: i7$1.MatCardTitle, selector: "mat-card-title, [mat-card-title], [matCardTitle]" }, { kind: "ngmodule", type: MatButtonModule }, { kind: "component", type: i3.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: i3.MatIconButton, selector: "button[mat-icon-button], a[mat-icon-button], button[matIconButton], a[matIconButton]", exportAs: ["matButton", "matAnchor"] }, { kind: "ngmodule", type: MatFormFieldModule }, { kind: "component", type: i4$1.MatFormField, selector: "mat-form-field", inputs: ["hideRequiredMarker", "color", "floatLabel", "appearance", "subscriptSizing", "hintLabel"], exportAs: ["matFormField"] }, { kind: "directive", type: i4$1.MatLabel, selector: "mat-label" }, { kind: "directive", type: i4$1.MatHint, selector: "mat-hint", inputs: ["align", "id"] }, { kind: "directive", type: i4$1.MatError, selector: "mat-error, [matError]", inputs: ["id"] }, { kind: "directive", type: i4$1.MatPrefix, selector: "[matPrefix], [matIconPrefix], [matTextPrefix]", inputs: ["matTextPrefix"] }, { kind: "directive", type: i4$1.MatSuffix, selector: "[matSuffix], [matIconSuffix], [matTextSuffix]", inputs: ["matTextSuffix"] }, { kind: "ngmodule", type: MatSelectModule }, { kind: "component", type: i5$1.MatSelect, selector: "mat-select", inputs: ["aria-describedby", "panelClass", "disabled", "disableRipple", "tabIndex", "hideSingleSelectionIndicator", "placeholder", "required", "multiple", "disableOptionCentering", "compareWith", "value", "aria-label", "aria-labelledby", "errorStateMatcher", "typeaheadDebounceInterval", "sortComparator", "id", "panelWidth", "canSelectNullableOptions"], outputs: ["openedChange", "opened", "closed", "selectionChange", "valueChange"], exportAs: ["matSelect"] }, { kind: "component", type: i5$1.MatOption, selector: "mat-option", inputs: ["value", "id", "disabled"], outputs: ["onSelectionChange"], exportAs: ["matOption"] }, { kind: "ngmodule", type: MatInputModule }, { kind: "directive", type: i4$2.MatInput, selector: "input[matInput], textarea[matInput], select[matNativeControl], input[matNativeControl], textarea[matNativeControl]", inputs: ["disabled", "id", "placeholder", "name", "required", "type", "errorStateMatcher", "aria-describedby", "value", "readonly", "disabledInteractive"], exportAs: ["matInput"] }, { kind: "ngmodule", type: MatCheckboxModule }, { kind: "component", type: i12.MatCheckbox, selector: "mat-checkbox", inputs: ["aria-label", "aria-labelledby", "aria-describedby", "aria-expanded", "aria-controls", "aria-owns", "id", "required", "labelPosition", "name", "value", "disableRipple", "tabIndex", "color", "disabledInteractive", "checked", "disabled", "indeterminate"], outputs: ["change", "indeterminateChange"], exportAs: ["matCheckbox"] }, { kind: "ngmodule", type: MatSlideToggleModule }, { kind: "component", type: i5$2.MatSlideToggle, selector: "mat-slide-toggle", inputs: ["name", "id", "labelPosition", "aria-label", "aria-labelledby", "aria-describedby", "required", "color", "disabled", "disableRipple", "tabIndex", "checked", "hideIcon", "disabledInteractive"], outputs: ["change", "toggleChange"], exportAs: ["matSlideToggle"] }, { kind: "ngmodule", type: MatButtonToggleModule }, { kind: "directive", type: i7$2.MatButtonToggleGroup, selector: "mat-button-toggle-group", inputs: ["appearance", "name", "vertical", "value", "multiple", "disabled", "disabledInteractive", "hideSingleSelectionIndicator", "hideMultipleSelectionIndicator"], outputs: ["valueChange", "change"], exportAs: ["matButtonToggleGroup"] }, { kind: "component", type: i7$2.MatButtonToggle, selector: "mat-button-toggle", inputs: ["aria-label", "aria-labelledby", "id", "name", "value", "tabIndex", "disableRipple", "appearance", "checked", "disabled", "disabledInteractive"], outputs: ["change"], exportAs: ["matButtonToggle"] }, { kind: "ngmodule", type: MatTooltipModule }, { kind: "directive", type: i5.MatTooltip, selector: "[matTooltip]", inputs: ["matTooltipPosition", "matTooltipPositionAtOrigin", "matTooltipDisabled", "matTooltipShowDelay", "matTooltipHideDelay", "matTooltipTouchGestures", "matTooltip", "matTooltipClass"], exportAs: ["matTooltip"] }, { kind: "directive", type: PraxisIconDirective, selector: "mat-icon[praxisIcon]", inputs: ["praxisIcon"] }, { kind: "component", type: PraxisIconButtonComponent, selector: "button[praxisIconButton]", inputs: ["praxisIconButton", "size", "appearance", "presentation", "pressed", "busy"] }, { kind: "component", type: JsonConfigEditorComponent, selector: "form-json-config-editor", inputs: ["config", "document"], outputs: ["configChange", "documentChange", "validationChange", "editorEvent"] }, { kind: "component", type: LayoutEditorComponent, selector: "praxis-layout-editor", inputs: ["config"], outputs: ["configChange", "select"] }, { kind: "component", type: BehaviorEditorComponent, selector: "praxis-behavior-editor", inputs: ["config"], outputs: ["configChange"] }, { kind: "component", type: ActionsEditorComponent$1, selector: "praxis-actions-editor", inputs: ["config"], outputs: ["configChange", "validationChange"] }, { kind: "component", type: MessagesEditorComponent, selector: "praxis-messages-editor", inputs: ["config"], outputs: ["configChange"] }, { kind: "component", type: HooksEditorComponent, selector: "praxis-hooks-editor", inputs: ["config"], outputs: ["configChange"] }, { kind: "component", type: RulePropertiesPanelComponent, selector: "praxis-rule-properties-panel", inputs: ["rules", "visualBlockNodes"], outputs: ["rulesChange"] }, { kind: "component", type: PraxisVisualBuilder, selector: "praxis-visual-builder", inputs: ["mode", "config", "initialRules", "initialCondition"], outputs: ["rulesChanged", "conditionChanged", "exportRequested", "importRequested"] }, { kind: "component", type: CascadeManagerTabComponent, selector: "praxis-cascade-manager-tab", inputs: ["fields", "connections"], outputs: ["apply", "cancel"] }, { kind: "component", type: SurfaceOpenActionEditorComponent, selector: "praxis-surface-open-action-editor", inputs: ["value", "hostKind"], outputs: ["valueChange", "validationChange"] }, { kind: "pipe", type: i1$2.JsonPipe, name: "json" }] });
|
|
33445
33726
|
}
|
|
33446
33727
|
i0.ɵɵngDeclareClassMetadata({ minVersion: "12.0.0", version: "21.2.14", ngImport: i0, type: PraxisDynamicFormConfigEditor, decorators: [{
|
|
33447
33728
|
type: Component,
|
|
@@ -33471,7 +33752,7 @@ i0.ɵɵngDeclareClassMetadata({ minVersion: "12.0.0", version: "21.2.14", ngImpo
|
|
|
33471
33752
|
PraxisVisualBuilder,
|
|
33472
33753
|
CascadeManagerTabComponent,
|
|
33473
33754
|
SurfaceOpenActionEditorComponent,
|
|
33474
|
-
], providers: [FormConfigService, providePraxisI18nConfig(PRAXIS_DYNAMIC_FORM_I18N_CONFIG)], template: "<div class=\"mobile-tab-selector\">\n <mat-form-field appearance=\"outline\" class=\"mobile-tab-selector__field\">\n <mat-label>{{ tx('config.tabs.mobileLabel', 'Se\u00E7\u00E3o do editor') }}</mat-label>\n <mat-select [(ngModel)]=\"selectedConfigTabIndex\" data-testid=\"dynamic-form-config-editor-mobile-tabs\">\n @for (tab of configTabOptions; track tab.key) {\n <mat-option [value]=\"tab.index\">{{ tab.label }}</mat-option>\n }\n </mat-select>\n </mat-form-field>\n</div>\n\n<mat-tab-group [preserveContent]=\"true\" class=\"config-tabs\" data-testid=\"dynamic-form-config-editor-tabs\" [(selectedIndex)]=\"selectedConfigTabIndex\">\n <mat-tab [label]=\"configTabLabel('general')\">\n <div class=\"tab-content\" data-testid=\"config-tab-panel-geral\">\n <mat-card class=\"section-card\">\n <mat-card-content>\n <div class=\"section-header\">\n <div>\n <h3>{{ tx('config.general.title', 'Dados do formul\u00E1rio') }}</h3>\n <p class=\"text-caption\">{{ tx('config.general.subtitle', 'Defina o modo de dados e o contexto de edi\u00E7\u00E3o.') }}</p>\n </div>\n </div>\n <div class=\"form-modes\">\n <div class=\"control\">\n <label class=\"control__label\">{{ tx('config.general.inputMode.label') }}</label>\n <mat-button-toggle-group [ngModel]=\"inputMode\" (ngModelChange)=\"inputMode = $event; onInputModeChange()\" [attr.aria-label]=\"tx('config.general.inputMode.label')\">\n <mat-button-toggle value=\"create\">{{ tx('config.general.inputMode.create') }}</mat-button-toggle>\n <mat-button-toggle value=\"edit\">{{ tx('config.general.inputMode.edit') }}</mat-button-toggle>\n <mat-button-toggle value=\"view\">{{ tx('config.general.inputMode.view') }}</mat-button-toggle>\n </mat-button-toggle-group>\n </div>\n @if (supportsPresentationSettings) {\n <div class=\"control\">\n <label class=\"control__label\">{{ tx('config.general.displayMode.label') }}</label>\n <mat-button-toggle-group [ngModel]=\"displayMode\" (ngModelChange)=\"onDisplayModeChange($event)\" [attr.aria-label]=\"tx('config.general.displayMode.label')\">\n <mat-button-toggle value=\"automatic\">{{ tx('config.general.displayMode.automatic') }}</mat-button-toggle>\n <mat-button-toggle value=\"fields\">{{ tx('config.general.displayMode.fields') }}</mat-button-toggle>\n <mat-button-toggle value=\"presentation\">{{ tx('config.general.displayMode.presentation') }}</mat-button-toggle>\n </mat-button-toggle-group>\n </div>\n <p class=\"display-result\" role=\"status\">{{ tx(displayModeHint) }}</p>\n @if (inputMode !== 'view' && inputMode !== 'presentation' && inputMode !== 'dossier' && inputPresentationMode === true) {\n <button mat-stroked-button type=\"button\" (click)=\"useViewMode()\">{{ tx('config.general.displayMode.useView') }}</button>\n }\n <button mat-button type=\"button\" (click)=\"openPresentationStyle()\">{{ tx('config.general.displayMode.openStyle') }}</button>\n }\n </div>\n </mat-card-content>\n </mat-card>\n\n @if (supportsPresentationSettings) {\n <mat-card class=\"section-card\" data-testid=\"form-empty-state-settings\">\n <mat-card-content>\n <h3>{{ tx('config.emptyState.heading') }}</h3>\n <p class=\"text-caption\">{{ tx('config.emptyState.help') }}</p>\n <mat-slide-toggle [ngModel]=\"!!inputEmptyState\" (ngModelChange)=\"setEmptyStateEnabled($event)\">{{ tx('config.emptyState.enabled') }}</mat-slide-toggle>\n @if (inputMode !== 'view' && inputMode !== 'presentation' && inputMode !== 'dossier') { <p class=\"text-caption\">{{ tx('config.emptyState.viewOnly') }}</p> }\n @if (inputEmptyState; as empty) {\n <div class=\"empty-state-fields empty-state-content\">\n <mat-form-field appearance=\"outline\"><mat-label>{{ tx('config.emptyState.title') }}</mat-label><input matInput required [(ngModel)]=\"empty.title\" (ngModelChange)=\"onEmptyStateChange()\" /><mat-hint *ngIf=\"!empty.title?.trim()\">{{ tx('config.emptyState.titleRequired') }}</mat-hint></mat-form-field>\n <mat-form-field appearance=\"outline\">\n <mat-label>{{ tx('config.emptyState.icon') }}</mat-label>\n @if (empty.icon) { <mat-icon matPrefix [praxisIcon]=\"empty.icon\" aria-hidden=\"true\"></mat-icon> }\n <input matInput [(ngModel)]=\"empty.icon\" (ngModelChange)=\"onEmptyStateChange()\" />\n <span matSuffix class=\"empty-state-icon-actions\">\n <button mat-icon-button type=\"button\" [attr.aria-label]=\"tx('config.emptyState.pickIcon')\" (click)=\"pickEmptyStateIcon()\"><mat-icon aria-hidden=\"true\">search</mat-icon></button>\n @if (empty.icon) { <button mat-icon-button type=\"button\" [attr.aria-label]=\"tx('config.emptyState.clearIcon')\" (click)=\"empty.icon = ''; onEmptyStateChange()\"><mat-icon aria-hidden=\"true\">close</mat-icon></button> }\n </span>\n </mat-form-field>\n <mat-form-field appearance=\"outline\" class=\"empty-state-description\"><mat-label>{{ tx('config.emptyState.description') }}</mat-label><textarea matInput rows=\"2\" [(ngModel)]=\"empty.description\" (ngModelChange)=\"onEmptyStateChange()\"></textarea></mat-form-field>\n </div>\n <details class=\"empty-state-appearance\"><summary>{{ tx('config.emptyState.appearance') }}</summary><div class=\"empty-state-fields\">\n <mat-form-field appearance=\"outline\"><mat-label>{{ tx('config.emptyState.tone') }}</mat-label><mat-select [(ngModel)]=\"empty.tone\" (ngModelChange)=\"onEmptyStateChange()\"><mat-option [value]=\"undefined\">{{ tx('config.emptyState.inherit') }}</mat-option>@for (value of emptyStateOptions.tone; track value) { <mat-option [value]=\"value\">{{ tx('config.emptyState.option.' + value) }}</mat-option> }</mat-select></mat-form-field>\n <mat-form-field appearance=\"outline\"><mat-label>{{ tx('config.emptyState.variant') }}</mat-label><mat-select [(ngModel)]=\"empty.variant\" (ngModelChange)=\"onEmptyStateChange()\"><mat-option [value]=\"undefined\">{{ tx('config.emptyState.inherit') }}</mat-option>@for (value of emptyStateOptions.variant; track value) { <mat-option [value]=\"value\">{{ tx('config.emptyState.option.' + value) }}</mat-option> }</mat-select></mat-form-field>\n <mat-form-field appearance=\"outline\"><mat-label>{{ tx('config.emptyState.alignment') }}</mat-label><mat-select [(ngModel)]=\"empty.alignment\" (ngModelChange)=\"onEmptyStateChange()\"><mat-option [value]=\"undefined\">{{ tx('config.emptyState.inherit') }}</mat-option>@for (value of emptyStateOptions.alignment; track value) { <mat-option [value]=\"value\">{{ tx('config.emptyState.option.' + value) }}</mat-option> }</mat-select></mat-form-field>\n <mat-form-field appearance=\"outline\"><mat-label>{{ tx('config.emptyState.density') }}</mat-label><mat-select [(ngModel)]=\"empty.density\" (ngModelChange)=\"onEmptyStateChange()\"><mat-option [value]=\"undefined\">{{ tx('config.emptyState.inherit') }}</mat-option>@for (value of emptyStateOptions.density; track value) { <mat-option [value]=\"value\">{{ tx('config.emptyState.option.' + value) }}</mat-option> }</mat-select></mat-form-field>\n <mat-form-field appearance=\"outline\"><mat-label>{{ tx('config.emptyState.iconContainer') }}</mat-label><mat-select [(ngModel)]=\"empty.iconContainer\" (ngModelChange)=\"onEmptyStateChange()\"><mat-option [value]=\"undefined\">{{ tx('config.emptyState.inherit') }}</mat-option>@for (value of emptyStateOptions.iconContainer; track value) { <mat-option [value]=\"value\">{{ tx('config.emptyState.option.' + value) }}</mat-option> }</mat-select></mat-form-field>\n </div></details>\n }\n </mat-card-content>\n </mat-card>\n }\n\n @if (hasResolvedRuntimeContract()) {\n <mat-card\n class=\"section-card\"\n data-testid=\"config-tab-runtime-contract\"\n >\n <mat-card-content>\n <div class=\"section-header\">\n <div>\n <h3>{{ tx('config.general.runtimeContract.title', 'Contrato Runtime Resolvido') }}</h3>\n <p class=\"text-caption\">\n {{ tx('config.general.runtimeContract.subtitle', 'Visualiza\u00E7\u00E3o somente leitura do contrato backend resolvido pelo host atual.') }}\n </p>\n </div>\n </div>\n <div class=\"block-status block-status--readonly\">\n <strong>{{ tx('config.general.runtimeContract.runtimeLabel', 'Runtime') }}</strong>\n <span>\n {{ tx('config.general.runtimeContract.readonly', 'Esses valores v\u00EAm do host/runtime atual e n\u00E3o s\u00E3o persistidos em `bindings` nem em `contextSnapshot`.') }}\n </span>\n </div>\n <div class=\"runtime-contract-grid\">\n <div class=\"runtime-contract-field\">\n <span class=\"runtime-contract-label\">{{ tx('config.general.runtimeContract.schemaUrl', 'Schema URL') }}</span>\n <code class=\"runtime-contract-code\">{{ runtimeContract?.schemaUrl || '\u2014' }}</code>\n </div>\n <div class=\"runtime-contract-field\">\n <span class=\"runtime-contract-label\">{{ tx('config.general.runtimeContract.schemaSource', 'Origem do schema') }}</span>\n <strong>{{ describeRuntimeSource(runtimeContract?.schemaSource) }}</strong>\n </div>\n <div class=\"runtime-contract-field\">\n <span class=\"runtime-contract-label\">{{ tx('config.general.runtimeContract.submitMethod', 'Submit method') }}</span>\n <strong>{{ runtimeContract?.submitMethod || '\u2014' }}</strong>\n </div>\n <div class=\"runtime-contract-field\">\n <span class=\"runtime-contract-label\">{{ tx('config.general.runtimeContract.submitUrl', 'Submit URL') }}</span>\n <code class=\"runtime-contract-code\">{{ runtimeContract?.submitUrl || '\u2014' }}</code>\n </div>\n <div class=\"runtime-contract-field\">\n <span class=\"runtime-contract-label\">{{ tx('config.general.runtimeContract.submitSource', 'Origem do submit') }}</span>\n <strong>{{ describeRuntimeSource(runtimeContract?.submitSource) }}</strong>\n </div>\n </div>\n </mat-card-content>\n </mat-card>\n }\n </div>\n </mat-tab>\n <mat-tab [label]=\"configTabLabel('schema')\">\n <div class=\"tab-content\" data-testid=\"config-tab-panel-schema\">\n <mat-card class=\"section-card\">\n <mat-card-content>\n <div class=\"section-header\">\n <div>\n <h3>{{ tx('config.schema.title', 'Valida\u00E7\u00E3o de schema') }}</h3>\n <p class=\"text-caption\">{{ tx('config.schema.subtitle', 'Controle avisos quando o schema do servidor mudar.') }}</p>\n </div>\n </div>\n <div class=\"form-grid\">\n <div class=\"form-row\">\n <mat-form-field appearance=\"fill\" class=\"w-100\">\n <mat-label>{{ tx('config.schema.notify.label', 'Notificar quando desatualizado') }}</mat-label>\n <mat-select [(ngModel)]=\"schemaPrefs.notifyIfOutdated\" (ngModelChange)=\"onSchemaPrefsChange('schema-prefs-notify')\">\n <mat-option value=\"both\">{{ tx('config.schema.notify.both', 'Banner + Snackbar') }}</mat-option>\n <mat-option value=\"inline\">{{ tx('config.schema.notify.inline', 'Somente Banner') }}</mat-option>\n <mat-option value=\"snackbar\">{{ tx('config.schema.notify.snackbar', 'Somente Snackbar') }}</mat-option>\n <mat-option value=\"none\">{{ tx('config.schema.notify.none', 'Nenhum') }}</mat-option>\n </mat-select>\n </mat-form-field>\n </div>\n <div class=\"form-row\">\n <mat-form-field appearance=\"fill\" class=\"w-100\">\n <mat-label>{{ tx('config.schema.snooze.label', 'Intervalo de sil\u00EAncio (ms)') }}</mat-label>\n <input matInput type=\"number\" [(ngModel)]=\"schemaPrefs.snoozeMs\" (ngModelChange)=\"onSchemaPrefsChange('schema-prefs-snooze')\" />\n </mat-form-field>\n </div>\n <div class=\"form-row\">\n <mat-slide-toggle [(ngModel)]=\"schemaPrefs.autoOpenSettingsOnOutdated\" (ngModelChange)=\"onSchemaPrefsChange('schema-prefs-auto-open')\">\n {{ tx('config.schema.autoOpenSettings', 'Abrir configura\u00E7\u00F5es automaticamente') }}\n </mat-slide-toggle>\n </div>\n @if (serverMeta) {\n <div class=\"form-row\">\n <div class=\"meta-card\">\n <div class=\"meta-row\">\n <span>{{ tx('config.schema.meta.serverHash', 'Server hash') }}</span>\n <strong>{{ serverMeta.serverHash || '\u2014' }}</strong>\n </div>\n <div class=\"meta-row\">\n <span>{{ tx('config.schema.meta.lastVerifiedAt', '\u00DAltima verifica\u00E7\u00E3o') }}</span>\n <strong>{{ serverMeta.lastVerifiedAt || '\u2014' }}</strong>\n </div>\n </div>\n </div>\n }\n <div class=\"block-status\" [class.block-status--implicit]=\"!isSchemaPrefsBlockPersisted()\">\n <strong>{{ tx('config.schema.prefs.label', 'Schema Prefs') }}</strong>\n @if (isSchemaPrefsBlockPersisted()) {\n <span>{{ tx('config.schema.prefs.persisted', '`contextSnapshot.schemaPrefs` ser\u00E1 persistido no documento can\u00F4nico.') }}</span>\n } @else {\n {{ tx('config.schema.prefs.implicit', 'Bloco ausente no documento can\u00F4nico. Os controles exibem fallback visual e n\u00E3o ser\u00E3o salvos at\u00E9 voc\u00EA editar.') }}\n }\n </div>\n </div>\n </mat-card-content>\n </mat-card>\n </div>\n </mat-tab>\n <mat-tab [label]=\"configTabLabel('layout')\">\n <div class=\"tab-content tab-content--full\" data-testid=\"config-tab-panel-layout\">\n <div class=\"section-header section-header--compact\">\n <div>\n <h3>{{ tx('config.layout.title', 'Layout do formul\u00E1rio') }}</h3>\n <p class=\"text-caption\">{{ tx('config.layout.subtitle', 'Organize se\u00E7\u00F5es, linhas e campos com drag & drop.') }}</p>\n </div>\n </div>\n <div class=\"section-body section-body--flex\">\n <praxis-layout-editor [config]=\"editedConfig\" (configChange)=\"onConfigChange($event)\"\n (select)=\"onLayoutSelect($event)\"></praxis-layout-editor>\n </div>\n </div>\n </mat-tab>\n <mat-tab [label]=\"configTabLabel('hooks')\">\n <div class=\"tab-content\" data-testid=\"config-tab-panel-hooks\">\n <mat-card class=\"section-card\">\n <mat-card-content>\n <div class=\"section-header\">\n <div>\n <h3>{{ tx('config.hooks.title', 'Hooks de ciclo de vida') }}</h3>\n <p class=\"text-caption\">{{ tx('config.hooks.subtitle', 'Automatize a\u00E7\u00F5es nos eventos do formul\u00E1rio.') }}</p>\n </div>\n </div>\n <praxis-hooks-editor [config]=\"editedConfig\" (configChange)=\"onConfigChange($event)\"></praxis-hooks-editor>\n </mat-card-content>\n </mat-card>\n </div>\n </mat-tab>\n @if (isPresentationMode) {\n <mat-tab [label]=\"configTabLabel('presentation')\">\n <div class=\"tab-content\" data-testid=\"config-tab-panel-presentation\">\n <mat-card class=\"section-card\">\n <mat-card-content>\n <div class=\"section-header\">\n <div>\n <h3>{{ tx('config.presentation.title', 'Modo Apresenta\u00E7\u00E3o') }}</h3>\n <p class=\"text-caption\">{{ tx('config.presentation.subtitle', 'Configura\u00E7\u00F5es de exibi\u00E7\u00E3o aplicadas somente ao modo apresenta\u00E7\u00E3o.') }}</p>\n </div>\n </div>\n <p class=\"display-result\" role=\"status\">{{ tx(displayModeHint) }}</p>\n <div class=\"presentation-layout\">\n <div class=\"presentation-controls\">\n <div class=\"block-status control-span\" [class.block-status--implicit]=\"!isPresentationBlockPersisted()\">\n <strong>{{ tx('config.presentation.block.label', 'Presentation') }}</strong>\n @if (isPresentationBlockPersisted()) {\n <span>{{ tx('config.presentation.block.persisted', '`contextSnapshot.presentation` ser\u00E1 persistido no documento can\u00F4nico.') }}</span>\n } @else {\n {{ tx('config.presentation.block.implicit', 'Bloco ausente no documento can\u00F4nico. A pr\u00E9-visualiza\u00E7\u00E3o usa fallback local e n\u00E3o ser\u00E1 salva at\u00E9 voc\u00EA editar.') }}\n }\n </div>\n <div class=\"control\">\n <label class=\"control__label\">{{ tx('config.presentation.labelPosition.label', 'Posi\u00E7\u00E3o do r\u00F3tulo') }}</label>\n <mat-button-toggle-group [(ngModel)]=\"presentationPrefs.labelPosition\" (ngModelChange)=\"onPresentationPrefsChange('presentation-label-position')\" [attr.aria-label]=\"tx('config.presentation.labelPosition.ariaLabel', 'Posi\u00E7\u00E3o do r\u00F3tulo')\"\n class=\"toggle-group\">\n <mat-button-toggle value=\"above\">\n <mat-icon>view_stream</mat-icon>\n <span class=\"sr-only\">{{ tx('config.presentation.labelPosition.above', 'Acima') }}</span>\n </mat-button-toggle>\n <mat-button-toggle value=\"left\">\n <mat-icon>view_column</mat-icon>\n <span class=\"sr-only\">{{ tx('config.presentation.labelPosition.left', '\u00C0 esquerda') }}</span>\n </mat-button-toggle>\n </mat-button-toggle-group>\n </div>\n <div class=\"control control-span\">\n <label class=\"control__label\">{{ tx('config.presentation.density.label', 'Densidade') }}</label>\n <mat-button-toggle-group [(ngModel)]=\"presentationPrefs.density\" (ngModelChange)=\"onPresentationPrefsChange('presentation-density')\" [attr.aria-label]=\"tx('config.presentation.density.ariaLabel', 'Densidade')\"\n class=\"toggle-group\">\n <mat-button-toggle value=\"comfortable\">{{ tx('config.presentation.density.comfortable', 'Confort\u00E1vel') }}</mat-button-toggle>\n <mat-button-toggle value=\"cozy\">{{ tx('config.presentation.density.cozy', 'Intermedi\u00E1ria') }}</mat-button-toggle>\n <mat-button-toggle value=\"compact\">{{ tx('config.presentation.density.compact', 'Compacta') }}</mat-button-toggle>\n </mat-button-toggle-group>\n </div>\n <div class=\"control\">\n <label class=\"control__label\">{{ tx('config.presentation.labelAlign.label', 'Alinhamento do r\u00F3tulo') }}</label>\n <mat-button-toggle-group [(ngModel)]=\"presentationPrefs.labelAlign\" (ngModelChange)=\"onPresentationPrefsChange('presentation-label-align')\" [attr.aria-label]=\"tx('config.presentation.labelAlign.ariaLabel', 'Alinhamento do r\u00F3tulo')\"\n class=\"toggle-group\">\n <mat-button-toggle value=\"start\" [aria-label]=\"tx('config.presentation.align.start')\" [matTooltip]=\"tx('config.presentation.align.start')\"><mat-icon>format_align_left</mat-icon></mat-button-toggle>\n <mat-button-toggle value=\"center\" [aria-label]=\"tx('config.presentation.align.center')\" [matTooltip]=\"tx('config.presentation.align.center')\"><mat-icon>format_align_center</mat-icon></mat-button-toggle>\n <mat-button-toggle value=\"end\" [aria-label]=\"tx('config.presentation.align.end')\" [matTooltip]=\"tx('config.presentation.align.end')\"><mat-icon>format_align_right</mat-icon></mat-button-toggle>\n </mat-button-toggle-group>\n </div>\n <div class=\"control\">\n <label class=\"control__label\">{{ tx('config.presentation.valueAlign.label', 'Alinhamento do valor') }}</label>\n <mat-button-toggle-group [(ngModel)]=\"presentationPrefs.valueAlign\" (ngModelChange)=\"onPresentationPrefsChange('presentation-value-align')\" [attr.aria-label]=\"tx('config.presentation.valueAlign.ariaLabel', 'Alinhamento do valor')\"\n class=\"toggle-group\">\n <mat-button-toggle value=\"start\" [aria-label]=\"tx('config.presentation.align.start')\" [matTooltip]=\"tx('config.presentation.align.start')\"><mat-icon>format_align_left</mat-icon></mat-button-toggle>\n <mat-button-toggle value=\"center\" [aria-label]=\"tx('config.presentation.align.center')\" [matTooltip]=\"tx('config.presentation.align.center')\"><mat-icon>format_align_center</mat-icon></mat-button-toggle>\n <mat-button-toggle value=\"end\" [aria-label]=\"tx('config.presentation.align.end')\" [matTooltip]=\"tx('config.presentation.align.end')\"><mat-icon>format_align_right</mat-icon></mat-button-toggle>\n </mat-button-toggle-group>\n </div>\n <div class=\"control\">\n <mat-form-field appearance=\"fill\" class=\"w-100\">\n <mat-label>{{ tx('config.presentation.labelFontSize.label', 'Tamanho do r\u00F3tulo') }}</mat-label>\n <input matInput type=\"number\" min=\"10\" step=\"any\" [(ngModel)]=\"presentationPrefs.labelFontSize\" (ngModelChange)=\"onPresentationPrefsChange('presentation-label-font-size')\"\n [placeholder]=\"tx('config.presentation.labelFontSize.placeholder', 'ex.: 12')\" />\n <span matSuffix>px</span>\n </mat-form-field>\n </div>\n <div class=\"control\">\n <mat-form-field appearance=\"fill\" class=\"w-100\">\n <mat-label>{{ tx('config.presentation.valueFontSize.label', 'Tamanho do valor') }}</mat-label>\n <input matInput type=\"number\" min=\"10\" step=\"any\" [(ngModel)]=\"presentationPrefs.valueFontSize\" (ngModelChange)=\"onPresentationPrefsChange('presentation-value-font-size')\"\n [placeholder]=\"tx('config.presentation.valueFontSize.placeholder', 'ex.: 16')\" />\n <span matSuffix>px</span>\n </mat-form-field>\n </div>\n <div class=\"control\">\n <mat-form-field appearance=\"fill\" class=\"w-100\">\n <mat-label>{{ tx('config.presentation.labelWidth.label', 'Largura do r\u00F3tulo (label \u00E0 esquerda)') }}</mat-label>\n <input matInput type=\"number\" min=\"60\" [disabled]=\"presentationPrefs.labelPosition !== 'left'\" [(ngModel)]=\"presentationPrefs.labelWidth\" (ngModelChange)=\"onPresentationPrefsChange('presentation-label-width')\"\n [placeholder]=\"tx('config.presentation.labelWidth.placeholder', 'ex.: 140')\" />\n <span matSuffix>px</span>\n </mat-form-field>\n </div>\n <div class=\"control control--inline\">\n <mat-slide-toggle [(ngModel)]=\"presentationPrefs.compact\" (ngModelChange)=\"onPresentationPrefsChange('presentation-compact')\">\n {{ tx('config.presentation.options.compactMode', 'Modo compacto') }}\n </mat-slide-toggle>\n <mat-checkbox [(ngModel)]=\"truncatePreview\">\n {{ tx('config.presentation.options.truncateValues', 'Truncar valores') }}\n </mat-checkbox>\n </div>\n </div>\n <div class=\"presentation-preview\">\n <h4>{{ tx('config.presentation.preview.title', 'Pr\u00E9-visualiza\u00E7\u00E3o') }}</h4>\n <p class=\"text-caption\">{{ tx('config.presentation.preview.sampleHint') }}</p>\n <div class=\"preview-card\">\n <div class=\"praxis-dynamic-form presentation-mode\" [ngClass]=\"{\n 'pres-compact': !!presentationPrefs.compact,\n 'pres-label-left': presentationPrefs.labelPosition === 'left',\n 'pres-label-above': presentationPrefs.labelPosition === 'above',\n 'pres-density-compact': presentationPrefs.density === 'compact',\n 'pres-density-cozy': presentationPrefs.density === 'cozy'\n }\" [style.--pfx-pres-label-size]=\"(presentationPrefs.labelFontSize || 12) + 'px'\"\n [style.--pfx-pres-value-size]=\"(presentationPrefs.valueFontSize || 16) + 'px'\"\n [style.--pfx-pres-label-width]=\"(presentationPrefs.labelWidth || 140) + 'px'\"\n [style.--pfx-pres-label-align]=\"presentationPrefs.labelAlign || 'start'\"\n [style.--pfx-pres-value-align]=\"presentationPrefs.valueAlign || 'start'\">\n @for (item of previewItems; track item) {\n <div class=\"preview-row\">\n <span class=\"praxis-presentation__label\">{{ item.label }}</span>\n <span class=\"praxis-presentation__value\" [attr.title]=\"truncatePreview ? item.value : null\"\n [style.maxWidth]=\"truncatePreview ? '280px' : null\"\n [style.overflow]=\"truncatePreview ? 'hidden' : null\"\n [style.textOverflow]=\"truncatePreview ? 'ellipsis' : null\"\n [style.whiteSpace]=\"truncatePreview ? 'nowrap' : 'normal'\">\n {{ item.value }}\n </span>\n </div>\n }\n </div>\n </div>\n </div>\n </div>\n\n </mat-card-content>\n </mat-card>\n </div>\n </mat-tab>\n }\n <mat-tab [label]=\"configTabLabel('behavior')\">\n <div class=\"tab-content\" data-testid=\"config-tab-panel-comportamento\">\n <mat-card class=\"section-card\">\n <mat-card-content>\n <div class=\"section-header\">\n <div>\n <h3>{{ tx('config.behavior.title', 'Comportamento') }}</h3>\n <p class=\"text-caption\">{{ tx('config.behavior.subtitle', 'Ajuste valida\u00E7\u00F5es e respostas do formul\u00E1rio.') }}</p>\n </div>\n </div>\n <praxis-behavior-editor [config]=\"editedConfig\" (configChange)=\"onConfigChange($event)\"></praxis-behavior-editor>\n </mat-card-content>\n </mat-card>\n </div>\n </mat-tab>\n <mat-tab [label]=\"configTabLabel('hints')\">\n <div class=\"tab-content tab-content--dense\" data-testid=\"config-tab-panel-hints\">\n <mat-card class=\"section-card\">\n <mat-card-content>\n <div class=\"section-header\">\n <div>\n <h3>{{ tx('config.hints.title', 'Dicas dos modos') }}</h3>\n <p class=\"text-caption\">{{ tx('config.hints.subtitle', 'Personalize textos de apoio para modos de dados e estados de UI.') }}</p>\n </div>\n </div>\n <p class=\"text-caption\">{{ tx('config.hints.description', 'Personalize os textos usados como tooltip/hint para modos de dados e modos globais de UI.') }}</p>\n\n <div class=\"grid-2-cols grid-2-cols--compact\">\n <section>\n <h4>{{ tx('config.hints.dataModes.title', 'Modos de dados') }}</h4>\n <mat-form-field appearance=\"fill\" class=\"w-100\">\n <mat-label>{{ tx('config.hints.dataModes.create.label', 'Criar') }}</mat-label>\n <input matInput [(ngModel)]=\"editedConfig.hints!.dataModes.create\"\n (ngModelChange)=\"updateDirtyState('hints-data-create')\" [placeholder]=\"tx('config.hints.dataModes.create.placeholder', 'Ex.: Preencha os campos obrigat\u00F3rios.')\" />\n </mat-form-field>\n <mat-form-field appearance=\"fill\" class=\"w-100\">\n <mat-label>{{ tx('config.hints.dataModes.edit.label', 'Editar') }}</mat-label>\n <input matInput [(ngModel)]=\"editedConfig.hints!.dataModes.edit\"\n (ngModelChange)=\"updateDirtyState('hints-data-edit')\" [placeholder]=\"tx('config.hints.dataModes.edit.placeholder', 'Ex.: Revise os dados antes de salvar.')\" />\n </mat-form-field>\n <mat-form-field appearance=\"fill\" class=\"w-100\">\n <mat-label>{{ tx('config.hints.dataModes.view.label', 'Visualizar') }}</mat-label>\n <input matInput [(ngModel)]=\"editedConfig.hints!.dataModes.view\"\n (ngModelChange)=\"updateDirtyState('hints-data-view')\" [placeholder]=\"tx('config.hints.dataModes.view.placeholder', 'Ex.: Visualiza\u00E7\u00E3o somente leitura.')\" />\n </mat-form-field>\n </section>\n\n <section>\n <h4>{{ tx('config.hints.uiModes.title', 'Modos de UI') }}</h4>\n <mat-form-field appearance=\"fill\" class=\"w-100\">\n <mat-label>{{ tx('config.hints.uiModes.presentation.label', 'Apresenta\u00E7\u00E3o') }}</mat-label>\n <textarea matInput rows=\"2\" [(ngModel)]=\"editedConfig.hints!.uiModes.presentation\"\n (ngModelChange)=\"updateDirtyState('hints-ui-presentation')\" [placeholder]=\"tx('config.hints.uiModes.presentation.placeholder', 'Ex.: Modo compacto para leitura r\u00E1pida.')\"></textarea>\n </mat-form-field>\n <mat-form-field appearance=\"fill\" class=\"w-100\">\n <mat-label>{{ tx('config.hints.uiModes.readonly.label', 'Leitura (readonly)') }}</mat-label>\n <textarea matInput rows=\"2\" [(ngModel)]=\"editedConfig.hints!.uiModes.readonly\"\n (ngModelChange)=\"updateDirtyState('hints-ui-readonly')\" [placeholder]=\"tx('config.hints.uiModes.readonly.placeholder', 'Ex.: Campos bloqueados para edi\u00E7\u00E3o.')\"></textarea>\n </mat-form-field>\n <mat-form-field appearance=\"fill\" class=\"w-100\">\n <mat-label>{{ tx('config.hints.uiModes.disabled.label', 'Desabilitado') }}</mat-label>\n <textarea matInput rows=\"2\" [(ngModel)]=\"editedConfig.hints!.uiModes.disabled\"\n (ngModelChange)=\"updateDirtyState('hints-ui-disabled')\" [placeholder]=\"tx('config.hints.uiModes.disabled.placeholder', 'Ex.: Fun\u00E7\u00E3o indispon\u00EDvel no momento.')\"></textarea>\n </mat-form-field>\n <mat-form-field appearance=\"fill\" class=\"w-100\">\n <mat-label>{{ tx('config.hints.uiModes.visible.label', 'Vis\u00EDvel') }}</mat-label>\n <textarea matInput rows=\"2\" [(ngModel)]=\"editedConfig.hints!.uiModes.visible\"\n (ngModelChange)=\"updateDirtyState('hints-ui-visible')\" [placeholder]=\"tx('config.hints.uiModes.visible.placeholder', 'Ex.: Campo exibido conforme permiss\u00F5es.')\"></textarea>\n </mat-form-field>\n </section>\n </div>\n\n <section>\n <h4>{{ tx('config.helpPresentation.title', 'Apresenta\u00E7\u00E3o das ajudas dos campos') }}</h4>\n <p class=\"text-caption\">{{ tx('config.helpPresentation.description', 'Controle como hint/helpText dos campos aparece em formul\u00E1rios densos. Erros de valida\u00E7\u00E3o continuam inline.') }}</p>\n <div class=\"grid-3-cols\">\n <mat-form-field appearance=\"fill\" class=\"w-100\">\n <mat-label>{{ tx('config.helpPresentation.display.label', 'Exibi\u00E7\u00E3o') }}</mat-label>\n <mat-select [ngModel]=\"helpPresentationDraft.display\" (ngModelChange)=\"onHelpPresentationDisplayChange($event)\">\n <mat-option value=\"inline\">{{ tx('config.helpPresentation.display.inline', 'Inline') }}</mat-option>\n <mat-option value=\"popover\">{{ tx('config.helpPresentation.display.popover', '\u00CDcone de ajuda') }}</mat-option>\n <mat-option value=\"auto\">{{ tx('config.helpPresentation.display.auto', 'Autom\u00E1tica') }}</mat-option>\n <mat-option value=\"hidden\">{{ tx('config.helpPresentation.display.hidden', 'Oculta') }}</mat-option>\n </mat-select>\n </mat-form-field>\n <mat-form-field appearance=\"fill\" class=\"w-100\">\n <mat-label>{{ tx('config.helpPresentation.inlineMaxLength.label', 'Limite inline') }}</mat-label>\n <input matInput type=\"number\" min=\"0\" [ngModel]=\"helpPresentationDraft.inlineMaxLength\"\n (ngModelChange)=\"onHelpPresentationInlineMaxLengthChange($event)\" />\n </mat-form-field>\n <mat-form-field appearance=\"fill\" class=\"w-100\">\n <mat-label>{{ tx('config.helpPresentation.preferPopoverForControls.label', 'Preferir \u00EDcone em') }}</mat-label>\n <input matInput [ngModel]=\"getHelpPreferPopoverControlsText()\"\n (ngModelChange)=\"onHelpPreferPopoverControlsChange($event)\"\n [placeholder]=\"tx('config.helpPresentation.preferPopoverForControls.placeholder', 'toggle, checkbox, select')\" />\n </mat-form-field>\n </div>\n </section>\n\n <div class=\"actions-row\">\n <button mat-stroked-button color=\"primary\" type=\"button\" (click)=\"restoreHintsDefaults()\">\n <mat-icon>restore</mat-icon>\n {{ tx('config.hints.actions.restoreDefaults', 'Restaurar padr\u00F5es') }}\n </button>\n </div>\n </mat-card-content>\n </mat-card>\n </div>\n </mat-tab>\n <mat-tab [label]=\"configTabLabel('actions')\">\n <div class=\"tab-content\" data-testid=\"config-tab-panel-acoes\">\n <mat-card class=\"section-card\">\n <mat-card-content>\n <div class=\"section-header\">\n <div>\n <h3>{{ tx('config.actions.title', 'A\u00E7\u00F5es do formul\u00E1rio') }}</h3>\n <p class=\"text-caption\">{{ tx('config.actions.subtitle', 'Configure bot\u00F5es padr\u00E3o e a\u00E7\u00F5es customizadas.') }}</p>\n </div>\n </div>\n <praxis-actions-editor #actionsDraft [config]=\"editedConfig\" (validationChange)=\"onSurfaceDraftValidity(actionsDraft, $event)\" (configChange)=\"onConfigChange($event)\"></praxis-actions-editor>\n </mat-card-content>\n </mat-card>\n </div>\n </mat-tab>\n <mat-tab [label]=\"configTabLabel('rules')\">\n <div class=\"tab-content visual-builder-content\" data-testid=\"config-tab-panel-regras\">\n <div class=\"builder-header\">\n <div>\n <h3>{{ tx('config.rules.title', 'Regras visuais') }}</h3>\n <p class=\"text-caption\">{{ tx('config.rules.subtitle', 'Defina visibilidade, estilos e rea\u00E7\u00F5es baseadas em condi\u00E7\u00F5es.') }}</p>\n </div>\n </div>\n @if (ruleDiagnostics.length) {\n <div class=\"rules-diagnostics\" data-testid=\"rules-diagnostics-panel\">\n <div class=\"rules-diagnostics__summary\">\n <span class=\"rules-diagnostics__pill rules-diagnostics__pill--total\">\n {{ tx('config.rules.summary.total', '{{count}} regras', { count: ruleDiagnosticsSummary.total }) }}\n </span>\n @if (ruleDiagnosticsSummary.invalid) {\n <span class=\"rules-diagnostics__pill rules-diagnostics__pill--error\">\n {{ tx('config.rules.summary.invalid', '{{count}} inv\u00E1lidas', { count: ruleDiagnosticsSummary.invalid }) }}\n </span>\n }\n @if (ruleDiagnosticsSummary.unsupported) {\n <span class=\"rules-diagnostics__pill rules-diagnostics__pill--warn\">\n {{ tx('config.rules.summary.unsupported', '{{count}} com propriedades rejeitadas', { count: ruleDiagnosticsSummary.unsupported }) }}\n </span>\n }\n @if (ruleDiagnosticsSummary.runtimeOnly) {\n <span class=\"rules-diagnostics__pill rules-diagnostics__pill--warn\">\n {{ tx('config.rules.summary.runtimeOnly', '{{count}} runtime only', { count: ruleDiagnosticsSummary.runtimeOnly }) }}\n </span>\n }\n @if (ruleDiagnosticsSummary.pendingReview) {\n <span class=\"rules-diagnostics__pill rules-diagnostics__pill--warn\">\n {{ tx('config.rules.summary.pendingReview', '{{count}} pendentes de revis\u00E3o', { count: ruleDiagnosticsSummary.pendingReview }) }}\n </span>\n }\n </div>\n <div class=\"rules-diagnostics__list\" [attr.aria-label]=\"tx('config.rules.diagnostics.ariaLabel', 'Diagn\u00F3stico das regras')\">\n @for (diagnostic of ruleDiagnostics; track diagnostic) {\n <article class=\"rules-diagnostics__item\"\n [class.rules-diagnostics__item--error]=\"getRuleStatusTone(diagnostic) === 'error'\"\n [class.rules-diagnostics__item--warn]=\"getRuleStatusTone(diagnostic) === 'warn'\">\n <div>\n <strong>{{ diagnostic.ruleName || diagnostic.ruleId }}</strong>\n <span>\n {{ tx('config.rules.diagnostics.targetConditionSummary', '{{targets}} alvo(s) \u00B7 {{conditions}} campo(s) na condi\u00E7\u00E3o', { targets: diagnostic.targetRefs.length, conditions: diagnostic.conditionRefs.length }) }}\n </span>\n @if (getRuleDiagnosticDetails(diagnostic).length) {\n <ul class=\"rules-diagnostics__details\">\n @for (detail of getRuleDiagnosticDetails(diagnostic); track detail) {\n <li>{{ detail }}</li>\n }\n </ul>\n }\n </div>\n <div class=\"rules-diagnostics__actions\">\n <span class=\"rules-diagnostics__status\">{{ getRuleStatusLabel(diagnostic) }}</span>\n @if (canApplyRulePropertyFix(diagnostic)) {\n <button\n mat-stroked-button\n type=\"button\"\n class=\"rules-diagnostics__action\"\n [matTooltip]=\"tx('config.rules.actions.fix.tooltip', 'Aplicar whitelist e saneamento de propriedades nesta regra')\"\n (click)=\"applyRulePropertyFix(diagnostic.ruleId)\">\n <mat-icon aria-hidden=\"true\">auto_fix_high</mat-icon>\n {{ tx('config.rules.actions.fix', 'Corrigir') }}\n </button>\n }\n @if (diagnostic.status.includes('llm-generated-pending-review')) {\n <button\n mat-stroked-button\n type=\"button\"\n class=\"rules-diagnostics__action\"\n [disabled]=\"!canAcceptPendingLlmRule(diagnostic)\"\n [matTooltip]=\"canAcceptPendingLlmRule(diagnostic) ? tx('config.rules.actions.accept.tooltip.ready', 'Aceitar sugest\u00E3o e atualizar estado visual') : tx('config.rules.actions.accept.tooltip.blocked', 'Corrija alvo, condi\u00E7\u00E3o e propriedades antes de aceitar')\"\n (click)=\"acceptPendingLlmRule(diagnostic.ruleId)\">\n <mat-icon aria-hidden=\"true\">check</mat-icon>\n {{ tx('config.rules.actions.accept', 'Aceitar') }}\n </button>\n }\n @if (canOpenRuleJsonReview(diagnostic)) {\n <button\n mat-stroked-button\n type=\"button\"\n class=\"rules-diagnostics__action\"\n [matTooltip]=\"tx('config.rules.actions.reviewJson.tooltip', 'Abrir a aba JSON para revisar esta regra sem convers\u00E3o visual')\"\n (click)=\"openRuleJsonReview(diagnostic.ruleId)\">\n <mat-icon aria-hidden=\"true\">data_object</mat-icon>\n {{ tx('config.rules.actions.reviewJson', 'Ver JSON') }}\n </button>\n }\n </div>\n </article>\n }\n </div>\n </div>\n } @else {\n <div class=\"rules-diagnostics rules-diagnostics--empty\" data-testid=\"rules-diagnostics-empty\">\n {{ tx('config.rules.empty', 'Nenhuma regra definida ainda. Crie uma regra para ver alvos, condi\u00E7\u00E3o, propriedades e compatibilidade do builder.') }}\n </div>\n }\n <praxis-visual-builder [config]=\"ruleBuilderConfig\" [initialRules]=\"ruleBuilderState\"\n (rulesChanged)=\"onRulesChanged($event)\"></praxis-visual-builder>\n <praxis-rule-properties-panel\n [rules]=\"currentRules\"\n [visualBlockNodes]=\"visualBlockNodeOptions\"\n (rulesChange)=\"onRulePropertiesChanged($event)\"\n ></praxis-rule-properties-panel>\n <mat-card class=\"command-rules-card\" data-testid=\"form-command-rules-editor\">\n <mat-card-title>{{ tx('config.commandRules.title', 'Comandos condicionais') }}</mat-card-title>\n <mat-card-subtitle>{{ tx('config.commandRules.subtitle', 'Execute a\u00E7\u00F5es globais quando uma condi\u00E7\u00E3o do formul\u00E1rio for satisfeita.') }}</mat-card-subtitle>\n <mat-card-content>\n <div class=\"command-rules-grid\">\n <div class=\"command-rules-toolbar\">\n <mat-form-field appearance=\"fill\" class=\"command-rules-select\">\n <mat-label>{{ tx('config.commandRules.command.label', 'Comando') }}</mat-label>\n <mat-select [disabled]=\"hasInvalidSurfaceDraft\" [(ngModel)]=\"selectedCommandRuleId\" (selectionChange)=\"onCommandRuleSelectionChange()\">\n @for (rule of commandRules; track rule) {\n <mat-option [value]=\"rule.id\">\n {{ rule.id }}\n </mat-option>\n }\n </mat-select>\n </mat-form-field>\n <button mat-stroked-button type=\"button\" [disabled]=\"hasInvalidSurfaceDraft\" (click)=\"addCommandRule()\">\n <mat-icon aria-hidden=\"true\">add</mat-icon>\n {{ tx('config.commandRules.actions.add', 'Adicionar') }}\n </button>\n <button mat-stroked-button color=\"warn\" type=\"button\" (click)=\"deleteCommandRule()\" [disabled]=\"hasInvalidSurfaceDraft || !selectedCommandRuleId\">\n <mat-icon aria-hidden=\"true\">delete</mat-icon>\n {{ tx('config.commandRules.actions.remove', 'Remover') }}\n </button>\n </div>\n\n @if (selectedCommandRuleId) {\n <div class=\"command-rule-condition-builder command-rules-full\">\n <praxis-visual-builder\n mode=\"condition\"\n [config]=\"ruleBuilderConfig\"\n [initialCondition]=\"commandRuleCondition\"\n (conditionChanged)=\"onCommandConditionChanged($event)\"\n ></praxis-visual-builder>\n </div>\n }\n\n <mat-form-field appearance=\"fill\" class=\"command-rules-full\">\n <mat-label>{{ tx('config.commandRules.conditionJson.label', 'Condi\u00E7\u00E3o JSON Logic') }}</mat-label>\n <textarea\n matInput\n rows=\"5\"\n [(ngModel)]=\"commandRuleConditionJson\"\n [attr.aria-label]=\"tx('config.commandRules.conditionJson.ariaLabel', 'Condi\u00E7\u00E3o JSON Logic do comando condicional')\"\n ></textarea>\n </mat-form-field>\n\n <mat-form-field appearance=\"fill\">\n <mat-label>{{ tx('config.commandRules.globalAction.label', 'A\u00E7\u00E3o global') }}</mat-label>\n <mat-select [disabled]=\"hasInvalidSurfaceDraft\" [(ngModel)]=\"commandRuleActionId\" (selectionChange)=\"onCommandActionChange()\">\n @for (action of globalActionCatalog; track action) {\n <mat-option [value]=\"action.id\">\n {{ action.label || action.id }}\n </mat-option>\n }\n </mat-select>\n </mat-form-field>\n\n <mat-form-field appearance=\"fill\">\n <mat-label>{{ tx('config.commandRules.distinctBy.label', 'distinctBy') }}</mat-label>\n <input matInput [(ngModel)]=\"commandRuleDistinctBy\" [placeholder]=\"tx('config.commandRules.distinctBy.placeholder', 'ex.: idade')\" />\n </mat-form-field>\n\n @if (commandRuleActionSchema; as actionSchema) {\n <div\n class=\"command-rules-payload-fields command-rules-full\"\n >\n <div class=\"command-rules-section-title\">{{ tx('config.commandRules.structuredPayload.title', 'Payload estruturado') }}</div>\n @if (actionSchema.editorMode !== 'surface-open') {\n @for (field of actionSchema.fields; track field) {\n @if (shouldShowCommandActionField(field)) {\n @if (field.type === 'toggle') {\n <mat-slide-toggle\n [ngModel]=\"getCommandActionFieldValue(field)\"\n (ngModelChange)=\"onCommandActionFieldChange(field, $event)\"\n [ngModelOptions]=\"{ standalone: true }\"\n >\n {{ field.label }}\n </mat-slide-toggle>\n } @else {\n <mat-form-field appearance=\"fill\">\n <mat-label>{{ field.label }}</mat-label>\n @if (field.type === 'textarea' || field.type === 'json') {\n <textarea\n matInput\n [rows]=\"field.rows || (field.type === 'json' ? 3 : 2)\"\n [ngModel]=\"getCommandActionFieldValue(field)\"\n (ngModelChange)=\"onCommandActionFieldChange(field, $event)\"\n [ngModelOptions]=\"{ standalone: true }\"\n [placeholder]=\"field.placeholder || (field.type === 'json' ? '{ }' : '')\"\n [required]=\"isCommandActionFieldRequired(field)\"\n ></textarea>\n } @else {\n @if (field.type === 'select') {\n <mat-select\n [ngModel]=\"getCommandActionFieldValue(field)\"\n (ngModelChange)=\"onCommandActionFieldChange(field, $event)\"\n [ngModelOptions]=\"{ standalone: true }\"\n [required]=\"isCommandActionFieldRequired(field)\"\n >\n @for (option of field.options || []; track option) {\n <mat-option [value]=\"option.value\">\n {{ option.label }}\n </mat-option>\n }\n </mat-select>\n } @else {\n <input\n matInput\n [type]=\"field.type === 'number' ? 'number' : 'text'\"\n [ngModel]=\"getCommandActionFieldValue(field)\"\n (ngModelChange)=\"onCommandActionFieldChange(field, $event)\"\n [ngModelOptions]=\"{ standalone: true }\"\n [placeholder]=\"field.placeholder || ''\"\n [required]=\"isCommandActionFieldRequired(field)\"\n />\n }\n }\n @if (field.hint) {\n <mat-hint>{{ field.hint }}</mat-hint>\n }\n @if (hasCommandActionFieldError(field.key)) {\n <mat-error>\n {{ getCommandActionFieldError(field.key) }}\n </mat-error>\n }\n @if (!hasCommandActionFieldError(field.key) && isCommandActionFieldMissing(field)) {\n <mat-error>\n {{ tx('config.commandRules.validation.requiredField', 'Campo obrigat\u00F3rio.') }}\n </mat-error>\n }\n </mat-form-field>\n }\n }\n }\n } @else {\n <praxis-surface-open-action-editor #commandSurfaceDraft\n class=\"command-rules-surface-editor\"\n data-testid=\"form-command-rule-surface-open-editor\"\n [value]=\"commandRuleSurfaceOpenPayload\"\n hostKind=\"dynamic-form\"\n (valueChange)=\"onCommandSurfaceOpenPayloadChange($event)\"\n (validationChange)=\"onSurfaceDraftValidity(commandSurfaceDraft, $event)\"\n ></praxis-surface-open-action-editor>\n }\n </div>\n }\n\n <mat-form-field appearance=\"fill\" class=\"command-rules-full\">\n <mat-label>{{ tx('config.commandRules.advancedPayload.label', 'Payload JSON avan\u00E7ado') }}</mat-label>\n <textarea\n matInput\n rows=\"4\"\n [(ngModel)]=\"commandRulePayloadJson\"\n [attr.aria-label]=\"tx('config.commandRules.advancedPayload.ariaLabel', 'Payload JSON da a\u00E7\u00E3o global')\"\n ></textarea>\n </mat-form-field>\n\n <div class=\"command-rules-options\">\n <mat-slide-toggle [(ngModel)]=\"commandRuleDistinct\">{{ tx('config.commandRules.options.distinct', 'Evitar repeti\u00E7\u00E3o enquanto a condi\u00E7\u00E3o permanecer verdadeira') }}</mat-slide-toggle>\n <mat-slide-toggle [(ngModel)]=\"commandRuleRunOnInitialEvaluation\">{{ tx('config.commandRules.options.runOnInitialEvaluation', 'Executar tamb\u00E9m na avalia\u00E7\u00E3o inicial') }}</mat-slide-toggle>\n </div>\n\n @if (commandRuleAuthoringError) {\n <div class=\"preview-error command-rules-full\">\n <mat-icon aria-hidden=\"true\">warning</mat-icon>\n <span>{{ commandRuleAuthoringError }}</span>\n </div>\n }\n\n <div\n class=\"command-rule-preview command-rules-full\"\n [class.command-rule-preview--invalid]=\"commandRulePreview.state === 'invalid'\"\n data-testid=\"command-rule-preview\"\n >\n <div class=\"command-rules-section-title\">{{ tx('config.commandRules.preview.title', 'Preview do comando') }}</div>\n <div class=\"command-rule-preview__row\">\n <span>{{ tx('config.commandRules.preview.mode', 'Modo') }}</span>\n <strong>{{ commandRulePreview.executionMode }}</strong>\n </div>\n <div class=\"command-rule-preview__row\">\n <span>{{ tx('config.commandRules.preview.action', 'A\u00E7\u00E3o') }}</span>\n <strong>{{ commandRulePreview.actionId || '\u2014' }}</strong>\n </div>\n <div class=\"command-rule-preview__row\">\n <span>{{ tx('config.commandRules.preview.policy', 'Policy') }}</span>\n <code>{{ commandRulePreview.policy | json }}</code>\n </div>\n @if (commandRulePreview.diagnostics.length) {\n <div class=\"command-rule-preview__diagnostics\">\n <mat-icon aria-hidden=\"true\">{{ commandRulePreview.state === 'invalid' ? 'warning' : 'visibility' }}</mat-icon>\n <span>{{ commandRulePreview.diagnostics[0] }}</span>\n </div>\n }\n </div>\n\n <div class=\"command-rules-actions\">\n <button mat-flat-button color=\"primary\" type=\"button\" (click)=\"applyCommandRule()\">\n <mat-icon aria-hidden=\"true\">check</mat-icon>\n {{ tx('config.commandRules.actions.apply', 'Aplicar comando') }}\n </button>\n </div>\n </div>\n </mat-card-content>\n </mat-card>\n </div>\n </mat-tab>\n <mat-tab [label]=\"configTabLabel('cascades')\">\n <div class=\"tab-content\" data-testid=\"config-tab-panel-cascatas\">\n <mat-card class=\"section-card\">\n <mat-card-content>\n <div class=\"section-header\">\n <div>\n <h3>{{ tx('config.cascades.title', 'Depend\u00EAncias entre campos') }}</h3>\n <p class=\"text-caption\">{{ tx('config.cascades.subtitle', 'Configure cascatas e carregamento entre campos.') }}</p>\n </div>\n </div>\n <praxis-cascade-manager-tab [fields]=\"editedConfig.fieldMetadata || []\"\n (apply)=\"onCascadeApply($event)\"></praxis-cascade-manager-tab>\n </mat-card-content>\n </mat-card>\n </div>\n </mat-tab>\n <mat-tab [label]=\"configTabLabel('messages')\">\n <div class=\"tab-content\" data-testid=\"config-tab-panel-mensagens\">\n <mat-card class=\"section-card\">\n <mat-card-content>\n <div class=\"section-header\">\n <div>\n <h3>{{ tx('config.messages.title', 'Mensagens e feedback') }}</h3>\n <p class=\"text-caption\">{{ tx('config.messages.subtitle', 'Padronize textos de sucesso, erro e confirma\u00E7\u00F5es.') }}</p>\n </div>\n </div>\n <praxis-messages-editor [config]=\"editedConfig\" (configChange)=\"onConfigChange($event)\"></praxis-messages-editor>\n </mat-card-content>\n </mat-card>\n </div>\n </mat-tab>\n <mat-tab [label]=\"configTabLabel('navigation')\">\n <div class=\"tab-content\" data-testid=\"config-tab-panel-navegacao\">\n <mat-card class=\"section-card\">\n <mat-card-content>\n <div class=\"section-header\">\n <div>\n <h3>{{ tx('config.navigation.title', 'Navega\u00E7\u00E3o de retorno') }}</h3>\n <p class=\"text-caption\">{{ tx('config.navigation.subtitle', 'Defina o comportamento do bot\u00E3o Voltar em fluxos CRUD.') }}</p>\n </div>\n </div>\n <div class=\"form-grid\">\n <div class=\"form-row\">\n <mat-form-field appearance=\"fill\" class=\"w-100\">\n <mat-label>{{ tx('config.navigation.returnTo.label', 'Rota de retorno') }}</mat-label>\n <input matInput id=\"returnTo\" [(ngModel)]=\"backConfig!.returnTo\" (ngModelChange)=\"onBackConfigChange()\" [placeholder]=\"tx('config.navigation.returnTo.placeholder', '/funcionarios')\" />\n </mat-form-field>\n </div>\n <div class=\"form-row\">\n <mat-slide-toggle [(ngModel)]=\"backConfig!.confirmOnDirty\" (ngModelChange)=\"onBackConfigChange()\">\n {{ tx('config.navigation.confirmOnDirty.label', 'Confirmar ao sair com altera\u00E7\u00F5es') }}\n </mat-slide-toggle>\n </div>\n <div class=\"block-status\" [class.block-status--implicit]=\"!isBackConfigBlockPersisted()\">\n <strong>{{ tx('config.navigation.backConfig.label', 'Back Config') }}</strong>\n @if (isBackConfigBlockPersisted()) {\n <span>{{ tx('config.navigation.backConfig.persisted', '`contextSnapshot.backConfig` ser\u00E1 persistido no documento can\u00F4nico.') }}</span>\n } @else {\n {{ tx('config.navigation.backConfig.implicit', 'Bloco ausente no documento can\u00F4nico. Os valores exibidos s\u00E3o fallback visual e n\u00E3o ser\u00E3o salvos at\u00E9 voc\u00EA editar.') }}\n }\n </div>\n </div>\n <div class=\"section-help\">\n <span class=\"section-help__label\">{{ tx('config.navigation.note.label', 'Observa\u00E7\u00E3o:') }}</span>\n <button\n praxisIconButton=\"help_outline\"\n size=\"dense\"\n class=\"help-icon-button\"\n type=\"button\"\n [matTooltip]=\"tx('config.navigation.note.tooltip', 'Afeta o fluxo de navega\u00E7\u00E3o do CRUD e pode ser sobreposto por metadados do recurso.')\"\n matTooltipPosition=\"above\"\n >\n </button>\n </div>\n </mat-card-content>\n </mat-card>\n </div>\n </mat-tab>\n <mat-tab [label]=\"configTabLabel('json')\">\n <div class=\"tab-content json-tab-content\" data-testid=\"config-tab-panel-json\">\n <mat-card class=\"section-card section-card--json\">\n <mat-card-content>\n <div class=\"section-header\">\n <div>\n <h3>{{ tx('config.json.title', 'Configura\u00E7\u00E3o JSON') }}</h3>\n <p class=\"text-caption\">{{ tx('config.json.subtitle', 'Edi\u00E7\u00E3o avan\u00E7ada do documento can\u00F4nico de autoria do formul\u00E1rio.') }}</p>\n </div>\n </div>\n <form-json-config-editor [document]=\"jsonDocument\" (documentChange)=\"onJsonConfigChange($event)\"\n (validationChange)=\"onJsonValidationChange($event)\" (editorEvent)=\"onJsonEditorEvent($event)\">\n </form-json-config-editor>\n </mat-card-content>\n </mat-card>\n </div>\n </mat-tab>\n</mat-tab-group>\n", styles: [":host{container:praxis-authoring-editor/inline-size;display:flex;flex-direction:column;height:100%;min-width:0}.mobile-tab-selector{display:none;flex:0 0 auto;padding:8px 16px 0;background:var(--md-sys-color-surface)}.mobile-tab-selector__field{width:100%}.config-tabs{flex:1 1 auto;min-height:0;min-width:0}::ng-deep .mat-mdc-tab-group.config-tabs{display:flex;flex-direction:column}::ng-deep .mat-mdc-tab-group.config-tabs .mat-mdc-tab-body-wrapper{flex:1;min-height:0;min-width:0}::ng-deep .mat-mdc-tab-group.config-tabs .mat-mdc-tab-body-content{height:100%;overflow-y:auto;overflow-x:hidden;display:flex;flex-direction:column;padding:0!important}.tab-content{padding:16px 20px 20px;flex:1;min-width:0;box-sizing:border-box}.json-tab-content{min-width:0;padding:12px 16px 16px}.section-card--json{display:flex;flex:1;min-height:calc(100vh - 180px);border:1px solid var(--md-sys-color-outline-variant);background:var(--md-sys-color-surface-container-low)}.section-card--json>mat-card-content{display:flex;flex:1;min-width:0;min-height:0;flex-direction:column}.section-card--json form-json-config-editor{display:block;flex:1;min-width:0;min-height:0}.form-row{display:block;margin-bottom:12px}.form-grid{display:grid;gap:12px}.section-help{display:inline-flex;align-items:center;gap:8px;color:var(--md-sys-color-on-surface-variant);font-size:12px}.section-help__label{font-weight:500}.grid-2-cols{display:grid;grid-template-columns:repeat(auto-fit,minmax(260px,1fr));gap:16px}.grid-2-cols--compact{gap:12px}.w-100{width:100%}.visual-builder-content{padding:0!important;height:100%;min-width:0;overflow-y:auto;overflow-x:hidden;display:flex;flex-direction:column;gap:16px}.visual-builder-content>praxis-visual-builder{flex:0 0 auto;min-width:0;min-height:clamp(360px,48vh,560px)}.visual-builder-content>praxis-rule-properties-panel{flex:0 0 auto;display:block;min-width:0;padding:0 16px 24px;box-sizing:border-box}.rules-diagnostics{flex:0 0 auto;display:grid;gap:10px;padding:12px 16px;border-bottom:1px solid var(--md-sys-color-outline-variant);background:var(--md-sys-color-surface-container-low)}.rules-diagnostics--empty{color:var(--md-sys-color-on-surface-variant);font-size:12px;line-height:1.45}.rules-diagnostics__summary,.rules-diagnostics__list{display:flex;flex-wrap:wrap;gap:8px}.rules-diagnostics__pill{display:inline-flex;align-items:center;min-height:24px;padding:3px 9px;border-radius:999px;background:var(--md-sys-color-surface-container-high);color:var(--md-sys-color-on-surface);font-size:12px;font-weight:600}.rules-diagnostics__pill--warn{background:color-mix(in srgb,var(--md-sys-color-tertiary-container) 72%,transparent);color:var(--md-sys-color-on-tertiary-container)}.rules-diagnostics__pill--error{background:var(--md-sys-color-error-container);color:var(--md-sys-color-on-error-container)}.rules-diagnostics__item{display:flex;align-items:flex-start;justify-content:space-between;gap:14px;min-width:min(100%,280px);padding:8px 10px;border:1px solid var(--md-sys-color-outline-variant);border-radius:8px;background:var(--md-sys-color-surface-container)}.rules-diagnostics__item>div{display:grid;gap:2px;min-width:0}.rules-diagnostics__item strong{color:var(--md-sys-color-on-surface);font-size:12px;line-height:1.25;overflow:hidden;text-overflow:ellipsis;white-space:nowrap}.rules-diagnostics__item span{color:var(--md-sys-color-on-surface-variant);font-size:11px}.rules-diagnostics__actions{flex:0 0 auto;display:flex;align-items:center;gap:8px}.rules-diagnostics__details{display:grid;gap:2px;margin:4px 0 0;padding-left:16px;color:var(--md-sys-color-on-surface-variant);font-size:11px;line-height:1.35}.rules-diagnostics__details li{overflow-wrap:anywhere}.rules-diagnostics__item--warn{border-color:color-mix(in srgb,var(--md-sys-color-tertiary) 52%,var(--md-sys-color-outline-variant))}.rules-diagnostics__item--error{border-color:var(--md-sys-color-error)}.rules-diagnostics__status{font-weight:600;margin-top:1px}.rules-diagnostics__action{min-width:0;height:28px;padding:0 10px;border-radius:999px;font-size:12px;line-height:1}.rules-diagnostics__action mat-icon{width:16px;height:16px;margin:0 4px 0 0;font-size:16px}.json-field{width:100%}.presentation-layout{display:grid;grid-template-columns:minmax(0,1fr);gap:20px;align-items:start}.presentation-controls{display:grid;grid-template-columns:repeat(auto-fit,minmax(min(100%,240px),1fr));gap:14px 18px}.control{display:flex;flex-direction:column}.control-span{grid-column:1/-1}.block-status{grid-column:1/-1;display:flex;gap:8px;align-items:flex-start;padding:10px 12px;border-radius:10px;background:color-mix(in srgb,var(--md-sys-color-primary-container) 35%,transparent);color:var(--md-sys-color-on-surface);font-size:12px;line-height:1.45}.block-status strong{min-width:112px;font-size:11px;letter-spacing:.04em;text-transform:uppercase;color:var(--md-sys-color-on-surface-variant)}.block-status--implicit{background:color-mix(in srgb,var(--md-sys-color-surface-variant) 42%,transparent);border:1px dashed var(--md-sys-color-outline)}.block-status--readonly{margin-bottom:12px}.block-status code{font-family:var(--md-ref-typeface-mono, \"Courier New\", monospace);font-size:11px}.control__label{font-size:12px;color:var(--md-sys-color-on-surface-variant);margin-bottom:6px}.toggle-group{max-width:100%;flex-wrap:wrap}.control--inline{grid-column:1/-1;display:flex;gap:16px;align-items:center}.presentation-preview{min-width:0;order:-1}.preview-card{border:1px solid var(--md-sys-color-outline);border-radius:12px;padding:14px;background:var(--md-sys-color-surface-container)}.preview-row{display:flex;gap:8px;padding:6px 0;border-bottom:1px dashed var(--md-sys-color-outline-variant)}.preview-row:last-child{border-bottom:none}.sr-only{position:absolute;width:1px;height:1px;padding:0;margin:-1px;overflow:hidden;clip:rect(0,0,0,0);white-space:nowrap;border:0}.presentation-preview .praxis-presentation__label{color:var(--md-sys-color-on-surface-variant);font-size:var(--pfx-pres-label-size, 12px)}.presentation-preview .praxis-presentation__value{min-width:0;overflow-wrap:anywhere;font-size:var(--pfx-pres-value-size, 16px);color:var(--md-sys-color-on-surface)}.presentation-preview .presentation-mode.pres-density-cozy .preview-row{padding:6px 0}.presentation-preview .presentation-mode.pres-density-compact .preview-row,.presentation-preview .presentation-mode.pres-compact .preview-row{padding:2px 0}.presentation-preview .presentation-mode.pres-label-left .preview-row{display:grid;grid-template-columns:var(--pfx-pres-label-width, 140px) 1fr;align-items:baseline;column-gap:10px}.presentation-preview .presentation-mode.pres-label-left .praxis-presentation__label{margin:0;text-align:var(--pfx-pres-label-align, start)}.presentation-preview .presentation-mode .praxis-presentation__value{text-align:var(--pfx-pres-value-align, start)}.presentation-preview h4{margin:0 0 8px;color:var(--md-sys-color-on-surface);font-size:1rem}.section-card{border:1px solid var(--md-sys-color-outline-variant);background:var(--md-sys-color-surface-container);box-shadow:var(--md-sys-elevation-level1, none)}.section-header{display:flex;align-items:flex-start;justify-content:space-between;gap:12px;margin-bottom:12px}.tab-content--dense{padding:12px 16px 16px}.tab-content--dense .section-header,.tab-content--dense .form-row{margin-bottom:8px}.section-header h3{margin:0;font-size:1.05rem;color:var(--md-sys-color-on-surface)}.text-caption{margin:6px 0 0;font-size:.9rem;color:var(--md-sys-color-on-surface-variant)}.section-header--compact{margin-bottom:8px}.section-body{display:block}.section-body--flex{flex:1;min-height:0;display:flex;flex-direction:column}.builder-header{padding:12px 16px;border-bottom:1px solid var(--md-sys-color-outline-variant);background:var(--md-sys-color-surface)}.builder-header h3{margin:0;font-size:1rem;color:var(--md-sys-color-on-surface)}.hint{margin:8px 0 0;padding:10px 12px;border-radius:10px;border:1px dashed var(--md-sys-color-outline-variant);background:var(--md-sys-color-surface-container);color:var(--md-sys-color-on-surface-variant)}.meta-card{display:grid;gap:6px;padding:10px 12px;border-radius:10px;border:1px solid var(--md-sys-color-outline-variant);background:var(--md-sys-color-surface);color:var(--md-sys-color-on-surface)}.meta-row{display:flex;align-items:center;justify-content:space-between;gap:12px;font-size:.9rem;color:var(--md-sys-color-on-surface-variant)}.meta-row strong{color:var(--md-sys-color-on-surface);font-weight:600}.runtime-contract-grid{display:grid;grid-template-columns:repeat(auto-fit,minmax(220px,1fr));gap:12px}.runtime-contract-field{display:grid;gap:6px;padding:12px;border-radius:10px;border:1px solid var(--md-sys-color-outline-variant);background:var(--md-sys-color-surface)}.runtime-contract-label{font-size:12px;color:var(--md-sys-color-on-surface-variant)}.runtime-contract-code{display:block;font-family:var(--md-ref-typeface-mono, \"Courier New\", monospace);font-size:12px;line-height:1.45;color:var(--md-sys-color-on-surface);word-break:break-word;white-space:normal}.command-rules-card{margin:16px;min-width:0;border:1px solid var(--md-sys-color-outline-variant);background:var(--md-sys-color-surface-container)}.command-rules-grid{display:grid;grid-template-columns:repeat(auto-fit,minmax(min(260px,100%),1fr));gap:12px;align-items:start;min-width:0}.command-rules-toolbar,.command-rules-options,.command-rules-actions{grid-column:1/-1;display:flex;align-items:center;gap:12px;flex-wrap:wrap}.command-rules-select{min-width:min(320px,100%)}.command-rules-full{grid-column:1/-1}.command-rule-condition-builder{min-height:420px;overflow:hidden;border:1px solid var(--md-sys-color-outline-variant);border-radius:8px;background:var(--md-sys-color-surface-container-low)}.command-rules-payload-fields{display:grid;grid-template-columns:repeat(auto-fit,minmax(min(220px,100%),1fr));gap:12px;min-width:0;padding:12px;border:1px dashed var(--md-sys-color-outline-variant);border-radius:8px;background:var(--md-sys-color-surface-container-low)}.command-rules-section-title{grid-column:1/-1;font-size:12px;font-weight:600;color:var(--md-sys-color-on-surface-variant);text-transform:uppercase}.command-rules-surface-editor{grid-column:1/-1}.command-rule-preview{display:grid;gap:8px;padding:12px;border:1px solid var(--md-sys-color-outline-variant);border-radius:8px;background:var(--md-sys-color-surface)}.command-rule-preview--invalid{border-color:var(--md-sys-color-error)}.command-rule-preview__row{display:grid;grid-template-columns:minmax(96px,.35fr) minmax(0,1fr);gap:8px;align-items:start;min-width:0}.command-rule-preview__row span{color:var(--md-sys-color-on-surface-variant);font-size:12px;font-weight:600}.command-rule-preview__row strong,.command-rule-preview__row code{min-width:0;overflow-wrap:anywhere}.command-rule-preview__diagnostics{display:flex;gap:8px;align-items:flex-start;color:var(--md-sys-color-on-surface-variant)}@container praxis-authoring-editor (max-width: 768px){.mobile-tab-selector{display:block}::ng-deep .mat-mdc-tab-group.config-tabs>.mat-mdc-tab-header{display:none}.tab-content{padding:12px}.json-tab-content{padding:8px}.section-card--json{min-height:auto}}.form-modes{display:flex;flex-direction:column;align-items:flex-start;gap:16px}.form-modes mat-button-toggle-group{max-width:100%;flex-wrap:wrap}.display-result{margin:0;padding-block:12px;color:var(--md-sys-color-on-surface);font:var(--md-sys-typescale-body-medium)}.presentation-preview .presentation-mode.pres-label-above .preview-row{flex-direction:column;gap:4px}.presentation-controls,.control{min-width:0}.block-status{flex-wrap:wrap}:host{container-type:inline-size}@container (min-width: 900px){.presentation-layout{grid-template-columns:minmax(0,1fr) minmax(280px,.8fr)}.presentation-preview{order:1;position:sticky;top:16px}}.empty-state-fields{display:grid;align-items:start;grid-template-columns:repeat(auto-fit,minmax(min(100%,240px),1fr));gap:var(--p-space-3, 12px);margin-block-start:var(--p-space-4, 16px)}.empty-state-appearance summary{cursor:pointer;padding-block:var(--p-space-3, 12px);color:var(--md-sys-color-on-surface)}.empty-state-content{grid-template-columns:repeat(auto-fit,minmax(min(100%,320px),1fr))}.empty-state-description{grid-column:1/-1}.empty-state-content mat-form-field{min-width:0}.empty-state-icon-actions{display:inline-flex;align-items:center}\n"] }]
|
|
33755
|
+
], providers: [FormConfigService, providePraxisI18nConfig(PRAXIS_DYNAMIC_FORM_I18N_CONFIG)], template: "<div class=\"mobile-tab-selector\">\n <mat-form-field appearance=\"outline\" class=\"mobile-tab-selector__field\">\n <mat-label>{{ tx('config.tabs.mobileLabel', 'Se\u00E7\u00E3o do editor') }}</mat-label>\n <mat-select [(ngModel)]=\"selectedConfigTabIndex\" data-testid=\"dynamic-form-config-editor-mobile-tabs\">\n @for (tab of configTabOptions; track tab.key) {\n <mat-option [value]=\"tab.index\">{{ tab.label }}</mat-option>\n }\n </mat-select>\n </mat-form-field>\n</div>\n\n<mat-tab-group [preserveContent]=\"true\" class=\"config-tabs\" data-testid=\"dynamic-form-config-editor-tabs\" [(selectedIndex)]=\"selectedConfigTabIndex\">\n <mat-tab [label]=\"configTabLabel('general')\">\n <div class=\"tab-content\" data-testid=\"config-tab-panel-geral\">\n <mat-card class=\"section-card\">\n <mat-card-content>\n <div class=\"section-header\">\n <div>\n <h3>{{ tx('config.general.title', 'Dados do formul\u00E1rio') }}</h3>\n <p class=\"text-caption\">{{ tx('config.general.subtitle', 'Defina o modo de dados e o contexto de edi\u00E7\u00E3o.') }}</p>\n </div>\n </div>\n <div class=\"form-modes\">\n <div class=\"control\">\n <label class=\"control__label\">{{ tx('config.general.inputMode.label') }}</label>\n <mat-button-toggle-group [ngModel]=\"inputMode\" (ngModelChange)=\"inputMode = $event; onInputModeChange()\" [attr.aria-label]=\"tx('config.general.inputMode.label')\">\n <mat-button-toggle value=\"create\">{{ tx('config.general.inputMode.create') }}</mat-button-toggle>\n <mat-button-toggle value=\"edit\">{{ tx('config.general.inputMode.edit') }}</mat-button-toggle>\n <mat-button-toggle value=\"view\">{{ tx('config.general.inputMode.view') }}</mat-button-toggle>\n </mat-button-toggle-group>\n </div>\n <div class=\"control\">\n <label class=\"control__label\">{{ tx('config.general.layoutScope.label', 'Escopo de persist\u00EAncia do layout') }}</label>\n <mat-button-toggle-group\n data-testid=\"dynamic-form-layout-scope-toggle\"\n [ngModel]=\"inputLayoutScope\"\n (ngModelChange)=\"onLayoutScopeChange($event)\"\n [attr.aria-label]=\"tx('config.general.layoutScope.label', 'Escopo de persist\u00EAncia do layout')\">\n <mat-button-toggle value=\"shared\" data-testid=\"dynamic-form-layout-scope-shared\">\n {{ tx('config.general.layoutScope.shared', 'Todos os modos (Criar / Editar / Visualizar)') }}\n </mat-button-toggle>\n <mat-button-toggle value=\"mode-only\" data-testid=\"dynamic-form-layout-scope-mode-only\">\n {{ tx('config.general.layoutScope.modeOnly', 'Somente este modo ({{mode}})', { mode: tx('config.general.inputMode.' + inputMode, inputMode) }) }}\n </mat-button-toggle>\n </mat-button-toggle-group>\n <p class=\"control__hint\" data-testid=\"dynamic-form-layout-scope-hint\" role=\"status\">\n {{ inputLayoutScope === 'mode-only'\n ? tx('config.general.layoutScope.modeOnlyHint', 'Ao salvar, aplica este layout exclusivamente ao modo atual, sem alterar os demais modos.')\n : tx('config.general.layoutScope.sharedHint', 'Ao salvar, replica se\u00E7\u00F5es e grade nos demais modos que ainda compartilham layout.') }}\n </p>\n </div>\n @if (supportsPresentationSettings) {\n <div class=\"control\">\n <label class=\"control__label\">{{ tx('config.general.displayMode.label') }}</label>\n <mat-button-toggle-group [ngModel]=\"displayMode\" (ngModelChange)=\"onDisplayModeChange($event)\" [attr.aria-label]=\"tx('config.general.displayMode.label')\">\n <mat-button-toggle value=\"automatic\">{{ tx('config.general.displayMode.automatic') }}</mat-button-toggle>\n <mat-button-toggle value=\"fields\">{{ tx('config.general.displayMode.fields') }}</mat-button-toggle>\n <mat-button-toggle value=\"presentation\">{{ tx('config.general.displayMode.presentation') }}</mat-button-toggle>\n </mat-button-toggle-group>\n </div>\n <p class=\"display-result\" role=\"status\">{{ tx(displayModeHint) }}</p>\n @if (inputMode !== 'view' && inputMode !== 'presentation' && inputMode !== 'dossier' && inputPresentationMode === true) {\n <button mat-stroked-button type=\"button\" (click)=\"useViewMode()\">{{ tx('config.general.displayMode.useView') }}</button>\n }\n <button mat-button type=\"button\" (click)=\"openPresentationStyle()\">{{ tx('config.general.displayMode.openStyle') }}</button>\n }\n </div>\n </mat-card-content>\n </mat-card>\n\n @if (supportsPresentationSettings) {\n <mat-card class=\"section-card\" data-testid=\"form-empty-state-settings\">\n <mat-card-content>\n <h3>{{ tx('config.emptyState.heading') }}</h3>\n <p class=\"text-caption\">{{ tx('config.emptyState.help') }}</p>\n <mat-slide-toggle [ngModel]=\"!!inputEmptyState\" (ngModelChange)=\"setEmptyStateEnabled($event)\">{{ tx('config.emptyState.enabled') }}</mat-slide-toggle>\n @if (inputMode !== 'view' && inputMode !== 'presentation' && inputMode !== 'dossier') { <p class=\"text-caption\">{{ tx('config.emptyState.viewOnly') }}</p> }\n @if (inputEmptyState; as empty) {\n <div class=\"empty-state-fields empty-state-content\">\n <mat-form-field appearance=\"outline\"><mat-label>{{ tx('config.emptyState.title') }}</mat-label><input matInput required [(ngModel)]=\"empty.title\" (ngModelChange)=\"onEmptyStateChange()\" /><mat-hint *ngIf=\"!empty.title?.trim()\">{{ tx('config.emptyState.titleRequired') }}</mat-hint></mat-form-field>\n <mat-form-field appearance=\"outline\">\n <mat-label>{{ tx('config.emptyState.icon') }}</mat-label>\n @if (empty.icon) { <mat-icon matPrefix [praxisIcon]=\"empty.icon\" aria-hidden=\"true\"></mat-icon> }\n <input matInput [(ngModel)]=\"empty.icon\" (ngModelChange)=\"onEmptyStateChange()\" />\n <span matSuffix class=\"empty-state-icon-actions\">\n <button mat-icon-button type=\"button\" [attr.aria-label]=\"tx('config.emptyState.pickIcon')\" (click)=\"pickEmptyStateIcon()\"><mat-icon aria-hidden=\"true\">search</mat-icon></button>\n @if (empty.icon) { <button mat-icon-button type=\"button\" [attr.aria-label]=\"tx('config.emptyState.clearIcon')\" (click)=\"empty.icon = ''; onEmptyStateChange()\"><mat-icon aria-hidden=\"true\">close</mat-icon></button> }\n </span>\n </mat-form-field>\n <mat-form-field appearance=\"outline\" class=\"empty-state-description\"><mat-label>{{ tx('config.emptyState.description') }}</mat-label><textarea matInput rows=\"2\" [(ngModel)]=\"empty.description\" (ngModelChange)=\"onEmptyStateChange()\"></textarea></mat-form-field>\n </div>\n <details class=\"empty-state-appearance\"><summary>{{ tx('config.emptyState.appearance') }}</summary><div class=\"empty-state-fields\">\n <mat-form-field appearance=\"outline\"><mat-label>{{ tx('config.emptyState.tone') }}</mat-label><mat-select [(ngModel)]=\"empty.tone\" (ngModelChange)=\"onEmptyStateChange()\"><mat-option [value]=\"undefined\">{{ tx('config.emptyState.inherit') }}</mat-option>@for (value of emptyStateOptions.tone; track value) { <mat-option [value]=\"value\">{{ tx('config.emptyState.option.' + value) }}</mat-option> }</mat-select></mat-form-field>\n <mat-form-field appearance=\"outline\"><mat-label>{{ tx('config.emptyState.variant') }}</mat-label><mat-select [(ngModel)]=\"empty.variant\" (ngModelChange)=\"onEmptyStateChange()\"><mat-option [value]=\"undefined\">{{ tx('config.emptyState.inherit') }}</mat-option>@for (value of emptyStateOptions.variant; track value) { <mat-option [value]=\"value\">{{ tx('config.emptyState.option.' + value) }}</mat-option> }</mat-select></mat-form-field>\n <mat-form-field appearance=\"outline\"><mat-label>{{ tx('config.emptyState.alignment') }}</mat-label><mat-select [(ngModel)]=\"empty.alignment\" (ngModelChange)=\"onEmptyStateChange()\"><mat-option [value]=\"undefined\">{{ tx('config.emptyState.inherit') }}</mat-option>@for (value of emptyStateOptions.alignment; track value) { <mat-option [value]=\"value\">{{ tx('config.emptyState.option.' + value) }}</mat-option> }</mat-select></mat-form-field>\n <mat-form-field appearance=\"outline\"><mat-label>{{ tx('config.emptyState.density') }}</mat-label><mat-select [(ngModel)]=\"empty.density\" (ngModelChange)=\"onEmptyStateChange()\"><mat-option [value]=\"undefined\">{{ tx('config.emptyState.inherit') }}</mat-option>@for (value of emptyStateOptions.density; track value) { <mat-option [value]=\"value\">{{ tx('config.emptyState.option.' + value) }}</mat-option> }</mat-select></mat-form-field>\n <mat-form-field appearance=\"outline\"><mat-label>{{ tx('config.emptyState.iconContainer') }}</mat-label><mat-select [(ngModel)]=\"empty.iconContainer\" (ngModelChange)=\"onEmptyStateChange()\"><mat-option [value]=\"undefined\">{{ tx('config.emptyState.inherit') }}</mat-option>@for (value of emptyStateOptions.iconContainer; track value) { <mat-option [value]=\"value\">{{ tx('config.emptyState.option.' + value) }}</mat-option> }</mat-select></mat-form-field>\n </div></details>\n }\n </mat-card-content>\n </mat-card>\n }\n\n @if (hasResolvedRuntimeContract()) {\n <mat-card\n class=\"section-card\"\n data-testid=\"config-tab-runtime-contract\"\n >\n <mat-card-content>\n <div class=\"section-header\">\n <div>\n <h3>{{ tx('config.general.runtimeContract.title', 'Contrato Runtime Resolvido') }}</h3>\n <p class=\"text-caption\">\n {{ tx('config.general.runtimeContract.subtitle', 'Visualiza\u00E7\u00E3o somente leitura do contrato backend resolvido pelo host atual.') }}\n </p>\n </div>\n </div>\n <div class=\"block-status block-status--readonly\">\n <strong>{{ tx('config.general.runtimeContract.runtimeLabel', 'Runtime') }}</strong>\n <span>\n {{ tx('config.general.runtimeContract.readonly', 'Esses valores v\u00EAm do host/runtime atual e n\u00E3o s\u00E3o persistidos em `bindings` nem em `contextSnapshot`.') }}\n </span>\n </div>\n <div class=\"runtime-contract-grid\">\n <div class=\"runtime-contract-field\">\n <span class=\"runtime-contract-label\">{{ tx('config.general.runtimeContract.schemaUrl', 'Schema URL') }}</span>\n <code class=\"runtime-contract-code\">{{ runtimeContract?.schemaUrl || '\u2014' }}</code>\n </div>\n <div class=\"runtime-contract-field\">\n <span class=\"runtime-contract-label\">{{ tx('config.general.runtimeContract.schemaSource', 'Origem do schema') }}</span>\n <strong>{{ describeRuntimeSource(runtimeContract?.schemaSource) }}</strong>\n </div>\n <div class=\"runtime-contract-field\">\n <span class=\"runtime-contract-label\">{{ tx('config.general.runtimeContract.submitMethod', 'Submit method') }}</span>\n <strong>{{ runtimeContract?.submitMethod || '\u2014' }}</strong>\n </div>\n <div class=\"runtime-contract-field\">\n <span class=\"runtime-contract-label\">{{ tx('config.general.runtimeContract.submitUrl', 'Submit URL') }}</span>\n <code class=\"runtime-contract-code\">{{ runtimeContract?.submitUrl || '\u2014' }}</code>\n </div>\n <div class=\"runtime-contract-field\">\n <span class=\"runtime-contract-label\">{{ tx('config.general.runtimeContract.submitSource', 'Origem do submit') }}</span>\n <strong>{{ describeRuntimeSource(runtimeContract?.submitSource) }}</strong>\n </div>\n </div>\n </mat-card-content>\n </mat-card>\n }\n </div>\n </mat-tab>\n <mat-tab [label]=\"configTabLabel('schema')\">\n <div class=\"tab-content\" data-testid=\"config-tab-panel-schema\">\n <mat-card class=\"section-card\">\n <mat-card-content>\n <div class=\"section-header\">\n <div>\n <h3>{{ tx('config.schema.title', 'Valida\u00E7\u00E3o de schema') }}</h3>\n <p class=\"text-caption\">{{ tx('config.schema.subtitle', 'Controle avisos quando o schema do servidor mudar.') }}</p>\n </div>\n </div>\n <div class=\"form-grid\">\n <div class=\"form-row\">\n <mat-form-field appearance=\"outline\" class=\"w-100\">\n <mat-label>{{ tx('config.schema.notify.label', 'Notificar quando desatualizado') }}</mat-label>\n <mat-select [(ngModel)]=\"schemaPrefs.notifyIfOutdated\" (ngModelChange)=\"onSchemaPrefsChange('schema-prefs-notify')\">\n <mat-option value=\"both\">{{ tx('config.schema.notify.both', 'Banner + Snackbar') }}</mat-option>\n <mat-option value=\"inline\">{{ tx('config.schema.notify.inline', 'Somente Banner') }}</mat-option>\n <mat-option value=\"snackbar\">{{ tx('config.schema.notify.snackbar', 'Somente Snackbar') }}</mat-option>\n <mat-option value=\"none\">{{ tx('config.schema.notify.none', 'Nenhum') }}</mat-option>\n </mat-select>\n </mat-form-field>\n </div>\n <div class=\"form-row\">\n <mat-form-field appearance=\"outline\" class=\"w-100\">\n <mat-label>{{ tx('config.schema.snooze.label', 'Intervalo de sil\u00EAncio (ms)') }}</mat-label>\n <input matInput type=\"number\" [(ngModel)]=\"schemaPrefs.snoozeMs\" (ngModelChange)=\"onSchemaPrefsChange('schema-prefs-snooze')\" />\n </mat-form-field>\n </div>\n <div class=\"form-row\">\n <mat-slide-toggle [(ngModel)]=\"schemaPrefs.autoOpenSettingsOnOutdated\" (ngModelChange)=\"onSchemaPrefsChange('schema-prefs-auto-open')\">\n {{ tx('config.schema.autoOpenSettings', 'Abrir configura\u00E7\u00F5es automaticamente') }}\n </mat-slide-toggle>\n </div>\n @if (serverMeta) {\n <div class=\"form-row\">\n <div class=\"meta-card\">\n <div class=\"meta-row\">\n <span>{{ tx('config.schema.meta.serverHash', 'Server hash') }}</span>\n <strong>{{ serverMeta.serverHash || '\u2014' }}</strong>\n </div>\n <div class=\"meta-row\">\n <span>{{ tx('config.schema.meta.lastVerifiedAt', '\u00DAltima verifica\u00E7\u00E3o') }}</span>\n <strong>{{ serverMeta.lastVerifiedAt || '\u2014' }}</strong>\n </div>\n </div>\n </div>\n }\n <div class=\"block-status\" [class.block-status--implicit]=\"!isSchemaPrefsBlockPersisted()\">\n <strong>{{ tx('config.schema.prefs.label', 'Schema Prefs') }}</strong>\n @if (isSchemaPrefsBlockPersisted()) {\n <span>{{ tx('config.schema.prefs.persisted', '`contextSnapshot.schemaPrefs` ser\u00E1 persistido no documento can\u00F4nico.') }}</span>\n } @else {\n {{ tx('config.schema.prefs.implicit', 'Bloco ausente no documento can\u00F4nico. Os controles exibem fallback visual e n\u00E3o ser\u00E3o salvos at\u00E9 voc\u00EA editar.') }}\n }\n </div>\n </div>\n </mat-card-content>\n </mat-card>\n </div>\n </mat-tab>\n <mat-tab [label]=\"configTabLabel('layout')\">\n <div class=\"tab-content tab-content--full\" data-testid=\"config-tab-panel-layout\">\n <div class=\"section-body section-body--flex\">\n <praxis-layout-editor [config]=\"editedConfig\" (configChange)=\"onConfigChange($event)\"\n (select)=\"onLayoutSelect($event)\"></praxis-layout-editor>\n </div>\n </div>\n </mat-tab>\n <mat-tab [label]=\"configTabLabel('hooks')\">\n <div class=\"tab-content\" data-testid=\"config-tab-panel-hooks\">\n <mat-card class=\"section-card\">\n <mat-card-content>\n <div class=\"section-header\">\n <div>\n <h3>{{ tx('config.hooks.title', 'Hooks de ciclo de vida') }}</h3>\n <p class=\"text-caption\">{{ tx('config.hooks.subtitle', 'Automatize a\u00E7\u00F5es nos eventos do formul\u00E1rio.') }}</p>\n </div>\n </div>\n <praxis-hooks-editor [config]=\"editedConfig\" (configChange)=\"onConfigChange($event)\"></praxis-hooks-editor>\n </mat-card-content>\n </mat-card>\n </div>\n </mat-tab>\n @if (isPresentationMode) {\n <mat-tab [label]=\"configTabLabel('presentation')\">\n <div class=\"tab-content\" data-testid=\"config-tab-panel-presentation\">\n <mat-card class=\"section-card\">\n <mat-card-content>\n <div class=\"section-header\">\n <div>\n <h3>{{ tx('config.presentation.title', 'Modo Apresenta\u00E7\u00E3o') }}</h3>\n <p class=\"text-caption\">{{ tx('config.presentation.subtitle', 'Configura\u00E7\u00F5es de exibi\u00E7\u00E3o aplicadas somente ao modo apresenta\u00E7\u00E3o.') }}</p>\n </div>\n </div>\n <p class=\"display-result\" role=\"status\">{{ tx(displayModeHint) }}</p>\n <div class=\"presentation-layout\">\n <div class=\"presentation-controls\">\n <div class=\"block-status control-span\" [class.block-status--implicit]=\"!isPresentationBlockPersisted()\">\n <strong>{{ tx('config.presentation.block.label', 'Presentation') }}</strong>\n @if (isPresentationBlockPersisted()) {\n <span>{{ tx('config.presentation.block.persisted', '`contextSnapshot.presentation` ser\u00E1 persistido no documento can\u00F4nico.') }}</span>\n } @else {\n {{ tx('config.presentation.block.implicit', 'Bloco ausente no documento can\u00F4nico. A pr\u00E9-visualiza\u00E7\u00E3o usa fallback local e n\u00E3o ser\u00E1 salva at\u00E9 voc\u00EA editar.') }}\n }\n </div>\n <div class=\"control\">\n <label class=\"control__label\">{{ tx('config.presentation.labelPosition.label', 'Posi\u00E7\u00E3o do r\u00F3tulo') }}</label>\n <mat-button-toggle-group [(ngModel)]=\"presentationPrefs.labelPosition\" (ngModelChange)=\"onPresentationPrefsChange('presentation-label-position')\" [attr.aria-label]=\"tx('config.presentation.labelPosition.ariaLabel', 'Posi\u00E7\u00E3o do r\u00F3tulo')\"\n class=\"toggle-group\">\n <mat-button-toggle value=\"above\">\n <mat-icon>view_stream</mat-icon>\n <span class=\"sr-only\">{{ tx('config.presentation.labelPosition.above', 'Acima') }}</span>\n </mat-button-toggle>\n <mat-button-toggle value=\"left\">\n <mat-icon>view_column</mat-icon>\n <span class=\"sr-only\">{{ tx('config.presentation.labelPosition.left', '\u00C0 esquerda') }}</span>\n </mat-button-toggle>\n </mat-button-toggle-group>\n </div>\n <div class=\"control control-span\">\n <label class=\"control__label\">{{ tx('config.presentation.density.label', 'Densidade') }}</label>\n <mat-button-toggle-group [(ngModel)]=\"presentationPrefs.density\" (ngModelChange)=\"onPresentationPrefsChange('presentation-density')\" [attr.aria-label]=\"tx('config.presentation.density.ariaLabel', 'Densidade')\"\n class=\"toggle-group\">\n <mat-button-toggle value=\"comfortable\">{{ tx('config.presentation.density.comfortable', 'Confort\u00E1vel') }}</mat-button-toggle>\n <mat-button-toggle value=\"cozy\">{{ tx('config.presentation.density.cozy', 'Intermedi\u00E1ria') }}</mat-button-toggle>\n <mat-button-toggle value=\"compact\">{{ tx('config.presentation.density.compact', 'Compacta') }}</mat-button-toggle>\n </mat-button-toggle-group>\n </div>\n <div class=\"control\">\n <label class=\"control__label\">{{ tx('config.presentation.labelAlign.label', 'Alinhamento do r\u00F3tulo') }}</label>\n <mat-button-toggle-group [(ngModel)]=\"presentationPrefs.labelAlign\" (ngModelChange)=\"onPresentationPrefsChange('presentation-label-align')\" [attr.aria-label]=\"tx('config.presentation.labelAlign.ariaLabel', 'Alinhamento do r\u00F3tulo')\"\n class=\"toggle-group\">\n <mat-button-toggle value=\"start\" [aria-label]=\"tx('config.presentation.align.start')\" [matTooltip]=\"tx('config.presentation.align.start')\"><mat-icon>format_align_left</mat-icon></mat-button-toggle>\n <mat-button-toggle value=\"center\" [aria-label]=\"tx('config.presentation.align.center')\" [matTooltip]=\"tx('config.presentation.align.center')\"><mat-icon>format_align_center</mat-icon></mat-button-toggle>\n <mat-button-toggle value=\"end\" [aria-label]=\"tx('config.presentation.align.end')\" [matTooltip]=\"tx('config.presentation.align.end')\"><mat-icon>format_align_right</mat-icon></mat-button-toggle>\n </mat-button-toggle-group>\n </div>\n <div class=\"control\">\n <label class=\"control__label\">{{ tx('config.presentation.valueAlign.label', 'Alinhamento do valor') }}</label>\n <mat-button-toggle-group [(ngModel)]=\"presentationPrefs.valueAlign\" (ngModelChange)=\"onPresentationPrefsChange('presentation-value-align')\" [attr.aria-label]=\"tx('config.presentation.valueAlign.ariaLabel', 'Alinhamento do valor')\"\n class=\"toggle-group\">\n <mat-button-toggle value=\"start\" [aria-label]=\"tx('config.presentation.align.start')\" [matTooltip]=\"tx('config.presentation.align.start')\"><mat-icon>format_align_left</mat-icon></mat-button-toggle>\n <mat-button-toggle value=\"center\" [aria-label]=\"tx('config.presentation.align.center')\" [matTooltip]=\"tx('config.presentation.align.center')\"><mat-icon>format_align_center</mat-icon></mat-button-toggle>\n <mat-button-toggle value=\"end\" [aria-label]=\"tx('config.presentation.align.end')\" [matTooltip]=\"tx('config.presentation.align.end')\"><mat-icon>format_align_right</mat-icon></mat-button-toggle>\n </mat-button-toggle-group>\n </div>\n <div class=\"control\">\n <mat-form-field appearance=\"outline\" class=\"w-100\">\n <mat-label>{{ tx('config.presentation.labelFontSize.label', 'Tamanho do r\u00F3tulo') }}</mat-label>\n <input matInput type=\"number\" min=\"10\" step=\"any\" [(ngModel)]=\"presentationPrefs.labelFontSize\" (ngModelChange)=\"onPresentationPrefsChange('presentation-label-font-size')\"\n [placeholder]=\"tx('config.presentation.labelFontSize.placeholder', 'ex.: 12')\" />\n <span matSuffix>px</span>\n </mat-form-field>\n </div>\n <div class=\"control\">\n <mat-form-field appearance=\"outline\" class=\"w-100\">\n <mat-label>{{ tx('config.presentation.valueFontSize.label', 'Tamanho do valor') }}</mat-label>\n <input matInput type=\"number\" min=\"10\" step=\"any\" [(ngModel)]=\"presentationPrefs.valueFontSize\" (ngModelChange)=\"onPresentationPrefsChange('presentation-value-font-size')\"\n [placeholder]=\"tx('config.presentation.valueFontSize.placeholder', 'ex.: 16')\" />\n <span matSuffix>px</span>\n </mat-form-field>\n </div>\n <div class=\"control\">\n <mat-form-field appearance=\"outline\" class=\"w-100\">\n <mat-label>{{ tx('config.presentation.labelWidth.label', 'Largura do r\u00F3tulo (label \u00E0 esquerda)') }}</mat-label>\n <input matInput type=\"number\" min=\"60\" [disabled]=\"presentationPrefs.labelPosition !== 'left'\" [(ngModel)]=\"presentationPrefs.labelWidth\" (ngModelChange)=\"onPresentationPrefsChange('presentation-label-width')\"\n [placeholder]=\"tx('config.presentation.labelWidth.placeholder', 'ex.: 140')\" />\n <span matSuffix>px</span>\n </mat-form-field>\n </div>\n <div class=\"control control--inline\">\n <mat-slide-toggle [(ngModel)]=\"presentationPrefs.compact\" (ngModelChange)=\"onPresentationPrefsChange('presentation-compact')\">\n {{ tx('config.presentation.options.compactMode', 'Modo compacto') }}\n </mat-slide-toggle>\n <mat-checkbox [(ngModel)]=\"truncatePreview\">\n {{ tx('config.presentation.options.truncateValues', 'Truncar valores') }}\n </mat-checkbox>\n </div>\n </div>\n <div class=\"presentation-preview\">\n <h4>{{ tx('config.presentation.preview.title', 'Pr\u00E9-visualiza\u00E7\u00E3o') }}</h4>\n <p class=\"text-caption\">{{ tx('config.presentation.preview.sampleHint') }}</p>\n <div class=\"preview-card\">\n <div class=\"praxis-dynamic-form presentation-mode\" [ngClass]=\"{\n 'pres-compact': !!presentationPrefs.compact,\n 'pres-label-left': presentationPrefs.labelPosition === 'left',\n 'pres-label-above': presentationPrefs.labelPosition === 'above',\n 'pres-density-compact': presentationPrefs.density === 'compact',\n 'pres-density-cozy': presentationPrefs.density === 'cozy'\n }\" [style.--pfx-pres-label-size]=\"(presentationPrefs.labelFontSize || 12) + 'px'\"\n [style.--pfx-pres-value-size]=\"(presentationPrefs.valueFontSize || 16) + 'px'\"\n [style.--pfx-pres-label-width]=\"(presentationPrefs.labelWidth || 140) + 'px'\"\n [style.--pfx-pres-label-align]=\"presentationPrefs.labelAlign || 'start'\"\n [style.--pfx-pres-value-align]=\"presentationPrefs.valueAlign || 'start'\">\n @for (item of previewItems; track item) {\n <div class=\"preview-row\">\n <span class=\"praxis-presentation__label\">{{ item.label }}</span>\n <span class=\"praxis-presentation__value\" [attr.title]=\"truncatePreview ? item.value : null\"\n [style.maxWidth]=\"truncatePreview ? '280px' : null\"\n [style.overflow]=\"truncatePreview ? 'hidden' : null\"\n [style.textOverflow]=\"truncatePreview ? 'ellipsis' : null\"\n [style.whiteSpace]=\"truncatePreview ? 'nowrap' : 'normal'\">\n {{ item.value }}\n </span>\n </div>\n }\n </div>\n </div>\n </div>\n </div>\n\n </mat-card-content>\n </mat-card>\n </div>\n </mat-tab>\n }\n <mat-tab [label]=\"configTabLabel('behavior')\">\n <div class=\"tab-content\" data-testid=\"config-tab-panel-comportamento\">\n <mat-card class=\"section-card\">\n <mat-card-content>\n <div class=\"section-header\">\n <div>\n <h3>{{ tx('config.behavior.title', 'Comportamento') }}</h3>\n <p class=\"text-caption\">{{ tx('config.behavior.subtitle', 'Ajuste valida\u00E7\u00F5es e respostas do formul\u00E1rio.') }}</p>\n </div>\n </div>\n <praxis-behavior-editor [config]=\"editedConfig\" (configChange)=\"onConfigChange($event)\"></praxis-behavior-editor>\n </mat-card-content>\n </mat-card>\n </div>\n </mat-tab>\n <mat-tab [label]=\"configTabLabel('hints')\">\n <div class=\"tab-content tab-content--dense\" data-testid=\"config-tab-panel-hints\">\n <mat-card class=\"section-card\">\n <mat-card-content>\n <div class=\"section-header\">\n <div>\n <h3>{{ tx('config.hints.title', 'Dicas dos modos') }}</h3>\n <p class=\"text-caption\">{{ tx('config.hints.subtitle', 'Personalize textos de apoio para modos de dados e estados de UI.') }}</p>\n </div>\n </div>\n <p class=\"text-caption\">{{ tx('config.hints.description', 'Personalize os textos usados como tooltip/hint para modos de dados e modos globais de UI.') }}</p>\n\n <div class=\"grid-2-cols grid-2-cols--compact\">\n <section>\n <h4>{{ tx('config.hints.dataModes.title', 'Modos de dados') }}</h4>\n <mat-form-field appearance=\"outline\" class=\"w-100\">\n <mat-label>{{ tx('config.hints.dataModes.create.label', 'Criar') }}</mat-label>\n <input matInput [(ngModel)]=\"editedConfig.hints!.dataModes.create\"\n (ngModelChange)=\"updateDirtyState('hints-data-create')\" [placeholder]=\"tx('config.hints.dataModes.create.placeholder', 'Ex.: Preencha os campos obrigat\u00F3rios.')\" />\n </mat-form-field>\n <mat-form-field appearance=\"outline\" class=\"w-100\">\n <mat-label>{{ tx('config.hints.dataModes.edit.label', 'Editar') }}</mat-label>\n <input matInput [(ngModel)]=\"editedConfig.hints!.dataModes.edit\"\n (ngModelChange)=\"updateDirtyState('hints-data-edit')\" [placeholder]=\"tx('config.hints.dataModes.edit.placeholder', 'Ex.: Revise os dados antes de salvar.')\" />\n </mat-form-field>\n <mat-form-field appearance=\"outline\" class=\"w-100\">\n <mat-label>{{ tx('config.hints.dataModes.view.label', 'Visualizar') }}</mat-label>\n <input matInput [(ngModel)]=\"editedConfig.hints!.dataModes.view\"\n (ngModelChange)=\"updateDirtyState('hints-data-view')\" [placeholder]=\"tx('config.hints.dataModes.view.placeholder', 'Ex.: Visualiza\u00E7\u00E3o somente leitura.')\" />\n </mat-form-field>\n </section>\n\n <section>\n <h4>{{ tx('config.hints.uiModes.title', 'Modos de UI') }}</h4>\n <mat-form-field appearance=\"outline\" class=\"w-100\">\n <mat-label>{{ tx('config.hints.uiModes.presentation.label', 'Apresenta\u00E7\u00E3o') }}</mat-label>\n <textarea matInput rows=\"2\" [(ngModel)]=\"editedConfig.hints!.uiModes.presentation\"\n (ngModelChange)=\"updateDirtyState('hints-ui-presentation')\" [placeholder]=\"tx('config.hints.uiModes.presentation.placeholder', 'Ex.: Modo compacto para leitura r\u00E1pida.')\"></textarea>\n </mat-form-field>\n <mat-form-field appearance=\"outline\" class=\"w-100\">\n <mat-label>{{ tx('config.hints.uiModes.readonly.label', 'Leitura (readonly)') }}</mat-label>\n <textarea matInput rows=\"2\" [(ngModel)]=\"editedConfig.hints!.uiModes.readonly\"\n (ngModelChange)=\"updateDirtyState('hints-ui-readonly')\" [placeholder]=\"tx('config.hints.uiModes.readonly.placeholder', 'Ex.: Campos bloqueados para edi\u00E7\u00E3o.')\"></textarea>\n </mat-form-field>\n <mat-form-field appearance=\"outline\" class=\"w-100\">\n <mat-label>{{ tx('config.hints.uiModes.disabled.label', 'Desabilitado') }}</mat-label>\n <textarea matInput rows=\"2\" [(ngModel)]=\"editedConfig.hints!.uiModes.disabled\"\n (ngModelChange)=\"updateDirtyState('hints-ui-disabled')\" [placeholder]=\"tx('config.hints.uiModes.disabled.placeholder', 'Ex.: Fun\u00E7\u00E3o indispon\u00EDvel no momento.')\"></textarea>\n </mat-form-field>\n <mat-form-field appearance=\"outline\" class=\"w-100\">\n <mat-label>{{ tx('config.hints.uiModes.visible.label', 'Vis\u00EDvel') }}</mat-label>\n <textarea matInput rows=\"2\" [(ngModel)]=\"editedConfig.hints!.uiModes.visible\"\n (ngModelChange)=\"updateDirtyState('hints-ui-visible')\" [placeholder]=\"tx('config.hints.uiModes.visible.placeholder', 'Ex.: Campo exibido conforme permiss\u00F5es.')\"></textarea>\n </mat-form-field>\n </section>\n </div>\n\n <section>\n <h4>{{ tx('config.helpPresentation.title', 'Apresenta\u00E7\u00E3o das ajudas dos campos') }}</h4>\n <p class=\"text-caption\">{{ tx('config.helpPresentation.description', 'Controle como hint/helpText dos campos aparece em formul\u00E1rios densos. Erros de valida\u00E7\u00E3o continuam inline.') }}</p>\n <div class=\"grid-3-cols\">\n <mat-form-field appearance=\"outline\" class=\"w-100\">\n <mat-label>{{ tx('config.helpPresentation.display.label', 'Exibi\u00E7\u00E3o') }}</mat-label>\n <mat-select [ngModel]=\"helpPresentationDraft.display\" (ngModelChange)=\"onHelpPresentationDisplayChange($event)\">\n <mat-option value=\"inline\">{{ tx('config.helpPresentation.display.inline', 'Inline') }}</mat-option>\n <mat-option value=\"popover\">{{ tx('config.helpPresentation.display.popover', '\u00CDcone de ajuda') }}</mat-option>\n <mat-option value=\"auto\">{{ tx('config.helpPresentation.display.auto', 'Autom\u00E1tica') }}</mat-option>\n <mat-option value=\"hidden\">{{ tx('config.helpPresentation.display.hidden', 'Oculta') }}</mat-option>\n </mat-select>\n </mat-form-field>\n <mat-form-field appearance=\"outline\" class=\"w-100\">\n <mat-label>{{ tx('config.helpPresentation.inlineMaxLength.label', 'Limite inline') }}</mat-label>\n <input matInput type=\"number\" min=\"0\" [ngModel]=\"helpPresentationDraft.inlineMaxLength\"\n (ngModelChange)=\"onHelpPresentationInlineMaxLengthChange($event)\" />\n </mat-form-field>\n <mat-form-field appearance=\"outline\" class=\"w-100\">\n <mat-label>{{ tx('config.helpPresentation.preferPopoverForControls.label', 'Preferir \u00EDcone em') }}</mat-label>\n <input matInput [ngModel]=\"getHelpPreferPopoverControlsText()\"\n (ngModelChange)=\"onHelpPreferPopoverControlsChange($event)\"\n [placeholder]=\"tx('config.helpPresentation.preferPopoverForControls.placeholder', 'toggle, checkbox, select')\" />\n </mat-form-field>\n </div>\n </section>\n\n <div class=\"actions-row\">\n <button mat-stroked-button color=\"primary\" type=\"button\" (click)=\"restoreHintsDefaults()\">\n <mat-icon>restore</mat-icon>\n {{ tx('config.hints.actions.restoreDefaults', 'Restaurar padr\u00F5es') }}\n </button>\n </div>\n </mat-card-content>\n </mat-card>\n </div>\n </mat-tab>\n <mat-tab [label]=\"configTabLabel('actions')\">\n <div class=\"tab-content\" data-testid=\"config-tab-panel-acoes\">\n <mat-card class=\"section-card\">\n <mat-card-content>\n <div class=\"section-header\">\n <div>\n <h3>{{ tx('config.actions.title', 'A\u00E7\u00F5es do formul\u00E1rio') }}</h3>\n <p class=\"text-caption\">{{ tx('config.actions.subtitle', 'Configure bot\u00F5es padr\u00E3o e a\u00E7\u00F5es customizadas.') }}</p>\n </div>\n </div>\n <praxis-actions-editor #actionsDraft [config]=\"editedConfig\" (validationChange)=\"onSurfaceDraftValidity(actionsDraft, $event)\" (configChange)=\"onConfigChange($event)\"></praxis-actions-editor>\n </mat-card-content>\n </mat-card>\n </div>\n </mat-tab>\n <mat-tab [label]=\"configTabLabel('rules')\">\n <div class=\"tab-content visual-builder-content\" data-testid=\"config-tab-panel-regras\">\n <div class=\"builder-header\">\n <div>\n <h3>{{ tx('config.rules.title', 'Regras visuais') }}</h3>\n <p class=\"text-caption\">{{ tx('config.rules.subtitle', 'Defina visibilidade, estilos e rea\u00E7\u00F5es baseadas em condi\u00E7\u00F5es.') }}</p>\n </div>\n </div>\n @if (ruleDiagnostics.length) {\n <div class=\"rules-diagnostics\" data-testid=\"rules-diagnostics-panel\">\n <div class=\"rules-diagnostics__summary\">\n <span class=\"rules-diagnostics__pill rules-diagnostics__pill--total\">\n {{ tx('config.rules.summary.total', '{{count}} regras', { count: ruleDiagnosticsSummary.total }) }}\n </span>\n @if (ruleDiagnosticsSummary.invalid) {\n <span class=\"rules-diagnostics__pill rules-diagnostics__pill--error\">\n {{ tx('config.rules.summary.invalid', '{{count}} inv\u00E1lidas', { count: ruleDiagnosticsSummary.invalid }) }}\n </span>\n }\n @if (ruleDiagnosticsSummary.unsupported) {\n <span class=\"rules-diagnostics__pill rules-diagnostics__pill--warn\">\n {{ tx('config.rules.summary.unsupported', '{{count}} com propriedades rejeitadas', { count: ruleDiagnosticsSummary.unsupported }) }}\n </span>\n }\n @if (ruleDiagnosticsSummary.runtimeOnly) {\n <span class=\"rules-diagnostics__pill rules-diagnostics__pill--warn\">\n {{ tx('config.rules.summary.runtimeOnly', '{{count}} runtime only', { count: ruleDiagnosticsSummary.runtimeOnly }) }}\n </span>\n }\n @if (ruleDiagnosticsSummary.pendingReview) {\n <span class=\"rules-diagnostics__pill rules-diagnostics__pill--warn\">\n {{ tx('config.rules.summary.pendingReview', '{{count}} pendentes de revis\u00E3o', { count: ruleDiagnosticsSummary.pendingReview }) }}\n </span>\n }\n </div>\n <div class=\"rules-diagnostics__list\" [attr.aria-label]=\"tx('config.rules.diagnostics.ariaLabel', 'Diagn\u00F3stico das regras')\">\n @for (diagnostic of ruleDiagnostics; track diagnostic) {\n <article class=\"rules-diagnostics__item\"\n [class.rules-diagnostics__item--error]=\"getRuleStatusTone(diagnostic) === 'error'\"\n [class.rules-diagnostics__item--warn]=\"getRuleStatusTone(diagnostic) === 'warn'\">\n <div>\n <strong>{{ diagnostic.ruleName || diagnostic.ruleId }}</strong>\n <span>\n {{ tx('config.rules.diagnostics.targetConditionSummary', '{{targets}} alvo(s) \u00B7 {{conditions}} campo(s) na condi\u00E7\u00E3o', { targets: diagnostic.targetRefs.length, conditions: diagnostic.conditionRefs.length }) }}\n </span>\n @if (getRuleDiagnosticDetails(diagnostic).length) {\n <ul class=\"rules-diagnostics__details\">\n @for (detail of getRuleDiagnosticDetails(diagnostic); track detail) {\n <li>{{ detail }}</li>\n }\n </ul>\n }\n </div>\n <div class=\"rules-diagnostics__actions\">\n <span class=\"rules-diagnostics__status\">{{ getRuleStatusLabel(diagnostic) }}</span>\n @if (canApplyRulePropertyFix(diagnostic)) {\n <button\n mat-stroked-button\n type=\"button\"\n class=\"rules-diagnostics__action\"\n [matTooltip]=\"tx('config.rules.actions.fix.tooltip', 'Aplicar whitelist e saneamento de propriedades nesta regra')\"\n (click)=\"applyRulePropertyFix(diagnostic.ruleId)\">\n <mat-icon aria-hidden=\"true\">auto_fix_high</mat-icon>\n {{ tx('config.rules.actions.fix', 'Corrigir') }}\n </button>\n }\n @if (diagnostic.status.includes('llm-generated-pending-review')) {\n <button\n mat-stroked-button\n type=\"button\"\n class=\"rules-diagnostics__action\"\n [disabled]=\"!canAcceptPendingLlmRule(diagnostic)\"\n [matTooltip]=\"canAcceptPendingLlmRule(diagnostic) ? tx('config.rules.actions.accept.tooltip.ready', 'Aceitar sugest\u00E3o e atualizar estado visual') : tx('config.rules.actions.accept.tooltip.blocked', 'Corrija alvo, condi\u00E7\u00E3o e propriedades antes de aceitar')\"\n (click)=\"acceptPendingLlmRule(diagnostic.ruleId)\">\n <mat-icon aria-hidden=\"true\">check</mat-icon>\n {{ tx('config.rules.actions.accept', 'Aceitar') }}\n </button>\n }\n @if (canOpenRuleJsonReview(diagnostic)) {\n <button\n mat-stroked-button\n type=\"button\"\n class=\"rules-diagnostics__action\"\n [matTooltip]=\"tx('config.rules.actions.reviewJson.tooltip', 'Abrir a aba JSON para revisar esta regra sem convers\u00E3o visual')\"\n (click)=\"openRuleJsonReview(diagnostic.ruleId)\">\n <mat-icon aria-hidden=\"true\">data_object</mat-icon>\n {{ tx('config.rules.actions.reviewJson', 'Ver JSON') }}\n </button>\n }\n </div>\n </article>\n }\n </div>\n </div>\n } @else {\n <div class=\"rules-diagnostics rules-diagnostics--empty\" data-testid=\"rules-diagnostics-empty\">\n {{ tx('config.rules.empty', 'Nenhuma regra definida ainda. Crie uma regra para ver alvos, condi\u00E7\u00E3o, propriedades e compatibilidade do builder.') }}\n </div>\n }\n <praxis-visual-builder [config]=\"ruleBuilderConfig\" [initialRules]=\"ruleBuilderState\"\n (rulesChanged)=\"onRulesChanged($event)\"></praxis-visual-builder>\n <praxis-rule-properties-panel\n [rules]=\"currentRules\"\n [visualBlockNodes]=\"visualBlockNodeOptions\"\n (rulesChange)=\"onRulePropertiesChanged($event)\"\n ></praxis-rule-properties-panel>\n <mat-card class=\"command-rules-card\" data-testid=\"form-command-rules-editor\">\n <mat-card-title>{{ tx('config.commandRules.title', 'Comandos condicionais') }}</mat-card-title>\n <mat-card-subtitle>{{ tx('config.commandRules.subtitle', 'Execute a\u00E7\u00F5es globais quando uma condi\u00E7\u00E3o do formul\u00E1rio for satisfeita.') }}</mat-card-subtitle>\n <mat-card-content>\n <div class=\"command-rules-grid\">\n <div class=\"command-rules-toolbar\">\n <mat-form-field appearance=\"outline\" class=\"command-rules-select\">\n <mat-label>{{ tx('config.commandRules.command.label', 'Comando') }}</mat-label>\n <mat-select [disabled]=\"hasInvalidSurfaceDraft\" [(ngModel)]=\"selectedCommandRuleId\" (selectionChange)=\"onCommandRuleSelectionChange()\">\n @for (rule of commandRules; track rule) {\n <mat-option [value]=\"rule.id\">\n {{ rule.id }}\n </mat-option>\n }\n </mat-select>\n </mat-form-field>\n <button mat-stroked-button type=\"button\" [disabled]=\"hasInvalidSurfaceDraft\" (click)=\"addCommandRule()\">\n <mat-icon aria-hidden=\"true\">add</mat-icon>\n {{ tx('config.commandRules.actions.add', 'Adicionar') }}\n </button>\n <button mat-stroked-button color=\"warn\" type=\"button\" (click)=\"deleteCommandRule()\" [disabled]=\"hasInvalidSurfaceDraft || !selectedCommandRuleId\">\n <mat-icon aria-hidden=\"true\">delete</mat-icon>\n {{ tx('config.commandRules.actions.remove', 'Remover') }}\n </button>\n </div>\n\n @if (selectedCommandRuleId) {\n <div class=\"command-rule-condition-builder command-rules-full\">\n <praxis-visual-builder\n mode=\"condition\"\n [config]=\"ruleBuilderConfig\"\n [initialCondition]=\"commandRuleCondition\"\n (conditionChanged)=\"onCommandConditionChanged($event)\"\n ></praxis-visual-builder>\n </div>\n }\n\n <mat-form-field appearance=\"outline\" class=\"command-rules-full\">\n <mat-label>{{ tx('config.commandRules.conditionJson.label', 'Condi\u00E7\u00E3o JSON Logic') }}</mat-label>\n <textarea\n matInput\n rows=\"5\"\n [(ngModel)]=\"commandRuleConditionJson\"\n [attr.aria-label]=\"tx('config.commandRules.conditionJson.ariaLabel', 'Condi\u00E7\u00E3o JSON Logic do comando condicional')\"\n ></textarea>\n </mat-form-field>\n\n <mat-form-field appearance=\"outline\">\n <mat-label>{{ tx('config.commandRules.globalAction.label', 'A\u00E7\u00E3o global') }}</mat-label>\n <mat-select [disabled]=\"hasInvalidSurfaceDraft\" [(ngModel)]=\"commandRuleActionId\" (selectionChange)=\"onCommandActionChange()\">\n @for (action of globalActionCatalog; track action) {\n <mat-option [value]=\"action.id\">\n {{ action.label || action.id }}\n </mat-option>\n }\n </mat-select>\n </mat-form-field>\n\n <mat-form-field appearance=\"outline\">\n <mat-label>{{ tx('config.commandRules.distinctBy.label', 'distinctBy') }}</mat-label>\n <input matInput [(ngModel)]=\"commandRuleDistinctBy\" [placeholder]=\"tx('config.commandRules.distinctBy.placeholder', 'ex.: idade')\" />\n </mat-form-field>\n\n @if (commandRuleActionSchema; as actionSchema) {\n <div\n class=\"command-rules-payload-fields command-rules-full\"\n >\n <div class=\"command-rules-section-title\">{{ tx('config.commandRules.structuredPayload.title', 'Payload estruturado') }}</div>\n @if (actionSchema.editorMode !== 'surface-open') {\n @for (field of actionSchema.fields; track field) {\n @if (shouldShowCommandActionField(field)) {\n @if (field.type === 'toggle') {\n <mat-slide-toggle\n [ngModel]=\"getCommandActionFieldValue(field)\"\n (ngModelChange)=\"onCommandActionFieldChange(field, $event)\"\n [ngModelOptions]=\"{ standalone: true }\"\n >\n {{ field.label }}\n </mat-slide-toggle>\n } @else {\n <mat-form-field appearance=\"outline\">\n <mat-label>{{ field.label }}</mat-label>\n @if (field.type === 'textarea' || field.type === 'json') {\n <textarea\n matInput\n [rows]=\"field.rows || (field.type === 'json' ? 3 : 2)\"\n [ngModel]=\"getCommandActionFieldValue(field)\"\n (ngModelChange)=\"onCommandActionFieldChange(field, $event)\"\n [ngModelOptions]=\"{ standalone: true }\"\n [placeholder]=\"field.placeholder || (field.type === 'json' ? '{ }' : '')\"\n [required]=\"isCommandActionFieldRequired(field)\"\n ></textarea>\n } @else {\n @if (field.type === 'select') {\n <mat-select\n [ngModel]=\"getCommandActionFieldValue(field)\"\n (ngModelChange)=\"onCommandActionFieldChange(field, $event)\"\n [ngModelOptions]=\"{ standalone: true }\"\n [required]=\"isCommandActionFieldRequired(field)\"\n >\n @for (option of field.options || []; track option) {\n <mat-option [value]=\"option.value\">\n {{ option.label }}\n </mat-option>\n }\n </mat-select>\n } @else {\n <input\n matInput\n [type]=\"field.type === 'number' ? 'number' : 'text'\"\n [ngModel]=\"getCommandActionFieldValue(field)\"\n (ngModelChange)=\"onCommandActionFieldChange(field, $event)\"\n [ngModelOptions]=\"{ standalone: true }\"\n [placeholder]=\"field.placeholder || ''\"\n [required]=\"isCommandActionFieldRequired(field)\"\n />\n }\n }\n @if (field.hint) {\n <mat-hint>{{ field.hint }}</mat-hint>\n }\n @if (hasCommandActionFieldError(field.key)) {\n <mat-error>\n {{ getCommandActionFieldError(field.key) }}\n </mat-error>\n }\n @if (!hasCommandActionFieldError(field.key) && isCommandActionFieldMissing(field)) {\n <mat-error>\n {{ tx('config.commandRules.validation.requiredField', 'Campo obrigat\u00F3rio.') }}\n </mat-error>\n }\n </mat-form-field>\n }\n }\n }\n } @else {\n <praxis-surface-open-action-editor #commandSurfaceDraft\n class=\"command-rules-surface-editor\"\n data-testid=\"form-command-rule-surface-open-editor\"\n [value]=\"commandRuleSurfaceOpenPayload\"\n hostKind=\"dynamic-form\"\n (valueChange)=\"onCommandSurfaceOpenPayloadChange($event)\"\n (validationChange)=\"onSurfaceDraftValidity(commandSurfaceDraft, $event)\"\n ></praxis-surface-open-action-editor>\n }\n </div>\n }\n\n <mat-form-field appearance=\"outline\" class=\"command-rules-full\">\n <mat-label>{{ tx('config.commandRules.advancedPayload.label', 'Payload JSON avan\u00E7ado') }}</mat-label>\n <textarea\n matInput\n rows=\"4\"\n [(ngModel)]=\"commandRulePayloadJson\"\n [attr.aria-label]=\"tx('config.commandRules.advancedPayload.ariaLabel', 'Payload JSON da a\u00E7\u00E3o global')\"\n ></textarea>\n </mat-form-field>\n\n <div class=\"command-rules-options\">\n <mat-slide-toggle [(ngModel)]=\"commandRuleDistinct\">{{ tx('config.commandRules.options.distinct', 'Evitar repeti\u00E7\u00E3o enquanto a condi\u00E7\u00E3o permanecer verdadeira') }}</mat-slide-toggle>\n <mat-slide-toggle [(ngModel)]=\"commandRuleRunOnInitialEvaluation\">{{ tx('config.commandRules.options.runOnInitialEvaluation', 'Executar tamb\u00E9m na avalia\u00E7\u00E3o inicial') }}</mat-slide-toggle>\n </div>\n\n @if (commandRuleAuthoringError) {\n <div class=\"preview-error command-rules-full\">\n <mat-icon aria-hidden=\"true\">warning</mat-icon>\n <span>{{ commandRuleAuthoringError }}</span>\n </div>\n }\n\n <div\n class=\"command-rule-preview command-rules-full\"\n [class.command-rule-preview--invalid]=\"commandRulePreview.state === 'invalid'\"\n data-testid=\"command-rule-preview\"\n >\n <div class=\"command-rules-section-title\">{{ tx('config.commandRules.preview.title', 'Preview do comando') }}</div>\n <div class=\"command-rule-preview__row\">\n <span>{{ tx('config.commandRules.preview.mode', 'Modo') }}</span>\n <strong>{{ commandRulePreview.executionMode }}</strong>\n </div>\n <div class=\"command-rule-preview__row\">\n <span>{{ tx('config.commandRules.preview.action', 'A\u00E7\u00E3o') }}</span>\n <strong>{{ commandRulePreview.actionId || '\u2014' }}</strong>\n </div>\n <div class=\"command-rule-preview__row\">\n <span>{{ tx('config.commandRules.preview.policy', 'Policy') }}</span>\n <code>{{ commandRulePreview.policy | json }}</code>\n </div>\n @if (commandRulePreview.diagnostics.length) {\n <div class=\"command-rule-preview__diagnostics\">\n <mat-icon aria-hidden=\"true\">{{ commandRulePreview.state === 'invalid' ? 'warning' : 'visibility' }}</mat-icon>\n <span>{{ commandRulePreview.diagnostics[0] }}</span>\n </div>\n }\n </div>\n\n <div class=\"command-rules-actions\">\n <button mat-flat-button color=\"primary\" type=\"button\" (click)=\"applyCommandRule()\">\n <mat-icon aria-hidden=\"true\">check</mat-icon>\n {{ tx('config.commandRules.actions.apply', 'Aplicar comando') }}\n </button>\n </div>\n </div>\n </mat-card-content>\n </mat-card>\n </div>\n </mat-tab>\n <mat-tab [label]=\"configTabLabel('cascades')\">\n <div class=\"tab-content\" data-testid=\"config-tab-panel-cascatas\">\n <mat-card class=\"section-card\">\n <mat-card-content>\n <div class=\"section-header\">\n <div>\n <h3>{{ tx('config.cascades.title', 'Depend\u00EAncias entre campos') }}</h3>\n <p class=\"text-caption\">{{ tx('config.cascades.subtitle', 'Configure cascatas e carregamento entre campos.') }}</p>\n </div>\n </div>\n <praxis-cascade-manager-tab [fields]=\"editedConfig.fieldMetadata || []\"\n (apply)=\"onCascadeApply($event)\"></praxis-cascade-manager-tab>\n </mat-card-content>\n </mat-card>\n </div>\n </mat-tab>\n <mat-tab [label]=\"configTabLabel('messages')\">\n <div class=\"tab-content\" data-testid=\"config-tab-panel-mensagens\">\n <mat-card class=\"section-card\">\n <mat-card-content>\n <div class=\"section-header\">\n <div>\n <h3>{{ tx('config.messages.title', 'Mensagens e feedback') }}</h3>\n <p class=\"text-caption\">{{ tx('config.messages.subtitle', 'Padronize textos de sucesso, erro e confirma\u00E7\u00F5es.') }}</p>\n </div>\n </div>\n <praxis-messages-editor [config]=\"editedConfig\" (configChange)=\"onConfigChange($event)\"></praxis-messages-editor>\n </mat-card-content>\n </mat-card>\n </div>\n </mat-tab>\n <mat-tab [label]=\"configTabLabel('navigation')\">\n <div class=\"tab-content\" data-testid=\"config-tab-panel-navegacao\">\n <mat-card class=\"section-card\">\n <mat-card-content>\n <div class=\"section-header\">\n <div>\n <h3>{{ tx('config.navigation.title', 'Navega\u00E7\u00E3o de retorno') }}</h3>\n <p class=\"text-caption\">{{ tx('config.navigation.subtitle', 'Defina o comportamento do bot\u00E3o Voltar em fluxos CRUD.') }}</p>\n </div>\n </div>\n <div class=\"form-grid\">\n <div class=\"form-row\">\n <mat-form-field appearance=\"outline\" class=\"w-100\">\n <mat-label>{{ tx('config.navigation.returnTo.label', 'Rota de retorno') }}</mat-label>\n <input matInput id=\"returnTo\" [(ngModel)]=\"backConfig!.returnTo\" (ngModelChange)=\"onBackConfigChange()\" [placeholder]=\"tx('config.navigation.returnTo.placeholder', '/funcionarios')\" />\n </mat-form-field>\n </div>\n <div class=\"form-row\">\n <mat-slide-toggle [(ngModel)]=\"backConfig!.confirmOnDirty\" (ngModelChange)=\"onBackConfigChange()\">\n {{ tx('config.navigation.confirmOnDirty.label', 'Confirmar ao sair com altera\u00E7\u00F5es') }}\n </mat-slide-toggle>\n </div>\n <div class=\"block-status\" [class.block-status--implicit]=\"!isBackConfigBlockPersisted()\">\n <strong>{{ tx('config.navigation.backConfig.label', 'Back Config') }}</strong>\n @if (isBackConfigBlockPersisted()) {\n <span>{{ tx('config.navigation.backConfig.persisted', '`contextSnapshot.backConfig` ser\u00E1 persistido no documento can\u00F4nico.') }}</span>\n } @else {\n {{ tx('config.navigation.backConfig.implicit', 'Bloco ausente no documento can\u00F4nico. Os valores exibidos s\u00E3o fallback visual e n\u00E3o ser\u00E3o salvos at\u00E9 voc\u00EA editar.') }}\n }\n </div>\n </div>\n <div class=\"section-help\">\n <span class=\"section-help__label\">{{ tx('config.navigation.note.label', 'Observa\u00E7\u00E3o:') }}</span>\n <button\n praxisIconButton=\"help_outline\"\n size=\"dense\"\n class=\"help-icon-button\"\n type=\"button\"\n [matTooltip]=\"tx('config.navigation.note.tooltip', 'Afeta o fluxo de navega\u00E7\u00E3o do CRUD e pode ser sobreposto por metadados do recurso.')\"\n matTooltipPosition=\"above\"\n >\n </button>\n </div>\n </mat-card-content>\n </mat-card>\n </div>\n </mat-tab>\n <mat-tab [label]=\"configTabLabel('json')\">\n <div class=\"tab-content json-tab-content\" data-testid=\"config-tab-panel-json\">\n <mat-card class=\"section-card section-card--json\">\n <mat-card-content>\n <div class=\"section-header\">\n <div>\n <h3>{{ tx('config.json.title', 'Configura\u00E7\u00E3o JSON') }}</h3>\n <p class=\"text-caption\">{{ tx('config.json.subtitle', 'Edi\u00E7\u00E3o avan\u00E7ada do documento can\u00F4nico de autoria do formul\u00E1rio.') }}</p>\n </div>\n </div>\n <form-json-config-editor [document]=\"jsonDocument\" (documentChange)=\"onJsonConfigChange($event)\"\n (validationChange)=\"onJsonValidationChange($event)\" (editorEvent)=\"onJsonEditorEvent($event)\">\n </form-json-config-editor>\n </mat-card-content>\n </mat-card>\n </div>\n </mat-tab>\n</mat-tab-group>\n", styles: [":host{container:praxis-authoring-editor/inline-size;display:flex;flex-direction:column;height:100%;min-width:0}.mobile-tab-selector{display:none;flex:0 0 auto;padding:8px 16px 0;background:var(--md-sys-color-surface)}.mobile-tab-selector__field{width:100%}.config-tabs{flex:1 1 auto;min-height:0;min-width:0}::ng-deep .mat-mdc-tab-group.config-tabs{display:flex;flex-direction:column}::ng-deep .mat-mdc-tab-group.config-tabs .mat-mdc-tab-body-wrapper{flex:1;min-height:0;min-width:0}::ng-deep .mat-mdc-tab-group.config-tabs .mat-mdc-tab-body-content{height:100%;overflow-y:auto;overflow-x:hidden;display:flex;flex-direction:column;padding:0!important}.tab-content{padding:20px 24px 28px;flex:1;min-width:0;box-sizing:border-box;display:flex;flex-direction:column;gap:24px}.json-tab-content{min-width:0;padding:12px 16px 16px}.section-card.section-card--json{display:flex;flex:1;min-height:calc(100vh - 180px);border:1px solid var(--md-sys-color-outline-variant);border-radius:12px;background:var(--md-sys-color-surface-container-low)}.section-card.section-card--json>mat-card-content,.section-card.section-card--json>.mat-mdc-card-content{display:flex;flex:1;min-width:0;min-height:0;flex-direction:column;padding:16px!important}.section-card--json form-json-config-editor{display:block;flex:1;min-width:0;min-height:0}.form-row{display:block;margin-bottom:12px}.form-grid{display:grid;gap:12px}.section-help{display:inline-flex;align-items:center;gap:8px;color:var(--md-sys-color-on-surface-variant);font-size:12px}.section-help__label{font-weight:500}.grid-2-cols{display:grid;grid-template-columns:repeat(auto-fit,minmax(260px,1fr));gap:16px}.grid-2-cols--compact{gap:12px}.w-100{width:100%}.visual-builder-content{padding:0!important;height:100%;min-width:0;overflow-y:auto;overflow-x:hidden;display:flex;flex-direction:column;gap:16px}.visual-builder-content>praxis-visual-builder{flex:0 0 auto;min-width:0;min-height:clamp(360px,48vh,560px)}.visual-builder-content>praxis-rule-properties-panel{flex:0 0 auto;display:block;min-width:0;padding:0 16px 24px;box-sizing:border-box}.rules-diagnostics{flex:0 0 auto;display:grid;gap:10px;padding:12px 16px;border-bottom:1px solid var(--md-sys-color-outline-variant);background:var(--md-sys-color-surface-container-low)}.rules-diagnostics--empty{color:var(--md-sys-color-on-surface-variant);font-size:12px;line-height:1.45}.rules-diagnostics__summary,.rules-diagnostics__list{display:flex;flex-wrap:wrap;gap:8px}.rules-diagnostics__pill{display:inline-flex;align-items:center;min-height:24px;padding:3px 9px;border-radius:999px;background:var(--md-sys-color-surface-container-high);color:var(--md-sys-color-on-surface);font-size:12px;font-weight:600}.rules-diagnostics__pill--warn{background:color-mix(in srgb,var(--md-sys-color-tertiary-container) 72%,transparent);color:var(--md-sys-color-on-tertiary-container)}.rules-diagnostics__pill--error{background:var(--md-sys-color-error-container);color:var(--md-sys-color-on-error-container)}.rules-diagnostics__item{display:flex;align-items:flex-start;justify-content:space-between;gap:14px;min-width:min(100%,280px);padding:8px 10px;border:1px solid var(--md-sys-color-outline-variant);border-radius:8px;background:var(--md-sys-color-surface-container)}.rules-diagnostics__item>div{display:grid;gap:2px;min-width:0}.rules-diagnostics__item strong{color:var(--md-sys-color-on-surface);font-size:12px;line-height:1.25;overflow:hidden;text-overflow:ellipsis;white-space:nowrap}.rules-diagnostics__item span{color:var(--md-sys-color-on-surface-variant);font-size:11px}.rules-diagnostics__actions{flex:0 0 auto;display:flex;align-items:center;gap:8px}.rules-diagnostics__details{display:grid;gap:2px;margin:4px 0 0;padding-left:16px;color:var(--md-sys-color-on-surface-variant);font-size:11px;line-height:1.35}.rules-diagnostics__details li{overflow-wrap:anywhere}.rules-diagnostics__item--warn{border-color:color-mix(in srgb,var(--md-sys-color-tertiary) 52%,var(--md-sys-color-outline-variant))}.rules-diagnostics__item--error{border-color:var(--md-sys-color-error)}.rules-diagnostics__status{font-weight:600;margin-top:1px}.rules-diagnostics__action{min-width:0;height:28px;padding:0 10px;border-radius:999px;font-size:12px;line-height:1}.rules-diagnostics__action mat-icon{width:16px;height:16px;margin:0 4px 0 0;font-size:16px}.json-field{width:100%}.presentation-layout{display:grid;grid-template-columns:minmax(0,1fr);gap:20px;align-items:start}.presentation-controls{display:grid;grid-template-columns:repeat(auto-fit,minmax(min(100%,240px),1fr));gap:14px 18px}.control{display:flex;flex-direction:column}.control-span{grid-column:1/-1}.block-status{grid-column:1/-1;display:flex;gap:8px;align-items:flex-start;padding:10px 12px;border-radius:10px;background:color-mix(in srgb,var(--md-sys-color-primary-container) 35%,transparent);color:var(--md-sys-color-on-surface);font-size:12px;line-height:1.45}.block-status strong{min-width:112px;font-size:11px;letter-spacing:.04em;text-transform:uppercase;color:var(--md-sys-color-on-surface-variant)}.block-status--implicit{background:color-mix(in srgb,var(--md-sys-color-surface-variant) 42%,transparent);border:1px dashed var(--md-sys-color-outline)}.block-status--readonly{margin-bottom:12px}.block-status code{font-family:var(--md-ref-typeface-mono, \"Courier New\", monospace);font-size:11px}.control__label{font-size:12px;color:var(--md-sys-color-on-surface-variant);margin-bottom:6px}.toggle-group{max-width:100%;flex-wrap:wrap}.control--inline{grid-column:1/-1;display:flex;gap:16px;align-items:center}.presentation-preview{min-width:0;order:-1}.preview-card{border:1px solid var(--md-sys-color-outline);border-radius:12px;padding:14px;background:var(--md-sys-color-surface-container)}.preview-row{display:flex;gap:8px;padding:6px 0;border-bottom:1px dashed var(--md-sys-color-outline-variant)}.preview-row:last-child{border-bottom:none}.sr-only{position:absolute;width:1px;height:1px;padding:0;margin:-1px;overflow:hidden;clip:rect(0,0,0,0);white-space:nowrap;border:0}.presentation-preview .praxis-presentation__label{color:var(--md-sys-color-on-surface-variant);font-size:var(--pfx-pres-label-size, 12px)}.presentation-preview .praxis-presentation__value{min-width:0;overflow-wrap:anywhere;font-size:var(--pfx-pres-value-size, 16px);color:var(--md-sys-color-on-surface)}.presentation-preview .presentation-mode.pres-density-cozy .preview-row{padding:6px 0}.presentation-preview .presentation-mode.pres-density-compact .preview-row,.presentation-preview .presentation-mode.pres-compact .preview-row{padding:2px 0}.presentation-preview .presentation-mode.pres-label-left .preview-row{display:grid;grid-template-columns:var(--pfx-pres-label-width, 140px) 1fr;align-items:baseline;column-gap:10px}.presentation-preview .presentation-mode.pres-label-left .praxis-presentation__label{margin:0;text-align:var(--pfx-pres-label-align, start)}.presentation-preview .presentation-mode .praxis-presentation__value{text-align:var(--pfx-pres-value-align, start)}.presentation-preview h4{margin:0 0 8px;color:var(--md-sys-color-on-surface);font-size:1rem}.section-card:not(.section-card--json),.section-card:not(.section-card--json).mat-mdc-card,.section-card:not(.section-card--json).mat-mdc-card-outlined{border:none!important;border-width:0!important;border-radius:0!important;background:transparent!important;box-shadow:none!important;margin:0!important;padding:0!important;--mdc-outlined-card-outline-width: 0px;--mdc-outlined-card-outline-color: transparent;--mdc-elevated-card-container-color: transparent;--mdc-outlined-card-container-color: transparent}.section-card:not(.section-card--json)>mat-card-content,.section-card:not(.section-card--json)>.mat-mdc-card-content{padding:0!important}.section-card:not(.section-card--json)+.section-card:not(.section-card--json),.section-card:not(.section-card--json).mat-mdc-card+.section-card:not(.section-card--json).mat-mdc-card{padding-top:24px!important;border-top:1px solid color-mix(in srgb,var(--md-sys-color-outline-variant) 65%,transparent)!important}.section-header{display:flex;align-items:flex-start;justify-content:space-between;gap:12px;margin-bottom:16px}.tab-content--dense{padding:16px 20px 24px;gap:20px}.tab-content--dense .section-header{margin-bottom:10px}.tab-content--dense .form-row{margin-bottom:8px}.section-header h3{margin:0;font-size:1rem;font-weight:600;letter-spacing:-.01em;color:var(--md-sys-color-on-surface)}.text-caption{margin:4px 0 0;font-size:.85rem;line-height:1.45;color:var(--md-sys-color-on-surface-variant)}.section-header--compact{margin-bottom:10px}.section-body{display:block}.section-body--flex{flex:1;min-height:0;display:flex;flex-direction:column}.builder-header{padding:12px 16px;border-bottom:1px solid var(--md-sys-color-outline-variant);background:var(--md-sys-color-surface)}.builder-header h3{margin:0;font-size:1rem;color:var(--md-sys-color-on-surface)}.hint{margin:8px 0 0;padding:10px 12px;border-radius:8px;border:1px dashed color-mix(in srgb,var(--md-sys-color-outline-variant) 70%,transparent);background:color-mix(in srgb,var(--md-sys-color-surface-container-low) 75%,transparent);color:var(--md-sys-color-on-surface-variant)}.meta-card{display:grid;gap:8px;padding:12px 14px;border-radius:8px;border:1px solid color-mix(in srgb,var(--md-sys-color-outline-variant) 50%,transparent);background:color-mix(in srgb,var(--md-sys-color-surface-container-low) 70%,transparent);color:var(--md-sys-color-on-surface)}.meta-row{display:flex;align-items:center;justify-content:space-between;gap:12px;font-size:.875rem;color:var(--md-sys-color-on-surface-variant)}.meta-row strong{color:var(--md-sys-color-on-surface);font-weight:600}.runtime-contract-grid{display:grid;grid-template-columns:repeat(auto-fit,minmax(200px,1fr));gap:10px 14px}.runtime-contract-field{display:grid;gap:4px;padding:10px 12px;border-radius:8px;border:1px solid color-mix(in srgb,var(--md-sys-color-outline-variant) 45%,transparent);background:color-mix(in srgb,var(--md-sys-color-surface-container-low) 65%,transparent)}.runtime-contract-label{font-size:11px;font-weight:600;letter-spacing:.02em;color:var(--md-sys-color-on-surface-variant)}.runtime-contract-code{display:block;font-family:var(--md-ref-typeface-mono, \"Courier New\", monospace);font-size:12px;line-height:1.45;color:var(--md-sys-color-on-surface);word-break:break-word;white-space:normal}.command-rules-card,.command-rules-card.mat-mdc-card,.command-rules-card.mat-mdc-card-outlined{margin:0!important;padding:20px 16px 24px!important;min-width:0;border:none!important;border-top:1px solid color-mix(in srgb,var(--md-sys-color-outline-variant) 65%,transparent)!important;border-radius:0!important;background:transparent!important;box-shadow:none!important;--mdc-outlined-card-outline-width: 0px;--mdc-outlined-card-outline-color: transparent;--mdc-elevated-card-container-color: transparent;--mdc-outlined-card-container-color: transparent}.command-rules-card>mat-card-content,.command-rules-card>.mat-mdc-card-content{padding:12px 0 0!important}.command-rules-grid{display:grid;grid-template-columns:repeat(auto-fit,minmax(min(260px,100%),1fr));gap:12px;align-items:start;min-width:0}.command-rules-toolbar,.command-rules-options,.command-rules-actions{grid-column:1/-1;display:flex;align-items:center;gap:12px;flex-wrap:wrap}.command-rules-select{min-width:min(320px,100%)}.command-rules-full{grid-column:1/-1}.command-rule-condition-builder{min-height:420px;overflow:hidden;border:1px solid var(--md-sys-color-outline-variant);border-radius:8px;background:var(--md-sys-color-surface-container-low)}.command-rules-payload-fields{display:grid;grid-template-columns:repeat(auto-fit,minmax(min(220px,100%),1fr));gap:12px;min-width:0;padding:12px;border:1px dashed var(--md-sys-color-outline-variant);border-radius:8px;background:var(--md-sys-color-surface-container-low)}.command-rules-section-title{grid-column:1/-1;font-size:12px;font-weight:600;color:var(--md-sys-color-on-surface-variant);text-transform:uppercase}.command-rules-surface-editor{grid-column:1/-1}.command-rule-preview{display:grid;gap:8px;padding:12px;border:1px solid var(--md-sys-color-outline-variant);border-radius:8px;background:var(--md-sys-color-surface)}.command-rule-preview--invalid{border-color:var(--md-sys-color-error)}.command-rule-preview__row{display:grid;grid-template-columns:minmax(96px,.35fr) minmax(0,1fr);gap:8px;align-items:start;min-width:0}.command-rule-preview__row span{color:var(--md-sys-color-on-surface-variant);font-size:12px;font-weight:600}.command-rule-preview__row strong,.command-rule-preview__row code{min-width:0;overflow-wrap:anywhere}.command-rule-preview__diagnostics{display:flex;gap:8px;align-items:flex-start;color:var(--md-sys-color-on-surface-variant)}@container praxis-authoring-editor (max-width: 768px){.mobile-tab-selector{display:block}::ng-deep .mat-mdc-tab-group.config-tabs>.mat-mdc-tab-header{display:none}.tab-content{padding:12px}.json-tab-content{padding:8px}.section-card--json{min-height:auto}}.form-modes{display:flex;flex-direction:column;align-items:flex-start;gap:16px}.form-modes mat-button-toggle-group{max-width:100%;flex-wrap:wrap}.display-result{margin:0;padding-block:12px;color:var(--md-sys-color-on-surface);font:var(--md-sys-typescale-body-medium)}.presentation-preview .presentation-mode.pres-label-above .preview-row{flex-direction:column;gap:4px}.presentation-controls,.control{min-width:0}.control__hint{margin:6px 0 0;color:var(--md-sys-color-on-surface-variant);font:var(--md-sys-typescale-body-small, 400 12px/1.45 sans-serif)}.block-status{flex-wrap:wrap}:host{container-type:inline-size}@container (min-width: 900px){.presentation-layout{grid-template-columns:minmax(0,1fr) minmax(280px,.8fr)}.presentation-preview{order:1;position:sticky;top:16px}}.empty-state-fields{display:grid;align-items:start;grid-template-columns:repeat(auto-fit,minmax(min(100%,240px),1fr));gap:var(--p-space-3, 12px);margin-block-start:var(--p-space-4, 16px)}.empty-state-appearance summary{cursor:pointer;padding-block:var(--p-space-3, 12px);color:var(--md-sys-color-on-surface)}.empty-state-content{grid-template-columns:repeat(auto-fit,minmax(min(100%,320px),1fr))}.empty-state-description{grid-column:1/-1}.empty-state-content mat-form-field{min-width:0}.empty-state-icon-actions{display:inline-flex;align-items:center}\n"] }]
|
|
33475
33756
|
}], ctorParameters: () => [{ type: undefined, decorators: [{
|
|
33476
33757
|
type: Inject,
|
|
33477
33758
|
args: [ASYNC_CONFIG_STORAGE]
|