@praxisui/dynamic-form 9.0.5-rc.2 → 9.0.5-rc.21

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.
@@ -10,7 +10,7 @@ import * as i4 from '@angular/material/icon';
10
10
  import { MatIconModule } from '@angular/material/icon';
11
11
  import * as i3 from '@angular/material/button';
12
12
  import { MatButtonModule } from '@angular/material/button';
13
- import * as i16 from '@angular/material/progress-spinner';
13
+ import * as i17 from '@angular/material/progress-spinner';
14
14
  import { MatProgressSpinnerModule } from '@angular/material/progress-spinner';
15
15
  import * as i5 from '@angular/material/tooltip';
16
16
  import { MatTooltipModule } from '@angular/material/tooltip';
@@ -18,12 +18,12 @@ import * as i2$1 from '@angular/material/dialog';
18
18
  import { MatDialogModule, MatDialog, MAT_DIALOG_DATA } from '@angular/material/dialog';
19
19
  import * as i9 from '@angular/material/snack-bar';
20
20
  import { MatSnackBarModule } from '@angular/material/snack-bar';
21
- import * as i18 from '@angular/material/badge';
21
+ import * as i19 from '@angular/material/badge';
22
22
  import { MatBadgeModule } from '@angular/material/badge';
23
- import { map, firstValueFrom, BehaviorSubject, Subject, throwError, Subscription, combineLatest, debounceTime as debounceTime$1, takeUntil as takeUntil$1 } from 'rxjs';
24
- import { map as map$1, takeUntil, skip, take, timeout, tap, debounceTime, startWith, finalize } from 'rxjs/operators';
23
+ import { map, Subscription, merge, timer, NEVER, EMPTY, defer, TimeoutError, of, Subject, firstValueFrom, BehaviorSubject, throwError, combineLatest, debounceTime as debounceTime$1, takeUntil as takeUntil$1 } from 'rxjs';
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
- import { serializeEntityLookupValueForPayload, PraxisI18nService, PraxisIconButtonComponent, PraxisIconDirective, providePraxisI18nConfig, RULE_PROPERTY_SCHEMA, FIELD_METADATA_CAPABILITIES, migrateFormLayoutRule, PraxisJsonLogicService, normalizeFormLayoutItems, deepMerge, createDefaultFormConfig, normalizeFormConfig as normalizeFormConfig$1, ensureIds, createEmptyRichContentDocument, resolveSpan, resolveGroupedCommandPartialRowSpans, isPraxisRuntimeGlobalActionEffect, ASYNC_CONFIG_STORAGE, withFormConfigSections, createFieldLayoutItem, getFormLayoutFieldNames, LoggerService, createCorporateLoggerConfig, ConsoleLoggerSink, GlobalActionService, ResourceQuickConnectComponent, composeHeadersWithVersion, buildApiUrl, mapFieldDefinitionsToMetadata, reconcileFormConfig, materializeFormLayoutFromMetadata, syncWithServerMetadata, PRAXIS_LOADING_CTX, evaluateFieldAccess, normalizeControlTypeKey, normalizePraxisEffectPolicy, buildPraxisEffectDistinctKey, getFormColumnFieldNames, resolveHidden, resolveOffset, resolveOrder, buildSchemaIdStorageKeySegment, buildSchemaId, fetchWithETag, resolveControlTypeAlias, getTextTransformer, MemoryCacheAdapter, LocalStorageCacheAdapter, SchemaMetadataClient, 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, validateGlobalActionRefs, normalizeFormMetadata } from '@praxisui/core';
26
+ import { serializeEntityLookupValueForPayload, PraxisI18nService, PraxisIconButtonComponent, PraxisIconDirective, providePraxisI18nConfig, RULE_PROPERTY_SCHEMA, FIELD_METADATA_CAPABILITIES, migrateFormLayoutRule, PraxisJsonLogicService, normalizeFormLayoutItems, deepMerge, createDefaultFormConfig, normalizeFormConfig as normalizeFormConfig$1, ensureIds, createEmptyRichContentDocument, resolveHidden, resolveOrder, resolveSpan, projectGroupedCommandPartialRows, isPraxisRuntimeGlobalActionEffect, ASYNC_CONFIG_STORAGE, withFormConfigSections, createFieldLayoutItem, getFormLayoutFieldNames, LoggerService, createCorporateLoggerConfig, ConsoleLoggerSink, GlobalActionService, ResourceQuickConnectComponent, composeHeadersWithVersion, buildApiUrl, mapFieldDefinitionsToMetadata, reconcileFormConfig, materializeFormLayoutFromMetadata, syncWithServerMetadata, PRAXIS_LOADING_CTX, evaluateFieldAccess, normalizeControlTypeKey, normalizePraxisEffectPolicy, buildPraxisEffectDistinctKey, getFormColumnFieldNames, resolveGroupedCommandPartialRowSpans, resolveOffset, buildSchemaIdStorageKeySegment, buildSchemaId, fetchWithETag, resolveControlTypeAlias, getTextTransformer, MemoryCacheAdapter, LocalStorageCacheAdapter, SchemaMetadataClient, 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, validateGlobalActionRefs, normalizeFormMetadata } from '@praxisui/core';
27
27
  import * as i1$1 from '@praxisui/dynamic-fields';
28
28
  import { getControlTypeCatalog, ConfirmDialogComponent, DynamicFieldLoaderDirective } from '@praxisui/dynamic-fields';
29
29
  import { BaseAiAdapter, AgenticAuthoringTurnClientService, PraxisAssistantSessionRegistryService, PraxisAssistantTurnOrchestratorService, createPraxisAssistantViewportLayout, PraxisAiAssistantShellComponent } from '@praxisui/ai';
@@ -33,7 +33,7 @@ import { MatMenuModule } from '@angular/material/menu';
33
33
  import { produce } from 'immer';
34
34
  import * as i7 from '@praxisui/settings-panel';
35
35
  import { SettingsPanelService, SETTINGS_PANEL_DATA, GLOBAL_CONFIG_DYNAMIC_FORM_COMPONENT } from '@praxisui/settings-panel';
36
- import * as i12 from '@angular/router';
36
+ import * as i13 from '@angular/router';
37
37
  import * as i6$3 from '@angular/material/tabs';
38
38
  import { MatTabsModule } from '@angular/material/tabs';
39
39
  import * as i7$1 from '@angular/material/card';
@@ -44,7 +44,7 @@ import * as i6$2 from '@angular/material/select';
44
44
  import { MatSelectModule } from '@angular/material/select';
45
45
  import * as i4$1 from '@angular/material/input';
46
46
  import { MatInputModule } from '@angular/material/input';
47
- import * as i12$1 from '@angular/material/checkbox';
47
+ import * as i12 from '@angular/material/checkbox';
48
48
  import { MatCheckboxModule } from '@angular/material/checkbox';
49
49
  import * as i5$2 from '@angular/material/slide-toggle';
50
50
  import { MatSlideToggleModule } from '@angular/material/slide-toggle';
@@ -193,6 +193,524 @@ i0.ɵɵngDeclareClassMetadata({ minVersion: "12.0.0", version: "21.2.14", ngImpo
193
193
  }]
194
194
  }], ctorParameters: () => [{ type: i1.DomainRuleService }] });
195
195
 
196
+ const DEFAULT_DEBOUNCE_MS = 300;
197
+ const DEFAULT_OPERATION_TIMEOUT_MS = 30_000;
198
+ const SAFE_URL_BASE = 'https://praxis.invalid';
199
+ class EmptyReactiveDeterminationResponseError extends Error {
200
+ }
201
+ class InvalidReactiveDeterminationBindingError extends Error {
202
+ }
203
+ class ReactiveDeterminationCommitError extends Error {
204
+ }
205
+ /** Internal scheduler for Metadata-compiled, backend reactive determinations. */
206
+ class ReactiveDeterminationRuntimeService {
207
+ pendingStateByForm = new WeakMap();
208
+ ownedTargetsByForm = new WeakMap();
209
+ committedControlsByForm = new WeakMap();
210
+ publishingCommitByForm = new WeakSet();
211
+ nextConnectionId = 0;
212
+ hasPending(form) {
213
+ return this.isPending(this.pendingStateByForm.get(form));
214
+ }
215
+ hasUnsatisfied(form) {
216
+ const state = this.pendingStateByForm.get(form);
217
+ return !!state && [...state.determinations.values()].some((item) => !item.satisfied);
218
+ }
219
+ waitForStable(form, timeoutMs = DEFAULT_OPERATION_TIMEOUT_MS) {
220
+ const state = this.pendingStateByForm.get(form);
221
+ if (!this.isPending(state))
222
+ return Promise.resolve(this.isSatisfied(state));
223
+ return new Promise((resolve) => {
224
+ let settled = false;
225
+ const finish = (stable) => {
226
+ if (settled)
227
+ return;
228
+ settled = true;
229
+ clearTimeout(timeoutHandle);
230
+ state?.waiters.delete(finish);
231
+ resolve(stable);
232
+ };
233
+ const timeoutHandle = setTimeout(() => finish(false), Math.max(0, timeoutMs));
234
+ state?.waiters.add(finish);
235
+ });
236
+ }
237
+ observePending(form, observer) {
238
+ const state = this.getOrCreatePendingState(form);
239
+ state.observers.add(observer);
240
+ observer(this.isPending(state));
241
+ return new Subscription(() => state.observers.delete(observer));
242
+ }
243
+ isOwnedTarget(form, control) {
244
+ return this.ownedTargetsByForm.get(form)?.has(control) === true;
245
+ }
246
+ connect(form, definitions, executor, onEvent, operationTimeoutMs = DEFAULT_OPERATION_TIMEOUT_MS) {
247
+ const composite = new Subscription();
248
+ const pendingCorrelations = new Set();
249
+ const publishEvent = (event) => {
250
+ if (event.status === 'pending')
251
+ pendingCorrelations.add(event.correlationId);
252
+ else
253
+ pendingCorrelations.delete(event.correlationId);
254
+ onEvent?.(event);
255
+ };
256
+ const connectionId = ++this.nextConnectionId;
257
+ const definitionIds = new Set();
258
+ const determinationKeyFor = (definitionIndex, definition) => `${connectionId}:${definitionIndex}:${definition.id}`;
259
+ definitions.forEach((definition, definitionIndex) => {
260
+ if (definitionIds.has(definition.id)) {
261
+ publishEvent(this.event(definition, 'skipped', createCorrelationId(), 0, 'duplicate-determination-id'));
262
+ return;
263
+ }
264
+ definitionIds.add(definition.id);
265
+ const determinationKey = determinationKeyFor(definitionIndex, definition);
266
+ let generation = 0;
267
+ let lastSuccessfulFingerprint = null;
268
+ const triggerControls = this.resolveControls(form, definition.trigger.sourcePaths);
269
+ const inputControls = this.resolveControls(form, definition.inputs.map((binding) => binding.fieldPath));
270
+ const targetControls = this.resolveControls(form, definition.outputs.map((binding) => binding.fieldPath));
271
+ const upstreamInputPaths = new Set();
272
+ const upstreamDeterminationKeys = definitions.flatMap((candidate, candidateIndex) => {
273
+ if (candidateIndex === definitionIndex)
274
+ return [];
275
+ const feedsCurrent = definition.inputs.some((binding) => {
276
+ if (!candidate.outputs.some((output) => jsonPointersOverlap(output.fieldPath, binding.fieldPath)))
277
+ return false;
278
+ upstreamInputPaths.add(binding.fieldPath);
279
+ return true;
280
+ });
281
+ return feedsCurrent
282
+ ? [determinationKeyFor(candidateIndex, candidate)]
283
+ : [];
284
+ });
285
+ if (triggerControls.length !== definition.trigger.sourcePaths.length) {
286
+ publishEvent(this.event(definition, 'skipped', createCorrelationId(), 0, 'source-control-missing'));
287
+ return;
288
+ }
289
+ if (inputControls.length !== definition.inputs.length) {
290
+ publishEvent(this.event(definition, 'skipped', createCorrelationId(), 0, 'input-control-missing'));
291
+ return;
292
+ }
293
+ if (targetControls.length !== definition.outputs.length) {
294
+ publishEvent(this.event(definition, 'skipped', createCorrelationId(), 0, 'target-control-missing'));
295
+ return;
296
+ }
297
+ composite.add(this.claimTargets(form, targetControls));
298
+ const triggerControlSet = new Set(triggerControls);
299
+ const observedControls = [...new Set([...triggerControls, ...inputControls])];
300
+ const committedControls$ = this.getOrCreateCommittedControls(form);
301
+ const changes$ = merge(...observedControls.flatMap((control) => [control.valueChanges, control.statusChanges].map((changes) => changes.pipe(filter(() => !this.publishingCommitByForm.has(form)), map$1(() => triggerControlSet.has(control))))), committedControls$.pipe(filter((committedControls) => observedControls.some((control) => committedControls.has(control))), map$1((committedControls) => triggerControls.some((control) => committedControls.has(control)))));
302
+ const determinationSubscription = changes$
303
+ .pipe(map$1((shouldExecute) => {
304
+ const currentGeneration = ++generation;
305
+ const correlationId = createCorrelationId();
306
+ // Publish the new authority before switchMap finalizes the old one.
307
+ this.beginGeneration(form, determinationKey, currentGeneration);
308
+ if (shouldExecute) {
309
+ publishEvent(this.event(definition, 'pending', correlationId, 0));
310
+ }
311
+ else {
312
+ publishEvent(this.event(definition, 'skipped', correlationId, 0, 'input-changed-awaiting-trigger'));
313
+ }
314
+ return { generation: currentGeneration, correlationId, shouldExecute, startedAt: Date.now() };
315
+ }), switchMap((signal) => {
316
+ const generation$ = signal.shouldExecute
317
+ ? timer(DEFAULT_DEBOUNCE_MS).pipe(switchMap(() => this.waitForUpstreamDeterminations(form, upstreamDeterminationKeys)), switchMap((upstreamsSatisfied) => {
318
+ if (triggerControls.some((control) => control.pending)) {
319
+ return NEVER;
320
+ }
321
+ if (triggerControls.some((control) => control.invalid)) {
322
+ publishEvent(this.event(definition, 'skipped', signal.correlationId, 0, 'invalid-source'));
323
+ return EMPTY;
324
+ }
325
+ if (!upstreamsSatisfied ||
326
+ definition.inputs.some((binding) => {
327
+ if (!upstreamInputPaths.has(binding.fieldPath))
328
+ return false;
329
+ const value = form.get(jsonPointerSegments(binding.fieldPath))?.value;
330
+ return value === null || value === undefined;
331
+ })) {
332
+ publishEvent(this.event(definition, 'skipped', signal.correlationId, 0, 'upstream-input-unavailable'));
333
+ return EMPTY;
334
+ }
335
+ let invocation;
336
+ try {
337
+ invocation = this.buildInvocation(form, definition);
338
+ }
339
+ catch {
340
+ publishEvent(this.event(definition, 'error', signal.correlationId, 0, 'request-binding-invalid'));
341
+ return EMPTY;
342
+ }
343
+ if (invocation.fingerprint === lastSuccessfulFingerprint) {
344
+ this.satisfyGeneration(form, determinationKey, signal.generation);
345
+ publishEvent(this.event(definition, 'skipped', signal.correlationId, 0, 'unchanged-inputs'));
346
+ return EMPTY;
347
+ }
348
+ const startedAt = Date.now();
349
+ return defer(() => executor(definition, invocation.body, signal.correlationId)).pipe(take(1), timeout({ first: Math.max(1, operationTimeoutMs) }), throwIfEmpty(() => new EmptyReactiveDeterminationResponseError()), tap((response) => {
350
+ if (!this.isCurrentGeneration(form, determinationKey, signal.generation)) {
351
+ return;
352
+ }
353
+ const commit = this.buildCommit(form, definition, response);
354
+ if (commit === null) {
355
+ publishEvent(this.event(definition, 'error', signal.correlationId, Date.now() - startedAt, 'response-binding-missing'));
356
+ return;
357
+ }
358
+ this.commit(form, commit);
359
+ this.satisfyGeneration(form, determinationKey, signal.generation);
360
+ lastSuccessfulFingerprint = invocation.fingerprint;
361
+ publishEvent(this.event(definition, 'success', signal.correlationId, Date.now() - startedAt, undefined, commit.map((entry) => entry.targetPath)));
362
+ }), catchError((error) => {
363
+ if (this.isCurrentGeneration(form, determinationKey, signal.generation)) {
364
+ const reason = error instanceof TimeoutError
365
+ ? 'operation-timeout'
366
+ : error instanceof EmptyReactiveDeterminationResponseError
367
+ ? 'operation-empty'
368
+ : error instanceof ReactiveDeterminationCommitError
369
+ ? 'commit-failed'
370
+ : 'operation-failed';
371
+ publishEvent(this.event(definition, 'error', signal.correlationId, Date.now() - startedAt, reason));
372
+ }
373
+ return EMPTY;
374
+ }), ignoreElements());
375
+ }))
376
+ : EMPTY;
377
+ return generation$.pipe(finalize(() => {
378
+ if (pendingCorrelations.has(signal.correlationId)) {
379
+ publishEvent(this.event(definition, 'skipped', signal.correlationId, Date.now() - signal.startedAt, 'superseded'));
380
+ }
381
+ this.finishGeneration(form, determinationKey, signal.generation);
382
+ }));
383
+ }))
384
+ .subscribe();
385
+ composite.add(determinationSubscription);
386
+ composite.add(() => this.clearDeterminationState(form, determinationKey));
387
+ });
388
+ return composite;
389
+ }
390
+ resolveControls(form, pointers) {
391
+ return pointers
392
+ .map((pointer) => form.get(jsonPointerSegments(pointer)))
393
+ .filter((control) => !!control);
394
+ }
395
+ waitForUpstreamDeterminations(form, upstreamKeys) {
396
+ const state = this.getOrCreatePendingState(form);
397
+ const hasPendingUpstream = () => upstreamKeys.some((key) => state.determinations.get(key)?.pending === true);
398
+ const upstreamsSatisfied = () => upstreamKeys.every((key) => {
399
+ const upstream = state.determinations.get(key);
400
+ return !upstream || upstream.satisfied;
401
+ });
402
+ if (!hasPendingUpstream())
403
+ return of(upstreamsSatisfied());
404
+ return state.transitions.pipe(filter(() => !hasPendingUpstream()), take(1), map$1(() => upstreamsSatisfied()));
405
+ }
406
+ claimTargets(form, controls) {
407
+ let states = this.ownedTargetsByForm.get(form);
408
+ if (!states) {
409
+ states = new Map();
410
+ this.ownedTargetsByForm.set(form, states);
411
+ }
412
+ const claimed = [...new Set(controls)];
413
+ claimed.forEach((control) => {
414
+ const current = states?.get(control);
415
+ if (current) {
416
+ current.references += 1;
417
+ }
418
+ else {
419
+ states?.set(control, { references: 1, initiallyDisabled: control.disabled });
420
+ control.disable({ emitEvent: false });
421
+ }
422
+ });
423
+ return () => {
424
+ const currentStates = this.ownedTargetsByForm.get(form);
425
+ claimed.forEach((control) => {
426
+ const current = currentStates?.get(control);
427
+ if (!current)
428
+ return;
429
+ current.references -= 1;
430
+ if (current.references > 0)
431
+ return;
432
+ currentStates?.delete(control);
433
+ if (!current.initiallyDisabled)
434
+ control.enable({ emitEvent: false });
435
+ });
436
+ if (currentStates?.size === 0)
437
+ this.ownedTargetsByForm.delete(form);
438
+ };
439
+ }
440
+ buildInvocation(form, definition) {
441
+ const body = Object.create(null);
442
+ const fingerprintValues = [];
443
+ for (const binding of definition.inputs) {
444
+ const control = form.get(jsonPointerSegments(binding.fieldPath));
445
+ if (!control || !writeJsonPointer(body, binding.requestPath, control.value)) {
446
+ throw new InvalidReactiveDeterminationBindingError();
447
+ }
448
+ fingerprintValues.push(control.value);
449
+ }
450
+ return { body, fingerprint: stableFingerprint(fingerprintValues) };
451
+ }
452
+ buildCommit(form, definition, response) {
453
+ if (!response || typeof response !== 'object' || Array.isArray(response))
454
+ return null;
455
+ const entries = [];
456
+ for (const binding of definition.outputs) {
457
+ const responseValue = readJsonPointer(response, binding.responsePath);
458
+ const control = form.get(jsonPointerSegments(binding.fieldPath));
459
+ if (!responseValue.found || !control)
460
+ return null;
461
+ entries.push({
462
+ targetPath: binding.fieldPath,
463
+ control,
464
+ value: responseValue.value,
465
+ previousValue: control.value,
466
+ });
467
+ }
468
+ return entries;
469
+ }
470
+ commit(form, entries) {
471
+ // Reactive Determination outputs have one closed semantic: server-derived
472
+ // draft values. Metadata cannot choose an overwrite policy.
473
+ const applied = [];
474
+ try {
475
+ for (const entry of entries) {
476
+ entry.control.setValue(entry.value, { onlySelf: true, emitEvent: false });
477
+ applied.push(entry);
478
+ }
479
+ }
480
+ catch {
481
+ // Angular does not provide a transaction across controls. Restore every
482
+ // previously written control before exposing the terminal diagnostic.
483
+ for (const entry of applied.reverse()) {
484
+ try {
485
+ entry.control.setValue(entry.previousValue, { onlySelf: true, emitEvent: false });
486
+ }
487
+ catch { }
488
+ }
489
+ form.updateValueAndValidity({ emitEvent: false });
490
+ throw new ReactiveDeterminationCommitError();
491
+ }
492
+ for (const entry of entries) {
493
+ entry.control.updateValueAndValidity({ onlySelf: true, emitEvent: false });
494
+ }
495
+ if (!entries.length)
496
+ return;
497
+ form.updateValueAndValidity({ emitEvent: false });
498
+ this.publishingCommitByForm.add(form);
499
+ try {
500
+ // External observers retain the normal Angular notifications, but every
501
+ // observer sees the fully committed draft. Runtime subscribers suppress
502
+ // these per-control emissions and receive one logical batch below.
503
+ for (const entry of entries) {
504
+ entry.control.updateValueAndValidity({ onlySelf: true, emitEvent: true });
505
+ }
506
+ form.updateValueAndValidity({ emitEvent: true });
507
+ }
508
+ finally {
509
+ this.publishingCommitByForm.delete(form);
510
+ }
511
+ this.getOrCreateCommittedControls(form).next(new Set(entries.map((entry) => entry.control)));
512
+ }
513
+ getOrCreateCommittedControls(form) {
514
+ const current = this.committedControlsByForm.get(form);
515
+ if (current)
516
+ return current;
517
+ const created = new Subject();
518
+ this.committedControlsByForm.set(form, created);
519
+ return created;
520
+ }
521
+ event(definition, status, correlationId, durationMs, reason, appliedTargetPaths) {
522
+ return {
523
+ determinationId: definition.id,
524
+ operationId: definition.capability.operationId,
525
+ status,
526
+ sourcePaths: [...definition.trigger.sourcePaths],
527
+ targetPaths: definition.outputs.map((binding) => binding.fieldPath),
528
+ correlationId,
529
+ durationMs,
530
+ provenance: { ...definition.provenance },
531
+ ...(reason ? { reason } : {}),
532
+ ...(appliedTargetPaths ? { appliedTargetPaths } : {}),
533
+ };
534
+ }
535
+ getOrCreatePendingState(form) {
536
+ const current = this.pendingStateByForm.get(form);
537
+ if (current)
538
+ return current;
539
+ const created = {
540
+ determinations: new Map(),
541
+ waiters: new Set(),
542
+ observers: new Set(),
543
+ transitions: new Subject(),
544
+ lastPending: false,
545
+ };
546
+ this.pendingStateByForm.set(form, created);
547
+ return created;
548
+ }
549
+ beginGeneration(form, key, generation) {
550
+ const state = this.getOrCreatePendingState(form);
551
+ state.determinations.set(key, { generation, pending: true, satisfied: false });
552
+ state.transitions.next();
553
+ this.notifyPendingChange(state);
554
+ }
555
+ satisfyGeneration(form, key, generation) {
556
+ const determinationState = this.pendingStateByForm
557
+ .get(form)
558
+ ?.determinations.get(key);
559
+ if (!determinationState || determinationState.generation !== generation)
560
+ return;
561
+ determinationState.satisfied = true;
562
+ }
563
+ finishGeneration(form, key, generation) {
564
+ const state = this.pendingStateByForm.get(form);
565
+ const determinationState = state?.determinations.get(key);
566
+ if (!state || !determinationState || determinationState.generation !== generation)
567
+ return;
568
+ determinationState.pending = false;
569
+ state.transitions.next();
570
+ this.notifyPendingChange(state);
571
+ this.notifyIfStable(state);
572
+ }
573
+ clearDeterminationState(form, key) {
574
+ const state = this.pendingStateByForm.get(form);
575
+ if (!state)
576
+ return;
577
+ state.determinations.delete(key);
578
+ state.transitions.next();
579
+ this.notifyPendingChange(state);
580
+ this.notifyIfStable(state);
581
+ }
582
+ isCurrentGeneration(form, key, generation) {
583
+ return this.pendingStateByForm.get(form)?.determinations.get(key)?.generation === generation;
584
+ }
585
+ isPending(state) {
586
+ return !!state && [...state.determinations.values()].some((item) => item.pending);
587
+ }
588
+ isSatisfied(state) {
589
+ return !state || [...state.determinations.values()].every((item) => item.satisfied);
590
+ }
591
+ notifyIfStable(state) {
592
+ if (this.isPending(state))
593
+ return;
594
+ const waiters = [...state.waiters];
595
+ state.waiters.clear();
596
+ const satisfied = this.isSatisfied(state);
597
+ waiters.forEach((waiter) => waiter(satisfied));
598
+ }
599
+ notifyPendingChange(state) {
600
+ const pending = this.isPending(state);
601
+ if (pending === state.lastPending)
602
+ return;
603
+ state.lastPending = pending;
604
+ [...state.observers].forEach((observer) => observer(pending));
605
+ }
606
+ static ɵfac = i0.ɵɵngDeclareFactory({ minVersion: "12.0.0", version: "21.2.14", ngImport: i0, type: ReactiveDeterminationRuntimeService, deps: [], target: i0.ɵɵFactoryTarget.Injectable });
607
+ static ɵprov = i0.ɵɵngDeclareInjectable({ minVersion: "12.0.0", version: "21.2.14", ngImport: i0, type: ReactiveDeterminationRuntimeService, providedIn: 'root' });
608
+ }
609
+ i0.ɵɵngDeclareClassMetadata({ minVersion: "12.0.0", version: "21.2.14", ngImport: i0, type: ReactiveDeterminationRuntimeService, decorators: [{
610
+ type: Injectable,
611
+ args: [{ providedIn: 'root' }]
612
+ }] });
613
+ function resolveReactiveDeterminationHref(href, apiOrigin) {
614
+ const normalizedHref = String(href || '').trim();
615
+ if (!isSafeOperationPath(normalizedHref)) {
616
+ throw new Error('Unsafe reactive determination capability href.');
617
+ }
618
+ const normalizedOrigin = String(apiOrigin || '').trim().replace(/\/+$/, '');
619
+ if (!normalizedOrigin)
620
+ return normalizedHref;
621
+ let originUrl;
622
+ let resolvedUrl;
623
+ try {
624
+ originUrl = new URL(normalizedOrigin);
625
+ resolvedUrl = new URL(normalizedHref, `${originUrl.origin}/`);
626
+ }
627
+ catch {
628
+ throw new Error('Invalid reactive determination API origin.');
629
+ }
630
+ if (resolvedUrl.origin !== originUrl.origin) {
631
+ throw new Error('Cross-origin reactive determination capability.');
632
+ }
633
+ return resolvedUrl.toString();
634
+ }
635
+ function jsonPointerSegments(pointer) {
636
+ if (!/^\/(?!\/)(?:[^/~]|~[01])+(?:\/(?:[^/~]|~[01])+)*$/.test(pointer)) {
637
+ throw new InvalidReactiveDeterminationBindingError();
638
+ }
639
+ return pointer.slice(1).split('/').map((segment) => segment.replace(/~1/g, '/').replace(/~0/g, '~'));
640
+ }
641
+ function jsonPointersOverlap(left, right) {
642
+ const leftSegments = jsonPointerSegments(left);
643
+ const rightSegments = jsonPointerSegments(right);
644
+ const shorter = Math.min(leftSegments.length, rightSegments.length);
645
+ for (let index = 0; index < shorter; index += 1) {
646
+ if (leftSegments[index] !== rightSegments[index])
647
+ return false;
648
+ }
649
+ return true;
650
+ }
651
+ function writeJsonPointer(target, pointer, value) {
652
+ const segments = jsonPointerSegments(pointer);
653
+ let current = target;
654
+ for (let index = 0; index < segments.length - 1; index += 1) {
655
+ const segment = segments[index];
656
+ const hasExisting = Object.prototype.hasOwnProperty.call(current, segment);
657
+ const existing = hasExisting ? current[segment] : undefined;
658
+ if (!hasExisting) {
659
+ const nested = Object.create(null);
660
+ current[segment] = nested;
661
+ current = nested;
662
+ continue;
663
+ }
664
+ if (!existing || typeof existing !== 'object' || Array.isArray(existing))
665
+ return false;
666
+ current = existing;
667
+ }
668
+ const leaf = segments[segments.length - 1];
669
+ if (Object.prototype.hasOwnProperty.call(current, leaf))
670
+ return false;
671
+ current[leaf] = value;
672
+ return true;
673
+ }
674
+ function readJsonPointer(source, pointer) {
675
+ const segments = jsonPointerSegments(pointer);
676
+ let current = source;
677
+ for (const segment of segments) {
678
+ if (!current || typeof current !== 'object' || Array.isArray(current))
679
+ return { found: false };
680
+ if (!Object.prototype.hasOwnProperty.call(current, segment))
681
+ return { found: false };
682
+ current = current[segment];
683
+ }
684
+ return { found: true, value: current };
685
+ }
686
+ function isSafeOperationPath(path) {
687
+ if (!path.startsWith('/') || path.startsWith('//') || path.includes('\\') || path.includes('?') ||
688
+ path.includes('#') || path.includes('{') || path.includes('}') ||
689
+ /[\u0000-\u001f\u007f]/.test(path) || /%(?:2f|5c)/i.test(path))
690
+ return false;
691
+ try {
692
+ return new URL(path, SAFE_URL_BASE).origin === SAFE_URL_BASE;
693
+ }
694
+ catch {
695
+ return false;
696
+ }
697
+ }
698
+ function stableFingerprint(value) {
699
+ try {
700
+ return JSON.stringify(value);
701
+ }
702
+ catch {
703
+ return String(value);
704
+ }
705
+ }
706
+ function createCorrelationId() {
707
+ const runtimeCrypto = globalThis.crypto;
708
+ if (runtimeCrypto && typeof runtimeCrypto.randomUUID === 'function') {
709
+ return runtimeCrypto.randomUUID();
710
+ }
711
+ return `reactive-determination-${Date.now()}-${Math.random().toString(16).slice(2)}`;
712
+ }
713
+
196
714
  /**
197
715
  * Recursively converts arrays representing dates into ISO-8601 strings.
198
716
  * Arrays are expected in the form `[year, month, day, hour?, minute?, second?, millisecond?]`.
@@ -631,6 +1149,11 @@ const PRAXIS_DYNAMIC_FORM_I18N_CONFIG = {
631
1149
  'layout.defaultSectionTitle': 'Informações',
632
1150
  'actions.invalidRequired': 'Preencha os campos obrigatórios para continuar.',
633
1151
  'actions.invalidRequiredWithFields': 'Preencha: {{fields}}.',
1152
+ 'runtime.reactiveDetermination.error': 'Não foi possível atualizar os campos relacionados. Revise os dados ou tente novamente.',
1153
+ 'runtime.reactiveDetermination.submitPending': 'Aguarde a atualização dos campos relacionados antes de salvar.',
1154
+ 'runtime.reactiveDetermination.submitTimeout': 'Os campos relacionados não estabilizaram a tempo. Revise os dados e tente salvar novamente.',
1155
+ 'runtime.reactiveDetermination.submitUnsatisfied': 'Os campos relacionados não foram atualizados com sucesso. Revise os dados e tente novamente.',
1156
+ 'common.dismiss': 'Fechar',
634
1157
  'config.tabs.mobileLabel': 'Seção do editor',
635
1158
  'config.tabs.general': 'Geral',
636
1159
  'config.tabs.schema': 'Verificação de Schema',
@@ -1116,6 +1639,11 @@ const PRAXIS_DYNAMIC_FORM_I18N_CONFIG = {
1116
1639
  ]`,
1117
1640
  },
1118
1641
  'en-US': {
1642
+ 'runtime.reactiveDetermination.error': 'Related fields could not be updated. Review the data or try again.',
1643
+ 'runtime.reactiveDetermination.submitPending': 'Wait for related fields to finish updating before saving.',
1644
+ 'runtime.reactiveDetermination.submitTimeout': 'Related fields did not stabilize in time. Review the data and try saving again.',
1645
+ 'runtime.reactiveDetermination.submitUnsatisfied': 'Related fields were not updated successfully. Review the data and try again.',
1646
+ 'common.dismiss': 'Dismiss',
1119
1647
  'settings.title': 'Form Configuration',
1120
1648
  'layout.defaultSectionTitle': 'Information',
1121
1649
  'actions.invalidRequired': 'Complete the required fields to continue.',
@@ -6032,7 +6560,7 @@ const PRAXIS_DYNAMIC_FORM_AUTHORING_MANIFEST = {
6032
6560
  { name: 'mode', type: 'string', allowedValues: ['create', 'edit', 'view'], description: 'Modo de operação' },
6033
6561
  { name: 'configPersistenceStrategy', type: 'string', allowedValues: ['local-first', 'input-first'], description: 'Precedência entre configuração persistida e contrato explícito do host. Use input-first em dialogs e surfaces transitórias governadas por schema para preservar mode e estados operacionais publicados pelo servidor.' },
6034
6562
  { name: 'generatedLayoutPreset', type: 'string', allowedValues: ['default', 'compactPresentation'], description: 'Preset usado apenas ao gerar a configuracao inicial a partir de metadata/schema; nao reprocessa layouts persistidos ou autorados.' },
6035
- { name: 'layoutPolicy', type: 'DynamicFormLayoutPolicy', description: 'Politica opt-in para layout schema-driven transient. Use source=schema apenas quando o backend schema for a fonte canonica do agrupamento; use detailSummary para seleção de campos e densidade responsiva do resumo read-only compacto sem FormConfig.sections locais. Quando o resumo precisar vencer x-ui.width publicado para outras surfaces, use detailSummary.widthPrecedence=summary. Em groupedCommand, orphanFieldExpansion governa linhas com um unico campo; partialRowStrategy=fill-compatible projeta spans compatíveis para completar a linha no breakpoint atual sem alterar x-ui.width ou persistir sections; contextFields identifica campos do request hidratados pela surface que permanecem no payload sem criar controles redundantes.' },
6563
+ { name: 'layoutPolicy', type: 'DynamicFormLayoutPolicy', description: 'Politica opt-in para layout schema-driven transient. Use source=schema apenas quando o backend schema for a fonte canonica do agrupamento; use detailSummary para seleção de campos e densidade responsiva do resumo read-only compacto sem FormConfig.sections locais. Quando o resumo precisar vencer x-ui.width publicado para outras surfaces, use detailSummary.widthPrecedence=summary. Em groupedCommand, orphanFieldExpansion governa linhas lógicas com um unico campo; partialRowStrategy=fill-compatible projeta spans compatíveis depois de resolver visibilidade responsiva, CSS order e wrap, sem alterar x-ui.width ou persistir sections; contextFields identifica campos do request hidratados pela surface que permanecem no payload sem criar controles redundantes.' },
6036
6564
  { name: 'fieldIconPolicy', type: 'string', allowedValues: ['all', 'presentation-only', 'none'], description: 'Politica visual do host para icones prefix/suffix de campos vindos da metadata. Use presentation-only para manter icones decorativos em apresentacao e ocultar em controles tradicionais.' },
6037
6565
  { name: 'enableCustomization', type: 'boolean', description: 'Habilita edição visual' }
6038
6566
  ],
@@ -8223,18 +8751,28 @@ function diagnoseIncompleteGroupedCommandRows(config, diagnostics) {
8223
8751
  return;
8224
8752
  const incomplete = ['md', 'lg', 'xl']
8225
8753
  .map((breakpoint) => {
8226
- const candidates = row.columns.map((column) => ({
8754
+ const candidates = row.columns
8755
+ .filter((column) => !resolveHidden(column?.hidden)[breakpoint])
8756
+ .map((column) => ({
8227
8757
  span: resolveSpan(column?.span)[breakpoint],
8758
+ order: resolveOrder(column?.order)[breakpoint],
8228
8759
  controlType: metadataByName.get(column.fields?.[0] || '')?.controlType,
8229
8760
  }));
8230
- const resolved = resolveGroupedCommandPartialRowSpans(candidates, strategy);
8761
+ const projection = projectGroupedCommandPartialRows(candidates, strategy);
8762
+ const partialRow = projection.visualRows.find((visualRow) => {
8763
+ const occupied = visualRow.canonicalSpans.reduce((total, span) => total + span, 0);
8764
+ const effective = visualRow.projectedSpans.reduce((total, span) => total + span, 0);
8765
+ return occupied < 12 && effective < 12;
8766
+ });
8767
+ if (!partialRow)
8768
+ return null;
8231
8769
  return {
8232
8770
  breakpoint,
8233
- occupied: candidates.reduce((total, candidate) => total + candidate.span, 0),
8234
- effective: resolved.reduce((total, span) => total + span, 0),
8771
+ occupied: partialRow.canonicalSpans.reduce((total, span) => total + span, 0),
8772
+ effective: partialRow.projectedSpans.reduce((total, span) => total + span, 0),
8235
8773
  };
8236
8774
  })
8237
- .find((result) => result.occupied < 12 && result.effective < 12);
8775
+ .find((result) => result != null);
8238
8776
  if (!incomplete)
8239
8777
  return;
8240
8778
  diagnostics.push(warnDiagnostic('dynamicForm.config.layout.groupedCommand.row.incomplete', strategy === 'fill-compatible'
@@ -10551,6 +11089,23 @@ i0.ɵɵngDeclareClassMetadata({ minVersion: "12.0.0", version: "21.2.14", ngImpo
10551
11089
  args: [{ providedIn: 'root' }]
10552
11090
  }] });
10553
11091
 
11092
+ function exactSchemaOperationId(schema, rootUi) {
11093
+ const records = [rootUi, schema].filter((value) => !!value && typeof value === 'object' && !Array.isArray(value));
11094
+ for (const record of records) {
11095
+ for (const key of ['schemaOperationId', 'operationId', 'x-operation-id']) {
11096
+ const value = record[key];
11097
+ if (typeof value === 'string' && value.trim())
11098
+ return value.trim();
11099
+ }
11100
+ }
11101
+ return null;
11102
+ }
11103
+ class PraxisDynamicFormDestroyedError extends Error {
11104
+ constructor() {
11105
+ super('PraxisDynamicForm was destroyed while asynchronous runtime work was pending.');
11106
+ this.name = 'PraxisDynamicFormDestroyedError';
11107
+ }
11108
+ }
10554
11109
  const FORM_CONFIG_LOAD_TIMEOUT_MS = 1200;
10555
11110
  const FORM_INPUT_PREFS_LOAD_TIMEOUT_MS = 1200;
10556
11111
  const SCHEMA_GLOBAL_CONFIG_READY_TIMEOUT_MS = 1200;
@@ -10571,6 +11126,7 @@ class PraxisDynamicForm {
10571
11126
  snackBar;
10572
11127
  canvasState;
10573
11128
  dynamicLayout;
11129
+ reactiveDeterminationRuntime;
10574
11130
  errorMessages;
10575
11131
  schemaNormalizer;
10576
11132
  componentMetaRegistry;
@@ -10913,9 +11469,15 @@ class PraxisDynamicForm {
10913
11469
  fieldRenderError = new EventEmitter();
10914
11470
  /** Emits runtime rule diagnostics so hosts can surface or log invalid rules. */
10915
11471
  ruleDiagnosticsChange = new EventEmitter();
11472
+ /** Emits metadata-only diagnostics for backend-owned form determinations. */
11473
+ reactiveDeterminationExecuted = new EventEmitter();
11474
+ /** Emits only aggregate runtime state; no request or response payload is exposed. */
11475
+ reactiveDeterminationPendingChange = new EventEmitter();
11476
+ reactiveDeterminationPending = false;
10916
11477
  // Estado interno para UX
10917
11478
  isLoading = false;
10918
11479
  submitting = false;
11480
+ submitPreparationInProgress = false;
10919
11481
  submitError = null;
10920
11482
  initializationStatus = 'idle';
10921
11483
  currentErrorMessage = '';
@@ -10975,8 +11537,13 @@ class PraxisDynamicForm {
10975
11537
  formConfigPersistenceGenerations = new Map();
10976
11538
  formConfigConflictBlockThrough = new Map();
10977
11539
  schemaRootHooks;
11540
+ schemaRootReactiveDeterminations = [];
11541
+ schemaRootOperationId = null;
10978
11542
  destroy$ = new Subject();
11543
+ isDestroyed = false;
10979
11544
  formValueChangesSubscription = null;
11545
+ reactiveDeterminationSubscription = null;
11546
+ reactiveDeterminationScheduledBuildId = 0;
10980
11547
  dependencyPolicySubscription = null;
10981
11548
  formBuildCycleId = 0;
10982
11549
  suppressedValueChangeBuildId = 0;
@@ -11327,7 +11894,7 @@ class PraxisDynamicForm {
11327
11894
  // programmatically before the first ngOnInit/detectChanges cycle.
11328
11895
  hasBuiltFormFromConfig = false;
11329
11896
  runtimeFieldMetadata = null;
11330
- constructor(crud, http, fb, cdr, layoutService, contextService, rulesService, settingsPanel, dialog, asyncConfigStorage, connectionStorage, dynamicForm, snackBar, canvasState, dynamicLayout, errorMessages, schemaNormalizer, componentMetaRegistry, global, componentKeys, loadingOrchestrator, ngZone, apiUrlConfig, loadingRenderer, router, route, hooksRegistry, hookPresets, logger, enterpriseRuntimeContext) {
11897
+ constructor(crud, http, fb, cdr, layoutService, contextService, rulesService, settingsPanel, dialog, asyncConfigStorage, connectionStorage, dynamicForm, snackBar, canvasState, dynamicLayout, reactiveDeterminationRuntime, errorMessages, schemaNormalizer, componentMetaRegistry, global, componentKeys, loadingOrchestrator, ngZone, apiUrlConfig, loadingRenderer, router, route, hooksRegistry, hookPresets, logger, enterpriseRuntimeContext) {
11331
11898
  this.crud = crud;
11332
11899
  this.http = http;
11333
11900
  this.fb = fb;
@@ -11343,6 +11910,7 @@ class PraxisDynamicForm {
11343
11910
  this.snackBar = snackBar;
11344
11911
  this.canvasState = canvasState;
11345
11912
  this.dynamicLayout = dynamicLayout;
11913
+ this.reactiveDeterminationRuntime = reactiveDeterminationRuntime;
11346
11914
  this.errorMessages = errorMessages;
11347
11915
  this.schemaNormalizer = schemaNormalizer;
11348
11916
  this.componentMetaRegistry = componentMetaRegistry;
@@ -12019,6 +12587,8 @@ class PraxisDynamicForm {
12019
12587
  catch { }
12020
12588
  }
12021
12589
  async initializeForm() {
12590
+ if (this.isDestroyed)
12591
+ return;
12022
12592
  this.debugLog('[PDF] initializeForm:start', {
12023
12593
  isInitialized: this.isInitialized,
12024
12594
  isLoading: this.isLoading,
@@ -12046,6 +12616,8 @@ class PraxisDynamicForm {
12046
12616
  this.emitLoadingState('config', 'loading', 'Carregando configuração do formulário...');
12047
12617
  // Hooks: beforeInit
12048
12618
  await this.runHooks('beforeInit');
12619
+ if (this.isDestroyed)
12620
+ return;
12049
12621
  try {
12050
12622
  // Step 1: Check for saved config
12051
12623
  const configKey = this.formConfigKey();
@@ -12113,6 +12685,8 @@ class PraxisDynamicForm {
12113
12685
  this.cdr.detectChanges();
12114
12686
  }
12115
12687
  catch (error) {
12688
+ if (this.isDestroyed || error instanceof PraxisDynamicFormDestroyedError)
12689
+ return;
12116
12690
  this.errorLog('[PDF] initializeForm:error', error);
12117
12691
  const key = this.formConfigKey();
12118
12692
  const hasLocalConfig = key
@@ -12125,11 +12699,15 @@ class PraxisDynamicForm {
12125
12699
  });
12126
12700
  }
12127
12701
  finally {
12128
- this.isLoading = false;
12129
- this.cdr.detectChanges();
12702
+ if (!this.isDestroyed) {
12703
+ this.isLoading = false;
12704
+ this.cdr.detectChanges();
12705
+ }
12130
12706
  }
12131
12707
  }
12132
12708
  handleInitializationError(stage, error, context) {
12709
+ if (this.isDestroyed || error instanceof PraxisDynamicFormDestroyedError)
12710
+ return;
12133
12711
  this.initializationStatus = 'error';
12134
12712
  this.isLoading = false;
12135
12713
  this.cdr.detectChanges();
@@ -12459,6 +13037,7 @@ class PraxisDynamicForm {
12459
13037
  this.hydratedEntityId = this.pendingEntityId;
12460
13038
  this.debugLog('[PDF] loadEntity:repatch', { id: this.pendingEntityId });
12461
13039
  this.flushEntityHydrationState();
13040
+ this.scheduleReactiveDeterminationsActivation(this.formBuildCycleId);
12462
13041
  }
12463
13042
  else {
12464
13043
  this.debugLog('[PDF] loadEntity:duplicate', {
@@ -12506,6 +13085,7 @@ class PraxisDynamicForm {
12506
13085
  });
12507
13086
  this.emitLoadingState('data', 'success', 'Dados carregados.');
12508
13087
  this.flushEntityHydrationState();
13088
+ this.scheduleReactiveDeterminationsActivation(this.formBuildCycleId);
12509
13089
  }
12510
13090
  else {
12511
13091
  this.warnLog('Invalid entity data received:', data, { actionId: 'entity.load', throttleKey: 'praxis-dynamic-form:invalid-entity-data' });
@@ -12535,6 +13115,7 @@ class PraxisDynamicForm {
12535
13115
  this.debugLog('[PDF] loadEntity:initialValue', { id: this.pendingEntityId });
12536
13116
  this.emitLoadingState('data', 'success', 'Dados carregados.');
12537
13117
  this.flushEntityHydrationState();
13118
+ this.scheduleReactiveDeterminationsActivation(this.formBuildCycleId);
12538
13119
  return true;
12539
13120
  }
12540
13121
  flushEntityHydrationState() {
@@ -12553,6 +13134,7 @@ class PraxisDynamicForm {
12553
13134
  ? this.captureFormRuntimeState()
12554
13135
  : null;
12555
13136
  const buildCycleId = ++this.formBuildCycleId;
13137
+ this.resetReactiveDeterminationSubscription();
12556
13138
  this.fieldVisibility = {}; // Reset visibility state
12557
13139
  const mountCtx = this.buildLoadingContext('mount', 'Montando interface...', false);
12558
13140
  this.beginLoading(mountCtx);
@@ -12610,7 +13192,7 @@ class PraxisDynamicForm {
12610
13192
  }
12611
13193
  catch { }
12612
13194
  }
12613
- const currentValues = this.form.value;
13195
+ const currentValues = this.form.getRawValue();
12614
13196
  this.valueChange.emit({
12615
13197
  formData: currentValues,
12616
13198
  changedFields: Object.keys(currentValues),
@@ -12630,6 +13212,7 @@ class PraxisDynamicForm {
12630
13212
  fields: this.config.fieldMetadata?.length,
12631
13213
  });
12632
13214
  this.scheduleValueChangeBootstrapRelease(buildCycleId);
13215
+ this.scheduleReactiveDeterminationsActivation(buildCycleId);
12633
13216
  this.hasBuiltFormFromConfig = true;
12634
13217
  }
12635
13218
  finally {
@@ -12646,6 +13229,73 @@ class PraxisDynamicForm {
12646
13229
  this.suppressedValueChangeBuildId = buildCycleId;
12647
13230
  this.pendingBootstrapValueChangeBuildId = 0;
12648
13231
  }
13232
+ resetReactiveDeterminationSubscription() {
13233
+ this.reactiveDeterminationSubscription?.unsubscribe();
13234
+ this.reactiveDeterminationSubscription = null;
13235
+ this.reactiveDeterminationScheduledBuildId = 0;
13236
+ this.setReactiveDeterminationPending(false);
13237
+ }
13238
+ scheduleReactiveDeterminationsActivation(buildCycleId) {
13239
+ if (this.mode === 'view' ||
13240
+ !this.schemaRootReactiveDeterminations.length ||
13241
+ !this.form ||
13242
+ buildCycleId !== this.formBuildCycleId ||
13243
+ (this.pendingEntityId != null && this.hydratedEntityId !== this.pendingEntityId) ||
13244
+ this.reactiveDeterminationScheduledBuildId === buildCycleId) {
13245
+ return;
13246
+ }
13247
+ this.reactiveDeterminationScheduledBuildId = buildCycleId;
13248
+ queueMicrotask(() => {
13249
+ if (buildCycleId !== this.formBuildCycleId ||
13250
+ this.mode === 'view' ||
13251
+ (this.pendingEntityId != null && this.hydratedEntityId !== this.pendingEntityId)) {
13252
+ if (this.reactiveDeterminationScheduledBuildId === buildCycleId) {
13253
+ this.reactiveDeterminationScheduledBuildId = 0;
13254
+ }
13255
+ return;
13256
+ }
13257
+ this.reactiveDeterminationSubscription?.unsubscribe();
13258
+ const connection = new Subscription();
13259
+ connection.add(this.reactiveDeterminationRuntime.connect(this.form, this.schemaRootReactiveDeterminations.filter((definition) => definition.scope.formMode === this.mode
13260
+ && (!this.schemaRootOperationId
13261
+ || definition.scope.schemaOperationId === this.schemaRootOperationId)), (definition, requestBody, correlationId) => {
13262
+ let headers = composeHeadersWithVersion(this.resolveApiEntry()) ?? new HttpHeaders();
13263
+ headers = headers.set('X-Correlation-Id', correlationId);
13264
+ return this.http
13265
+ .post(resolveReactiveDeterminationHref(definition.capability.href, this.resolveApiOrigin()), requestBody, { headers })
13266
+ .pipe(map$1((response) => this.unwrapRestApiResponse(response)));
13267
+ }, (event) => this.handleReactiveDeterminationExecutionEvent(event)));
13268
+ connection.add(this.reactiveDeterminationRuntime.observePending(this.form, (pending) => this.setReactiveDeterminationPending(pending)));
13269
+ this.reactiveDeterminationSubscription = connection;
13270
+ });
13271
+ }
13272
+ /** True while at least one backend Reactive Determination is unsettled. */
13273
+ hasPendingReactiveDeterminations() {
13274
+ return !!this.form && this.reactiveDeterminationRuntime.hasPending(this.form);
13275
+ }
13276
+ /** True when the latest settled generation failed or could not derive a current draft. */
13277
+ hasUnsatisfiedReactiveDeterminations() {
13278
+ return !!this.form && this.reactiveDeterminationRuntime.hasUnsatisfied(this.form);
13279
+ }
13280
+ /** Resolves true only when the latest generations settled successfully/current. */
13281
+ waitForReactiveDeterminations(timeoutMs) {
13282
+ if (!this.form)
13283
+ return Promise.resolve(true);
13284
+ return this.reactiveDeterminationRuntime.waitForStable(this.form, timeoutMs);
13285
+ }
13286
+ setReactiveDeterminationPending(pending) {
13287
+ if (this.reactiveDeterminationPending === pending)
13288
+ return;
13289
+ this.reactiveDeterminationPending = pending;
13290
+ this.reactiveDeterminationPendingChange.emit(pending);
13291
+ this.cdr.markForCheck();
13292
+ }
13293
+ handleReactiveDeterminationExecutionEvent(event) {
13294
+ this.reactiveDeterminationExecuted.emit(event);
13295
+ if (event.status !== 'error')
13296
+ return;
13297
+ this.snackBar.open(this.i18n.t('runtime.reactiveDetermination.error', undefined, 'Não foi possível atualizar os campos relacionados. Revise os dados ou tente novamente.', PRAXIS_DYNAMIC_FORM_I18N_NAMESPACE), this.i18n.t('common.dismiss', undefined, 'Fechar', PRAXIS_DYNAMIC_FORM_I18N_NAMESPACE), { duration: 7000 });
13298
+ }
12649
13299
  resetDependencyPolicySubscription() {
12650
13300
  this.dependencyPolicySubscription?.unsubscribe();
12651
13301
  this.dependencyPolicySubscription = null;
@@ -13287,6 +13937,7 @@ class PraxisDynamicForm {
13287
13937
  ? disabledOverride
13288
13938
  : baseDisabled) ||
13289
13939
  (readonlyOverride !== undefined ? readonlyOverride : false) ||
13940
+ (!!control && this.reactiveDeterminationRuntime.isOwnedTarget(this.form, control)) ||
13290
13941
  isVisible === false;
13291
13942
  if (control) {
13292
13943
  if (shouldDisable && control.enabled) {
@@ -14555,6 +15206,7 @@ class PraxisDynamicForm {
14555
15206
  return {
14556
15207
  span: candidateSpan[breakpoint],
14557
15208
  controlType: this.getColumnControlType(candidate),
15209
+ order: resolveOrder(this.getEffectiveColumn(candidate).order)[breakpoint],
14558
15210
  };
14559
15211
  }), strategy);
14560
15212
  projected[breakpoint] = resolved[targetIndex];
@@ -14853,17 +15505,30 @@ class PraxisDynamicForm {
14853
15505
  undefined);
14854
15506
  }
14855
15507
  async onSubmit() {
14856
- if (this.submitting)
15508
+ if (this.submitting || this.submitPreparationInProgress)
14857
15509
  return;
14858
15510
  if (this.entityHydrationPending) {
14859
15511
  return;
14860
15512
  }
15513
+ this.submitPreparationInProgress = true;
15514
+ try {
15515
+ await this.prepareAndSubmit();
15516
+ }
15517
+ finally {
15518
+ this.submitPreparationInProgress = false;
15519
+ }
15520
+ }
15521
+ async prepareAndSubmit() {
15522
+ if (!(await this.waitForReactiveDeterminationsBeforeSubmit()))
15523
+ return;
14861
15524
  this.clearSubmitFieldErrors();
14862
15525
  // Hooks: beforeValidate
14863
15526
  try {
14864
15527
  await this.runHooks('beforeValidate');
14865
15528
  }
14866
15529
  catch { }
15530
+ if (!(await this.waitForReactiveDeterminationsBeforeSubmit()))
15531
+ return;
14867
15532
  if (this.form.invalid) {
14868
15533
  // UX: marcar todos como touched para exibir erros
14869
15534
  this.form.markAllAsTouched();
@@ -14900,6 +15565,8 @@ class PraxisDynamicForm {
14900
15565
  await this.runHooks('afterValidate');
14901
15566
  }
14902
15567
  catch { }
15568
+ if (!(await this.waitForReactiveDeterminationsBeforeSubmit()))
15569
+ return;
14903
15570
  // Hooks: beforeSubmit (cancelable) — must run BEFORE snapshotting form value
14904
15571
  try {
14905
15572
  const res = await this.runHooks('beforeSubmit');
@@ -14928,6 +15595,13 @@ class PraxisDynamicForm {
14928
15595
  }
14929
15596
  }
14930
15597
  catch { }
15598
+ if (!(await this.waitForReactiveDeterminationsBeforeSubmit()))
15599
+ return;
15600
+ if (this.form.invalid) {
15601
+ this.form.markAllAsTouched();
15602
+ this.form.updateValueAndValidity({ onlySelf: false, emitEvent: false });
15603
+ return;
15604
+ }
14931
15605
  // Snapshot after hooks potentially changed control values
14932
15606
  const rawFormData = this.form.getRawValue();
14933
15607
  const formData = prepareSubmitPayload(rawFormData, this.config.fieldMetadata, {
@@ -15053,6 +15727,20 @@ class PraxisDynamicForm {
15053
15727
  },
15054
15728
  });
15055
15729
  }
15730
+ async waitForReactiveDeterminationsBeforeSubmit() {
15731
+ const pendingNotice = this.reactiveDeterminationRuntime.hasPending(this.form)
15732
+ ? this.snackBar.open(this.i18n.t('runtime.reactiveDetermination.submitPending', undefined, 'Aguarde a atualização dos campos relacionados antes de salvar.', PRAXIS_DYNAMIC_FORM_I18N_NAMESPACE), this.i18n.t('common.dismiss', undefined, 'Fechar', PRAXIS_DYNAMIC_FORM_I18N_NAMESPACE), { duration: 5000 })
15733
+ : null;
15734
+ const stable = await this.reactiveDeterminationRuntime.waitForStable(this.form);
15735
+ try {
15736
+ pendingNotice?.dismiss();
15737
+ }
15738
+ catch { }
15739
+ if (stable)
15740
+ return true;
15741
+ this.snackBar.open(this.i18n.t('runtime.reactiveDetermination.submitUnsatisfied', undefined, 'Os campos relacionados não foram atualizados com sucesso. Revise os dados e tente novamente.', PRAXIS_DYNAMIC_FORM_I18N_NAMESPACE), this.i18n.t('common.dismiss', undefined, 'Fechar', PRAXIS_DYNAMIC_FORM_I18N_NAMESPACE), { duration: 7000 });
15742
+ return false;
15743
+ }
15056
15744
  applySubmitFieldErrors(details) {
15057
15745
  for (const detail of details) {
15058
15746
  const target = this.normalizeSubmitErrorTarget(detail.target);
@@ -18714,11 +19402,13 @@ class PraxisDynamicForm {
18714
19402
  this.cdr.detectChanges();
18715
19403
  }
18716
19404
  ngOnDestroy() {
19405
+ this.isDestroyed = true;
18717
19406
  this.assistantSessions.removeContextSession(this.buildAiAssistantContextSnapshot());
18718
19407
  this.aiAssistantStateSubscription?.unsubscribe();
18719
19408
  this.aiAssistantStateSubscription = null;
18720
19409
  this.formValueChangesSubscription?.unsubscribe();
18721
19410
  this.formValueChangesSubscription = null;
19411
+ this.resetReactiveDeterminationSubscription();
18722
19412
  this.resetDependencyPolicySubscription();
18723
19413
  this.destroy$.next();
18724
19414
  this.destroy$.complete();
@@ -19179,11 +19869,15 @@ class PraxisDynamicForm {
19179
19869
  return { path, operation, schemaType, includeInternalSchemas: useFilterSchema, tenant, locale, baseUrl, apiOrigin };
19180
19870
  }
19181
19871
  async getSchemaWithCache() {
19872
+ if (this.isDestroyed)
19873
+ throw new PraxisDynamicFormDestroyedError();
19182
19874
  if (this.schemaCache) {
19183
19875
  this.debugLog('[PDF] schema:fromCache');
19184
19876
  return this.schemaCache;
19185
19877
  }
19186
19878
  const ctx = this.buildSchemaContext();
19879
+ this.schemaRootReactiveDeterminations = [];
19880
+ this.schemaRootOperationId = null;
19187
19881
  const schemaContext = {
19188
19882
  path: ctx.path,
19189
19883
  operation: ctx.operation,
@@ -19202,12 +19896,16 @@ class PraxisDynamicForm {
19202
19896
  }
19203
19897
  catch { }
19204
19898
  await this.waitForGlobalConfigReadyForSchema();
19899
+ if (this.isDestroyed)
19900
+ throw new PraxisDynamicFormDestroyedError();
19205
19901
  const disableCache = this.global.get('cache.disableSchemaCache');
19206
19902
  const adapter = disableCache
19207
19903
  ? new MemoryCacheAdapter()
19208
19904
  : new LocalStorageCacheAdapter({ ttlMs: 30 * 60 * 1000, maxEntries: 200 });
19209
19905
  const client = new SchemaMetadataClient(adapter);
19210
19906
  const loadLegacySchema = async (reason) => {
19907
+ if (this.isDestroyed)
19908
+ throw new PraxisDynamicFormDestroyedError();
19211
19909
  try {
19212
19910
  this.warnLog('[PDF] schema:metadata-fallback', reason);
19213
19911
  }
@@ -19222,6 +19920,8 @@ class PraxisDynamicForm {
19222
19920
  const legacyDefs = await firstValueFrom(legacyResult && typeof legacyResult.pipe === 'function'
19223
19921
  ? legacyResult.pipe(take(1))
19224
19922
  : legacyResult);
19923
+ if (this.isDestroyed)
19924
+ throw new PraxisDynamicFormDestroyedError();
19225
19925
  try {
19226
19926
  const schemaId = buildSchemaId(schemaContext);
19227
19927
  this.lastSchemaMeta = { schemaId, context: schemaContext };
@@ -19251,13 +19951,22 @@ class PraxisDynamicForm {
19251
19951
  locale: ctx.locale,
19252
19952
  });
19253
19953
  const defs = this.schemaNormalizer.normalizeSchema(entry.schema);
19254
- // Parse root-level x-ui.hooks if present (form-level hooks)
19954
+ // Parse backend-owned root x-ui runtime contracts. They remain transient
19955
+ // and are never copied into the persisted/authorable FormConfig.
19255
19956
  try {
19256
19957
  const rootUi = entry?.schema?.['x-ui'];
19958
+ this.schemaRootOperationId = exactSchemaOperationId(entry?.schema, rootUi);
19257
19959
  const hooks = rootUi && typeof rootUi === 'object' ? rootUi.hooks : undefined;
19258
19960
  if (hooks && typeof hooks === 'object') {
19259
19961
  this.schemaRootHooks = hooks;
19260
19962
  }
19963
+ const normalizedDeterminations = ctx.schemaType === 'request'
19964
+ ? normalizeReactiveDeterminations(rootUi && typeof rootUi === 'object'
19965
+ ? rootUi.reactiveDeterminations
19966
+ : undefined)
19967
+ : [];
19968
+ this.schemaRootReactiveDeterminations = normalizedDeterminations.filter((definition) => !this.schemaRootOperationId
19969
+ || definition.scope.schemaOperationId === this.schemaRootOperationId);
19261
19970
  }
19262
19971
  catch { }
19263
19972
  const schemaId = buildSchemaId(schemaContext);
@@ -19284,6 +19993,9 @@ class PraxisDynamicForm {
19284
19993
  return defs;
19285
19994
  }
19286
19995
  catch (error) {
19996
+ if (this.isDestroyed || error instanceof PraxisDynamicFormDestroyedError) {
19997
+ throw new PraxisDynamicFormDestroyedError();
19998
+ }
19287
19999
  return await loadLegacySchema(error);
19288
20000
  }
19289
20001
  finally {
@@ -19414,8 +20126,8 @@ class PraxisDynamicForm {
19414
20126
  this.config = normalizeFormConfig$1(this.config);
19415
20127
  }
19416
20128
  }
19417
- 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: 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: i12.Router, optional: true }, { token: i12.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 });
19418
- 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", editorialContext: "editorialContext", mode: "mode", config: "config", actions: "actions", schemaSource: "schemaSource", schemaUrl: "schemaUrl", readUrl: "readUrl", submitUrl: "submitUrl", submitMethod: "submitMethod", submitIdempotencyKey: "submitIdempotencyKey", submitCorrelationId: "submitCorrelationId", submitResourceVersion: "submitResourceVersion", responseSchemaUrl: "responseSchemaUrl", apiEndpointKey: "apiEndpointKey", apiUrlEntry: "apiUrlEntry", enableCustomization: "enableCustomization", showAiAssistant: "showAiAssistant", formId: "formId", componentInstanceId: "componentInstanceId", configPersistenceStrategy: "configPersistenceStrategy", layout: "layout", 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", visibleGlobal: "visibleGlobal", fieldIconPolicy: "fieldIconPolicy", domainRules: "domainRules", customEndpoints: "customEndpoints" }, outputs: { formSubmit: "formSubmit", formCancel: "formCancel", formReset: "formReset", configChange: "configChange", configPatchChange: "configPatchChange", formReady: "formReady", valueChange: "valueChange", syncCompleted: "syncCompleted", initializationError: "initializationError", loadingStateChange: "loadingStateChange", enableCustomizationChange: "enableCustomizationChange", customAction: "customAction", actionConfirmation: "actionConfirmation", schemaStatusChange: "schemaStatusChange", fieldRenderError: "fieldRenderError", ruleDiagnosticsChange: "ruleDiagnosticsChange" }, 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 [matTooltip]=\"schemaOutdated ? 'Schema do servidor mudou \u2014 Reconciliar' : 'Configurar formul\u00E1rio'\">\n </button>\n <button type=\"button\" praxisIconButton=\"link_off\" size=\"dense\" (click)=\"disconnect()\" matTooltip=\"Desconectar da fonte de dados\"\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 <form #formHost (ngSubmit)=\"onSubmit()\" [attr.aria-busy]=\"submitting ? 'true' : null\"\n [attr.aria-label]=\"'Formul\u00E1rio ' + (config.metadata?.version || '')\" [class.canvas-mode-enabled]=\"enableCustomization\"\n [class.presentation-mode]=\"effectivePresentation\" [class.readonly-mode]=\"effectiveReadonly\"\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 @for (section of (config.sections || []); track (section.id ?? $index); let sectionIndex = $index) {\n <div class=\"section-drop-wrapper\" [attr.data-section-id]=\"section.id\">\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 [style.marginBottom.px]=\"!isLastVisibleSection(section) ? getSectionGapBottom(section) : null\" [ngClass]=\"getSectionClasses(section)\"\n [ngStyle]=\"getSectionStyles(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 <div class=\"section-body\" [class.collapsed]=\"isSectionCollapsed(section)\"\n [attr.id]=\"sectionPanelId(section, sectionIndex)\"\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 @if (showAiAssistant && !enableCustomization && mode === 'view') {\n <div class=\"ai-floating-assistant\">\n <button type=\"button\" praxisIconButton=\"auto_awesome\" size=\"compact\" (click)=\"openAiAssistant()\" [disabled]=\"isLoading\"\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}.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}}.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{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}.form-section.section-appearance-plain{border-color:transparent;border-radius:0;padding:0;background:transparent}.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}\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: i16.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: i18.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"] }] });
20129
+ 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 });
20130
+ 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", editorialContext: "editorialContext", mode: "mode", config: "config", actions: "actions", schemaSource: "schemaSource", schemaUrl: "schemaUrl", readUrl: "readUrl", submitUrl: "submitUrl", submitMethod: "submitMethod", submitIdempotencyKey: "submitIdempotencyKey", submitCorrelationId: "submitCorrelationId", submitResourceVersion: "submitResourceVersion", responseSchemaUrl: "responseSchemaUrl", apiEndpointKey: "apiEndpointKey", apiUrlEntry: "apiUrlEntry", enableCustomization: "enableCustomization", showAiAssistant: "showAiAssistant", formId: "formId", componentInstanceId: "componentInstanceId", configPersistenceStrategy: "configPersistenceStrategy", layout: "layout", 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", visibleGlobal: "visibleGlobal", fieldIconPolicy: "fieldIconPolicy", domainRules: "domainRules", customEndpoints: "customEndpoints" }, outputs: { formSubmit: "formSubmit", formCancel: "formCancel", formReset: "formReset", configChange: "configChange", configPatchChange: "configPatchChange", formReady: "formReady", valueChange: "valueChange", syncCompleted: "syncCompleted", initializationError: "initializationError", loadingStateChange: "loadingStateChange", enableCustomizationChange: "enableCustomizationChange", customAction: "customAction", actionConfirmation: "actionConfirmation", schemaStatusChange: "schemaStatusChange", fieldRenderError: "fieldRenderError", ruleDiagnosticsChange: "ruleDiagnosticsChange", reactiveDeterminationExecuted: "reactiveDeterminationExecuted", reactiveDeterminationPendingChange: "reactiveDeterminationPendingChange" }, 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 [matTooltip]=\"schemaOutdated ? 'Schema do servidor mudou \u2014 Reconciliar' : 'Configurar formul\u00E1rio'\">\n </button>\n <button type=\"button\" praxisIconButton=\"link_off\" size=\"dense\" (click)=\"disconnect()\" matTooltip=\"Desconectar da fonte de dados\"\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 <form #formHost (ngSubmit)=\"onSubmit()\" [attr.aria-busy]=\"submitting ? 'true' : null\"\n [attr.aria-label]=\"'Formul\u00E1rio ' + (config.metadata?.version || '')\" [class.canvas-mode-enabled]=\"enableCustomization\"\n [class.presentation-mode]=\"effectivePresentation\" [class.readonly-mode]=\"effectiveReadonly\"\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 @for (section of (config.sections || []); track (section.id ?? $index); let sectionIndex = $index) {\n <div class=\"section-drop-wrapper\" [attr.data-section-id]=\"section.id\">\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 [style.marginBottom.px]=\"!isLastVisibleSection(section) ? getSectionGapBottom(section) : null\" [ngClass]=\"getSectionClasses(section)\"\n [ngStyle]=\"getSectionStyles(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 <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 @if (showAiAssistant && !enableCustomization && mode === 'view') {\n <div class=\"ai-floating-assistant\">\n <button type=\"button\" praxisIconButton=\"auto_awesome\" size=\"compact\" (click)=\"openAiAssistant()\" [disabled]=\"isLoading\"\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}.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}}.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{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}.form-section.section-appearance-plain{border-color:transparent;border-radius:0;padding:0;background:transparent}.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}\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"] }] });
19419
20131
  }
19420
20132
  i0.ɵɵngDeclareClassMetadata({ minVersion: "12.0.0", version: "21.2.14", ngImport: i0, type: PraxisDynamicForm, decorators: [{
19421
20133
  type: Component,
@@ -19437,14 +20149,14 @@ i0.ɵɵngDeclareClassMetadata({ minVersion: "12.0.0", version: "21.2.14", ngImpo
19437
20149
  EmptyStateCardComponent,
19438
20150
  PraxisAiAssistantShellComponent,
19439
20151
  PraxisRichContent,
19440
- ], 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 [matTooltip]=\"schemaOutdated ? 'Schema do servidor mudou \u2014 Reconciliar' : 'Configurar formul\u00E1rio'\">\n </button>\n <button type=\"button\" praxisIconButton=\"link_off\" size=\"dense\" (click)=\"disconnect()\" matTooltip=\"Desconectar da fonte de dados\"\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 <form #formHost (ngSubmit)=\"onSubmit()\" [attr.aria-busy]=\"submitting ? 'true' : null\"\n [attr.aria-label]=\"'Formul\u00E1rio ' + (config.metadata?.version || '')\" [class.canvas-mode-enabled]=\"enableCustomization\"\n [class.presentation-mode]=\"effectivePresentation\" [class.readonly-mode]=\"effectiveReadonly\"\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 @for (section of (config.sections || []); track (section.id ?? $index); let sectionIndex = $index) {\n <div class=\"section-drop-wrapper\" [attr.data-section-id]=\"section.id\">\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 [style.marginBottom.px]=\"!isLastVisibleSection(section) ? getSectionGapBottom(section) : null\" [ngClass]=\"getSectionClasses(section)\"\n [ngStyle]=\"getSectionStyles(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 <div class=\"section-body\" [class.collapsed]=\"isSectionCollapsed(section)\"\n [attr.id]=\"sectionPanelId(section, sectionIndex)\"\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 @if (showAiAssistant && !enableCustomization && mode === 'view') {\n <div class=\"ai-floating-assistant\">\n <button type=\"button\" praxisIconButton=\"auto_awesome\" size=\"compact\" (click)=\"openAiAssistant()\" [disabled]=\"isLoading\"\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}.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}}.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{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}.form-section.section-appearance-plain{border-color:transparent;border-radius:0;padding:0;background:transparent}.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}\n"] }]
20152
+ ], 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 [matTooltip]=\"schemaOutdated ? 'Schema do servidor mudou \u2014 Reconciliar' : 'Configurar formul\u00E1rio'\">\n </button>\n <button type=\"button\" praxisIconButton=\"link_off\" size=\"dense\" (click)=\"disconnect()\" matTooltip=\"Desconectar da fonte de dados\"\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 <form #formHost (ngSubmit)=\"onSubmit()\" [attr.aria-busy]=\"submitting ? 'true' : null\"\n [attr.aria-label]=\"'Formul\u00E1rio ' + (config.metadata?.version || '')\" [class.canvas-mode-enabled]=\"enableCustomization\"\n [class.presentation-mode]=\"effectivePresentation\" [class.readonly-mode]=\"effectiveReadonly\"\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 @for (section of (config.sections || []); track (section.id ?? $index); let sectionIndex = $index) {\n <div class=\"section-drop-wrapper\" [attr.data-section-id]=\"section.id\">\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 [style.marginBottom.px]=\"!isLastVisibleSection(section) ? getSectionGapBottom(section) : null\" [ngClass]=\"getSectionClasses(section)\"\n [ngStyle]=\"getSectionStyles(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 <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 @if (showAiAssistant && !enableCustomization && mode === 'view') {\n <div class=\"ai-floating-assistant\">\n <button type=\"button\" praxisIconButton=\"auto_awesome\" size=\"compact\" (click)=\"openAiAssistant()\" [disabled]=\"isLoading\"\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}.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}}.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{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}.form-section.section-appearance-plain{border-color:transparent;border-radius:0;padding:0;background:transparent}.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}\n"] }]
19441
20153
  }], 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: [{
19442
20154
  type: Inject,
19443
20155
  args: [ASYNC_CONFIG_STORAGE]
19444
20156
  }] }, { type: undefined, decorators: [{
19445
20157
  type: Inject,
19446
20158
  args: [CONNECTION_STORAGE]
19447
- }] }, { type: i1.DynamicFormService }, { type: i9.MatSnackBar }, { type: CanvasStateService }, { type: DynamicFormLayoutService }, { type: i1.ErrorMessageService }, { type: i1.SchemaNormalizerService }, { type: i1.ComponentMetadataRegistry }, { type: i1.GlobalConfigService }, { type: i1.ComponentKeyService }, { type: i1.LoadingOrchestrator }, { type: i0.NgZone }, { type: undefined, decorators: [{
20159
+ }] }, { type: i1.DynamicFormService }, { type: i9.MatSnackBar }, { type: CanvasStateService }, { type: DynamicFormLayoutService }, { type: ReactiveDeterminationRuntimeService }, { type: i1.ErrorMessageService }, { type: i1.SchemaNormalizerService }, { type: i1.ComponentMetadataRegistry }, { type: i1.GlobalConfigService }, { type: i1.ComponentKeyService }, { type: i1.LoadingOrchestrator }, { type: i0.NgZone }, { type: undefined, decorators: [{
19448
20160
  type: Inject,
19449
20161
  args: [API_URL]
19450
20162
  }] }, { type: undefined, decorators: [{
@@ -19452,9 +20164,9 @@ i0.ɵɵngDeclareClassMetadata({ minVersion: "12.0.0", version: "21.2.14", ngImpo
19452
20164
  }, {
19453
20165
  type: Inject,
19454
20166
  args: [PRAXIS_LOADING_RENDERER]
19455
- }] }, { type: i12.Router, decorators: [{
20167
+ }] }, { type: i13.Router, decorators: [{
19456
20168
  type: Optional
19457
- }] }, { type: i12.ActivatedRoute, decorators: [{
20169
+ }] }, { type: i13.ActivatedRoute, decorators: [{
19458
20170
  type: Optional
19459
20171
  }] }, { type: i1.FormHooksRegistry, decorators: [{
19460
20172
  type: Optional
@@ -19581,6 +20293,10 @@ i0.ɵɵngDeclareClassMetadata({ minVersion: "12.0.0", version: "21.2.14", ngImpo
19581
20293
  type: Output
19582
20294
  }], ruleDiagnosticsChange: [{
19583
20295
  type: Output
20296
+ }], reactiveDeterminationExecuted: [{
20297
+ type: Output
20298
+ }], reactiveDeterminationPendingChange: [{
20299
+ type: Output
19584
20300
  }], formHost: [{
19585
20301
  type: ViewChild,
19586
20302
  args: ['formHost', { static: false }]
@@ -30363,7 +31079,7 @@ class PraxisDynamicFormConfigEditor {
30363
31079
  return Object.entries(params).reduce((text, [key, value]) => text.split(`{{${key}}}`).join(String(value)), fallback);
30364
31080
  }
30365
31081
  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 });
30366
- static ɵcmp = i0.ɵɵngDeclareComponent({ minVersion: "17.0.0", version: "21.2.14", type: PraxisDynamicFormConfigEditor, isStandalone: true, selector: "praxis-dynamic-form-config-editor", providers: [FormConfigService], 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 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-grid\">\n <div class=\"form-row\">\n <mat-form-field appearance=\"fill\" class=\"w-100\">\n <mat-label>{{ tx('config.general.inputMode.label', 'Modo de dados') }}</mat-label>\n <mat-select [(ngModel)]=\"inputMode\" (ngModelChange)=\"onInputModeChange()\">\n <mat-option value=\"create\">{{ tx('config.general.inputMode.create', 'create') }}</mat-option>\n <mat-option value=\"edit\">{{ tx('config.general.inputMode.edit', 'edit') }}</mat-option>\n <mat-option value=\"view\">{{ tx('config.general.inputMode.view', 'view') }}</mat-option>\n </mat-select>\n </mat-form-field>\n </div>\n <div class=\"block-status\" [class.block-status--implicit]=\"!isBindingsBlockPersisted()\">\n <strong>{{ tx('config.general.bindings.label', 'Bindings') }}</strong>\n @if (isBindingsBlockPersisted()) {\n <span>{{ tx('config.general.bindings.persisted', '`bindings.mode` ser\u00E1 persistido no documento can\u00F4nico.') }}</span>\n } @else {\n {{ tx('config.general.bindings.implicit', 'Bloco ausente no documento can\u00F4nico. O valor exibido \u00E9 fallback visual e n\u00E3o ser\u00E1 salvo at\u00E9 voc\u00EA editar este campo.') }}\n }\n </div>\n <div class=\"section-help\">\n <span class=\"section-help__label\">{{ tx('config.common.understand', 'Entenda:') }}</span>\n <button\n praxisIconButton=\"help_outline\"\n size=\"dense\"\n class=\"help-icon-button\"\n type=\"button\"\n [matTooltip]=\"tx('config.general.inputMode.tooltip', 'O mode controla o fluxo (create/edit/view). enableCustomization s\u00F3 libera edi\u00E7\u00E3o do layout e n\u00E3o altera o mode.')\"\n matTooltipPosition=\"above\"\n >\n </button>\n </div>\n </div>\n </mat-card-content>\n </mat-card>\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 <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\">\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\"><mat-icon>format_align_left</mat-icon></mat-button-toggle>\n <mat-button-toggle value=\"center\"><mat-icon>format_align_center</mat-icon></mat-button-toggle>\n <mat-button-toggle value=\"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\"><mat-icon>format_align_left</mat-icon></mat-button-toggle>\n <mat-button-toggle value=\"center\"><mat-icon>format_align_center</mat-icon></mat-button-toggle>\n <mat-button-toggle value=\"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\" [(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\" [(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\" [(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 <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\" [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 <div class=\"section-help\">\n <span class=\"section-help__label\">{{ tx('config.common.understand', 'Entenda:') }}</span>\n <button\n praxisIconButton=\"help_outline\"\n size=\"dense\"\n class=\"help-icon-button\"\n type=\"button\"\n [matTooltip]=\"tx('config.presentation.help.tooltip', 'Ajustes aplicam somente ao Modo Apresenta\u00E7\u00E3o e s\u00E3o salvos por formul\u00E1rio (via CSS/Classes).')\"\n matTooltipPosition=\"above\"\n >\n </button>\n </div>\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 [config]=\"editedConfig\" (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 [(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\" (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]=\"!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 [(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\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 ></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{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:flex;gap:20px;align-items:flex-start}.presentation-controls{flex:1 1 60%;display:grid;grid-template-columns:repeat(auto-fit,minmax(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{width:100%}.control--inline{grid-column:1/-1;display:flex;gap:16px;align-items:center}.presentation-preview{flex:0 0 360px;position:sticky;top:16px}.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)}.presentation-preview .praxis-presentation__value{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)}@media(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}}\n"], dependencies: [{ kind: "ngmodule", type: CommonModule }, { kind: "directive", type: i1$2.NgClass, selector: "[ngClass]", inputs: ["class", "ngClass"] }, { 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$3.MatTab, selector: "mat-tab", inputs: ["disabled", "label", "aria-label", "aria-labelledby", "labelClass", "bodyClass", "id"], exportAs: ["matTab"] }, { kind: "component", type: i6$3.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: "ngmodule", type: MatFormFieldModule }, { kind: "component", type: i5$1.MatFormField, selector: "mat-form-field", inputs: ["hideRequiredMarker", "color", "floatLabel", "appearance", "subscriptSizing", "hintLabel"], exportAs: ["matFormField"] }, { kind: "directive", type: i5$1.MatLabel, selector: "mat-label" }, { kind: "directive", type: i5$1.MatHint, selector: "mat-hint", inputs: ["align", "id"] }, { kind: "directive", type: i5$1.MatError, selector: "mat-error, [matError]", inputs: ["id"] }, { kind: "directive", type: i5$1.MatSuffix, selector: "[matSuffix], [matIconSuffix], [matTextSuffix]", inputs: ["matTextSuffix"] }, { kind: "ngmodule", type: MatSelectModule }, { kind: "component", type: i6$2.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: i6$2.MatOption, selector: "mat-option", inputs: ["value", "id", "disabled"], outputs: ["onSelectionChange"], exportAs: ["matOption"] }, { kind: "ngmodule", type: MatInputModule }, { kind: "directive", type: i4$1.MatInput, selector: "input[matInput], textarea[matInput], select[matNativeControl], input[matNativeControl], textarea[matNativeControl]", inputs: ["disabled", "id", "placeholder", "name", "required", "type", "errorStateMatcher", "aria-describedby", "value", "readonly", "disabledInteractive"], exportAs: ["matInput"] }, { kind: "ngmodule", type: MatCheckboxModule }, { kind: "component", type: i12$1.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: "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"] }, { 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"] }, { kind: "pipe", type: i1$2.JsonPipe, name: "json" }] });
31082
+ static ɵcmp = i0.ɵɵngDeclareComponent({ minVersion: "17.0.0", version: "21.2.14", type: PraxisDynamicFormConfigEditor, isStandalone: true, selector: "praxis-dynamic-form-config-editor", providers: [FormConfigService], 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 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-grid\">\n <div class=\"form-row\">\n <mat-form-field appearance=\"fill\" class=\"w-100\">\n <mat-label>{{ tx('config.general.inputMode.label', 'Modo de dados') }}</mat-label>\n <mat-select [(ngModel)]=\"inputMode\" (ngModelChange)=\"onInputModeChange()\">\n <mat-option value=\"create\">{{ tx('config.general.inputMode.create', 'create') }}</mat-option>\n <mat-option value=\"edit\">{{ tx('config.general.inputMode.edit', 'edit') }}</mat-option>\n <mat-option value=\"view\">{{ tx('config.general.inputMode.view', 'view') }}</mat-option>\n </mat-select>\n </mat-form-field>\n </div>\n <div class=\"block-status\" [class.block-status--implicit]=\"!isBindingsBlockPersisted()\">\n <strong>{{ tx('config.general.bindings.label', 'Bindings') }}</strong>\n @if (isBindingsBlockPersisted()) {\n <span>{{ tx('config.general.bindings.persisted', '`bindings.mode` ser\u00E1 persistido no documento can\u00F4nico.') }}</span>\n } @else {\n {{ tx('config.general.bindings.implicit', 'Bloco ausente no documento can\u00F4nico. O valor exibido \u00E9 fallback visual e n\u00E3o ser\u00E1 salvo at\u00E9 voc\u00EA editar este campo.') }}\n }\n </div>\n <div class=\"section-help\">\n <span class=\"section-help__label\">{{ tx('config.common.understand', 'Entenda:') }}</span>\n <button\n praxisIconButton=\"help_outline\"\n size=\"dense\"\n class=\"help-icon-button\"\n type=\"button\"\n [matTooltip]=\"tx('config.general.inputMode.tooltip', 'O mode controla o fluxo (create/edit/view). enableCustomization s\u00F3 libera edi\u00E7\u00E3o do layout e n\u00E3o altera o mode.')\"\n matTooltipPosition=\"above\"\n >\n </button>\n </div>\n </div>\n </mat-card-content>\n </mat-card>\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 <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\">\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\"><mat-icon>format_align_left</mat-icon></mat-button-toggle>\n <mat-button-toggle value=\"center\"><mat-icon>format_align_center</mat-icon></mat-button-toggle>\n <mat-button-toggle value=\"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\"><mat-icon>format_align_left</mat-icon></mat-button-toggle>\n <mat-button-toggle value=\"center\"><mat-icon>format_align_center</mat-icon></mat-button-toggle>\n <mat-button-toggle value=\"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\" [(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\" [(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\" [(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 <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\" [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 <div class=\"section-help\">\n <span class=\"section-help__label\">{{ tx('config.common.understand', 'Entenda:') }}</span>\n <button\n praxisIconButton=\"help_outline\"\n size=\"dense\"\n class=\"help-icon-button\"\n type=\"button\"\n [matTooltip]=\"tx('config.presentation.help.tooltip', 'Ajustes aplicam somente ao Modo Apresenta\u00E7\u00E3o e s\u00E3o salvos por formul\u00E1rio (via CSS/Classes).')\"\n matTooltipPosition=\"above\"\n >\n </button>\n </div>\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 [config]=\"editedConfig\" (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 [(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\" (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]=\"!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 [(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\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 ></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{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:flex;gap:20px;align-items:flex-start}.presentation-controls{flex:1 1 60%;display:grid;grid-template-columns:repeat(auto-fit,minmax(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{width:100%}.control--inline{grid-column:1/-1;display:flex;gap:16px;align-items:center}.presentation-preview{flex:0 0 360px;position:sticky;top:16px}.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)}.presentation-preview .praxis-presentation__value{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)}@media(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}}\n"], dependencies: [{ kind: "ngmodule", type: CommonModule }, { kind: "directive", type: i1$2.NgClass, selector: "[ngClass]", inputs: ["class", "ngClass"] }, { 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$3.MatTab, selector: "mat-tab", inputs: ["disabled", "label", "aria-label", "aria-labelledby", "labelClass", "bodyClass", "id"], exportAs: ["matTab"] }, { kind: "component", type: i6$3.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: "ngmodule", type: MatFormFieldModule }, { kind: "component", type: i5$1.MatFormField, selector: "mat-form-field", inputs: ["hideRequiredMarker", "color", "floatLabel", "appearance", "subscriptSizing", "hintLabel"], exportAs: ["matFormField"] }, { kind: "directive", type: i5$1.MatLabel, selector: "mat-label" }, { kind: "directive", type: i5$1.MatHint, selector: "mat-hint", inputs: ["align", "id"] }, { kind: "directive", type: i5$1.MatError, selector: "mat-error, [matError]", inputs: ["id"] }, { kind: "directive", type: i5$1.MatSuffix, selector: "[matSuffix], [matIconSuffix], [matTextSuffix]", inputs: ["matTextSuffix"] }, { kind: "ngmodule", type: MatSelectModule }, { kind: "component", type: i6$2.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: i6$2.MatOption, selector: "mat-option", inputs: ["value", "id", "disabled"], outputs: ["onSelectionChange"], exportAs: ["matOption"] }, { kind: "ngmodule", type: MatInputModule }, { kind: "directive", type: i4$1.MatInput, selector: "input[matInput], textarea[matInput], select[matNativeControl], input[matNativeControl], textarea[matNativeControl]", inputs: ["disabled", "id", "placeholder", "name", "required", "type", "errorStateMatcher", "aria-describedby", "value", "readonly", "disabledInteractive"], exportAs: ["matInput"] }, { kind: "ngmodule", type: 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: "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"] }, { 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"] }, { kind: "pipe", type: i1$2.JsonPipe, name: "json" }] });
30367
31083
  }
30368
31084
  i0.ɵɵngDeclareClassMetadata({ minVersion: "12.0.0", version: "21.2.14", ngImport: i0, type: PraxisDynamicFormConfigEditor, decorators: [{
30369
31085
  type: Component,
@@ -31077,6 +31793,8 @@ const PRAXIS_DYNAMIC_FORM_COMPONENT_METADATA = {
31077
31793
  { name: 'customAction', type: 'FormCustomActionEvent', description: 'Emite quando uma acao customizada e executada' },
31078
31794
  { name: 'actionConfirmation', type: 'FormActionConfirmationEvent', description: 'Resultado de confirmacoes de acoes' },
31079
31795
  { name: 'schemaStatusChange', type: '{ outdated: boolean; serverHash?: string; lastVerifiedAt?: string; formId?: string }', description: 'Emite quando o status do schema muda' },
31796
+ { name: 'reactiveDeterminationExecuted', type: 'ReactiveDeterminationExecutionEvent', description: 'Emite evidência metadata-only sem valores sensíveis ao iniciar, executar, ignorar ou falhar uma determinação reativa backend.' },
31797
+ { name: 'reactiveDeterminationPendingChange', type: 'boolean', description: 'Emite o estado agregado de estabilizacao das determinacoes, sem valores do formulario ou da resposta.' },
31080
31798
  ],
31081
31799
  actions: [
31082
31800
  {
@@ -31740,7 +32458,7 @@ class Ergadm00034CompactPresentationExampleComponent {
31740
32458
  corporatePresentationConfig = buildCorporatePresentationFormatGalleryConfig(this.dynamicLayout);
31741
32459
  corporatePresentationInitialValue = this.corporatePresentationExample.initialValue;
31742
32460
  static ɵfac = i0.ɵɵngDeclareFactory({ minVersion: "12.0.0", version: "21.2.14", ngImport: i0, type: Ergadm00034CompactPresentationExampleComponent, deps: [], target: i0.ɵɵFactoryTarget.Component });
31743
- static ɵcmp = i0.ɵɵngDeclareComponent({ minVersion: "17.0.0", version: "21.2.14", type: Ergadm00034CompactPresentationExampleComponent, isStandalone: true, selector: "praxis-ergadm00034-compact-presentation-example", ngImport: i0, template: "<mat-card class=\"legacy-presentation-card\" data-testid=\"ergadm00034-compact-fixture\">\n <div class=\"legacy-presentation-header\">\n <div>\n <p class=\"examples-eyebrow\">Exemplo visual da lib</p>\n <h2>{{ legacyFrequencyExample.title }}</h2>\n <p>\n Fixture visual representativo de <code>{{ legacyFrequencyExample.resourcePath }}</code>:\n cinco registros densos e detalhe gerado por <code>x-ui.group</code>, <code>order</code>\n e <code>width</code>, sem declarar <code>FormConfig.sections</code> no host.\n </p>\n </div>\n <div class=\"legacy-presentation-badge\">\n <mat-icon aria-hidden=\"true\">view_compact</mat-icon>\n <span>compactPresentation</span>\n </div>\n </div>\n\n <div class=\"legacy-workbench\">\n <section class=\"legacy-records-panel\" aria-labelledby=\"legacy-records-title\">\n <div class=\"legacy-panel-heading\">\n <div>\n <h3 id=\"legacy-records-title\">C\u00F3digos de frequ\u00EAncia</h3>\n <p>5 registros carregados</p>\n </div>\n <span class=\"legacy-count-chip\">fixture local</span>\n </div>\n\n <div class=\"legacy-table-wrap\">\n <table class=\"legacy-record-table\" aria-label=\"C\u00F3digos de frequ\u00EAncia\">\n <thead>\n <tr>\n <th scope=\"col\">Tipo</th>\n <th scope=\"col\">C\u00F3digo</th>\n <th scope=\"col\">Nome</th>\n <th scope=\"col\">Preench.</th>\n <th scope=\"col\">Marcador</th>\n </tr>\n </thead>\n <tbody>\n @for (row of legacyFrequencyRows; track row.codigo) {\n <tr [class.is-selected]=\"row.selected\">\n <td>{{ row.tipo }}</td>\n <td><strong>{{ row.codigo }}</strong></td>\n <td>{{ row.nome }}</td>\n <td>{{ row.preenchimento }}</td>\n <td>{{ row.marcador }}</td>\n </tr>\n }\n </tbody>\n </table>\n </div>\n </section>\n\n <section class=\"legacy-detail-panel\" aria-labelledby=\"legacy-detail-title\">\n <div class=\"legacy-detail-toolbar\">\n <div>\n <p class=\"legacy-detail-kicker\">Registro selecionado</p>\n <h3 id=\"legacy-detail-title\">AFA - Afastamento abonado</h3>\n </div>\n <div class=\"legacy-detail-actions\" aria-label=\"A\u00E7\u00F5es do registro\">\n <button type=\"button\" aria-label=\"Novo c\u00F3digo de frequ\u00EAncia\">\n <mat-icon aria-hidden=\"true\">add</mat-icon>\n </button>\n <button type=\"button\" aria-label=\"Editar c\u00F3digo de frequ\u00EAncia\">\n <mat-icon aria-hidden=\"true\">edit</mat-icon>\n </button>\n </div>\n </div>\n\n <div class=\"legacy-detail-tabs\" aria-label=\"Abas do detalhe\">\n <button type=\"button\" class=\"is-active\">\n <mat-icon aria-hidden=\"true\">fact_check</mat-icon>\n <span>Detalhes</span>\n </button>\n <button type=\"button\">\n <mat-icon aria-hidden=\"true\">gavel</mat-icon>\n <span>Documentos legais</span>\n </button>\n </div>\n\n <praxis-dynamic-form\n class=\"presentation-mode pres-label-left pres-density-compact legacy-frequency-form\"\n data-testid=\"ergadm00034-detail-form\"\n formId=\"legacy-frequency-compact-presentation-demo\"\n [config]=\"legacyFrequencyPresentationConfig\"\n [initialValue]=\"legacyFrequencyInitialValue\"\n mode=\"view\"\n [presentationModeGlobal]=\"true\"\n [enableCustomization]=\"false\"\n [showAiAssistant]=\"false\"\n ></praxis-dynamic-form>\n </section>\n </div>\n\n <section class=\"corporate-format-gallery\" data-testid=\"corporate-format-gallery\">\n <div class=\"corporate-gallery-heading\">\n <div>\n <p class=\"examples-eyebrow\">Valida\u00E7\u00E3o de apresenta\u00E7\u00E3o</p>\n <h2>{{ corporatePresentationExample.title }}</h2>\n <p>\n Fixture de <code>{{ corporatePresentationExample.resourcePath }}</code> para validar\n datas, moedas, percentuais, quantidades, documentos, listas e status em telas densas.\n </p>\n </div>\n <div class=\"corporate-kpi-strip\" aria-label=\"Resumo financeiro\">\n <span>\n <strong>R$ 1,38 mi</strong>\n <small>valor bruto</small>\n </span>\n <span>\n <strong>18,45%</strong>\n <small>margem</small>\n </span>\n <span>\n <strong>42</strong>\n <small>itens</small>\n </span>\n </div>\n </div>\n\n <praxis-dynamic-form\n class=\"presentation-mode pres-label-left pres-density-compact corporate-format-form\"\n data-testid=\"corporate-format-detail-form\"\n formId=\"corporate-format-gallery-demo\"\n [config]=\"corporatePresentationConfig\"\n [initialValue]=\"corporatePresentationInitialValue\"\n mode=\"view\"\n [presentationModeGlobal]=\"true\"\n [enableCustomization]=\"false\"\n [showAiAssistant]=\"false\"\n ></praxis-dynamic-form>\n </section>\n</mat-card>\n", styles: [":host{--pdx-ergadm-bg: var(--mat-sys-surface, var(--md-sys-color-surface, #ffffff));--pdx-ergadm-surface-strong: color-mix( in srgb, var(--mat-sys-surface-container-high, var(--md-sys-color-surface-container-high, #eef3f1)) 90%, var(--pdx-ergadm-bg) );--pdx-ergadm-border: color-mix( in srgb, var(--mat-sys-outline-variant, var(--md-sys-color-outline-variant, #c6d0cb)) 76%, transparent );--pdx-ergadm-text: var(--mat-sys-on-surface, var(--md-sys-color-on-surface, #17221d));--pdx-ergadm-text-muted: var( --mat-sys-on-surface-variant, var(--md-sys-color-on-surface-variant, #53625c) );--pdx-ergadm-primary: var(--mat-sys-primary, var(--md-sys-color-primary, #0f766e));--pdx-ergadm-primary-strong: color-mix(in srgb, var(--pdx-ergadm-primary) 82%, black);--pdx-ergadm-primary-soft: color-mix(in srgb, var(--pdx-ergadm-primary) 14%, transparent);--pdx-ergadm-chip-bg: color-mix( in srgb, var(--mat-sys-primary-container, var(--md-sys-color-primary-container, #dcefeb)) 74%, var(--pdx-ergadm-bg) );--pdx-ergadm-chip-text: var( --mat-sys-on-primary-container, var(--md-sys-color-on-primary-container, #123932) );--pdx-ergadm-shadow-soft: 0 18px 36px rgba(15, 23, 42, .06);display:block;min-width:0;color:var(--pdx-ergadm-text)}.legacy-presentation-card{padding:22px;border-radius:20px;border:1px solid var(--pdx-ergadm-border);background:linear-gradient(180deg,color-mix(in srgb,var(--pdx-ergadm-surface-strong) 86%,var(--pdx-ergadm-bg)) 0%,var(--pdx-ergadm-bg) 100%);box-shadow:var(--pdx-ergadm-shadow-soft)}.legacy-presentation-header{display:flex;align-items:flex-start;justify-content:space-between;gap:18px;margin-bottom:14px}.examples-eyebrow{margin:0;text-transform:uppercase;letter-spacing:.18em;font-size:.76rem;font-weight:800;color:color-mix(in srgb,var(--pdx-ergadm-primary) 84%,var(--pdx-ergadm-text))}.legacy-presentation-header h2{margin:6px 0 8px;font-size:clamp(1.18rem,1.6vw,1.48rem);line-height:1.14}.legacy-presentation-header p{margin:0;max-width:76ch;color:var(--pdx-ergadm-text-muted);line-height:1.55}.legacy-presentation-badge{display:inline-flex;align-items:center;gap:8px;flex:0 0 auto;padding:8px 12px;border-radius:999px;border:1px solid color-mix(in srgb,var(--pdx-ergadm-primary) 18%,transparent);background:var(--pdx-ergadm-chip-bg);color:var(--pdx-ergadm-chip-text);font-size:.82rem;font-weight:800}.legacy-workbench{display:grid;grid-template-columns:minmax(360px,.44fr) minmax(0,1fr);gap:14px;align-items:start}.legacy-records-panel,.legacy-detail-panel{min-width:0;border:1px solid var(--pdx-ergadm-border);border-radius:14px;background:color-mix(in srgb,var(--pdx-ergadm-bg) 88%,var(--pdx-ergadm-surface-strong))}.legacy-records-panel{overflow:hidden}.legacy-detail-panel{padding:12px}.legacy-panel-heading,.legacy-detail-toolbar{display:flex;align-items:flex-start;justify-content:space-between;gap:12px}.legacy-panel-heading{padding:12px 14px 10px;border-bottom:1px solid var(--pdx-ergadm-border)}.legacy-panel-heading h3,.legacy-detail-toolbar h3{margin:0;font-size:.98rem;line-height:1.25}.legacy-panel-heading p,.legacy-detail-kicker{margin:3px 0 0;color:var(--pdx-ergadm-text-muted);font-size:.76rem;line-height:1.35}.legacy-count-chip{flex:0 0 auto;padding:5px 8px;border-radius:999px;background:var(--pdx-ergadm-primary-soft);color:var(--pdx-ergadm-primary-strong);font-size:.68rem;font-weight:800;text-transform:uppercase}.legacy-table-wrap{overflow-x:auto}.legacy-record-table{width:100%;min-width:500px;border-collapse:collapse;font-size:.78rem;line-height:1.25}.legacy-record-table th,.legacy-record-table td{padding:8px 10px;text-align:left;white-space:nowrap;border-bottom:1px solid color-mix(in srgb,var(--pdx-ergadm-border) 78%,transparent)}.legacy-record-table th{color:var(--pdx-ergadm-text-muted);font-size:.66rem;font-weight:800;text-transform:uppercase}.legacy-record-table td:nth-child(3){max-width:190px;overflow:hidden;text-overflow:ellipsis}.legacy-record-table tr:last-child td{border-bottom:0}.legacy-record-table tr.is-selected td{background:color-mix(in srgb,var(--pdx-ergadm-primary) 11%,transparent)}.legacy-detail-actions{display:inline-flex;gap:6px;flex:0 0 auto}.legacy-detail-actions button{display:inline-grid;place-items:center;width:32px;height:32px;border:1px solid var(--pdx-ergadm-border);border-radius:8px;background:var(--pdx-ergadm-bg);color:var(--pdx-ergadm-primary-strong);cursor:default}.legacy-detail-actions mat-icon{width:18px;height:18px;font-size:18px}.legacy-detail-tabs{display:flex;gap:6px;margin:12px 0;padding-bottom:8px;border-bottom:1px solid var(--pdx-ergadm-border);overflow-x:auto}.legacy-detail-tabs button{display:inline-flex;align-items:center;gap:6px;min-height:30px;padding:5px 9px;border:1px solid transparent;border-radius:999px;background:transparent;color:var(--pdx-ergadm-text-muted);font:inherit;font-size:.78rem;font-weight:700;white-space:nowrap}.legacy-detail-tabs button.is-active{border-color:color-mix(in srgb,var(--pdx-ergadm-primary) 18%,transparent);background:var(--pdx-ergadm-primary-soft);color:var(--pdx-ergadm-primary-strong)}.legacy-detail-tabs mat-icon{width:16px;height:16px;font-size:16px}.legacy-frequency-form{--pdx-presentation-label-width: 116px;--pdx-presentation-label-size: .7rem;--pdx-presentation-value-size: .9rem;--pdx-presentation-flag-height: 20px;--pdx-presentation-flag-padding: 0 7px;display:block}.corporate-format-gallery{margin-top:18px;padding-top:18px;border-top:1px solid var(--pdx-ergadm-border)}.corporate-gallery-heading{display:grid;grid-template-columns:minmax(0,1fr) minmax(260px,.34fr);gap:16px;align-items:start;margin-bottom:12px}.corporate-gallery-heading h2{margin:6px 0 8px;font-size:clamp(1.08rem,1.35vw,1.32rem);line-height:1.16}.corporate-gallery-heading p{margin:0;max-width:82ch;color:var(--pdx-ergadm-text-muted);line-height:1.55}.corporate-kpi-strip{display:grid;grid-template-columns:repeat(3,minmax(0,1fr));gap:8px}.corporate-kpi-strip span{min-width:0;padding:10px;border:1px solid var(--pdx-ergadm-border);border-radius:12px;background:color-mix(in srgb,var(--pdx-ergadm-bg) 86%,var(--pdx-ergadm-primary-soft))}.corporate-kpi-strip strong,.corporate-kpi-strip small{display:block;min-width:0;overflow-wrap:anywhere}.corporate-kpi-strip strong{color:var(--pdx-ergadm-primary-strong);font-size:.96rem;line-height:1.2}.corporate-kpi-strip small{margin-top:3px;color:var(--pdx-ergadm-text-muted);font-size:.68rem;font-weight:700;text-transform:uppercase}.corporate-format-form{--pdx-presentation-label-width: 132px;--pdx-presentation-label-size: .7rem;--pdx-presentation-value-size: .9rem;display:block;padding:12px;border:1px solid var(--pdx-ergadm-border);border-radius:14px;background:color-mix(in srgb,var(--pdx-ergadm-bg) 90%,var(--pdx-ergadm-surface-strong))}@media(max-width:960px){.legacy-workbench,.corporate-gallery-heading{grid-template-columns:1fr}}@media(max-width:720px){.legacy-presentation-card{padding:18px;border-radius:20px}.legacy-presentation-header{display:grid}.legacy-presentation-badge{width:fit-content}.legacy-records-panel,.legacy-detail-panel{border-radius:12px}.legacy-panel-heading,.legacy-detail-toolbar{display:grid}.legacy-record-table{min-width:460px}.legacy-frequency-form{--pdx-presentation-label-width: 104px}.corporate-kpi-strip{grid-template-columns:1fr}.corporate-format-form{--pdx-presentation-label-width: 104px;padding:10px}}\n"], dependencies: [{ kind: "ngmodule", type: MatCardModule }, { kind: "component", type: i7$1.MatCard, selector: "mat-card", inputs: ["appearance"], exportAs: ["matCard"] }, { kind: "ngmodule", type: MatIconModule }, { kind: "component", type: i4.MatIcon, selector: "mat-icon", inputs: ["color", "inline", "svgIcon", "fontSet", "fontIcon"], exportAs: ["matIcon"] }, { kind: "component", type: PraxisDynamicForm, selector: "praxis-dynamic-form", inputs: ["resourcePath", "resourceId", "initialValue", "editorialContext", "mode", "config", "actions", "schemaSource", "schemaUrl", "readUrl", "submitUrl", "submitMethod", "submitIdempotencyKey", "submitCorrelationId", "submitResourceVersion", "responseSchemaUrl", "apiEndpointKey", "apiUrlEntry", "enableCustomization", "showAiAssistant", "formId", "componentInstanceId", "configPersistenceStrategy", "layout", "generatedLayoutPreset", "layoutPolicy", "backConfig", "hooks", "removeEmptyContainersOnSave", "reactiveValidation", "reactiveValidationDebounceMs", "notifyIfOutdated", "snoozeMs", "autoOpenSettingsOnOutdated", "readonlyModeGlobal", "disabledModeGlobal", "presentationModeGlobal", "visibleGlobal", "fieldIconPolicy", "domainRules", "customEndpoints"], outputs: ["formSubmit", "formCancel", "formReset", "configChange", "configPatchChange", "formReady", "valueChange", "syncCompleted", "initializationError", "loadingStateChange", "enableCustomizationChange", "customAction", "actionConfirmation", "schemaStatusChange", "fieldRenderError", "ruleDiagnosticsChange"] }], changeDetection: i0.ChangeDetectionStrategy.OnPush });
32461
+ static ɵcmp = i0.ɵɵngDeclareComponent({ minVersion: "17.0.0", version: "21.2.14", type: Ergadm00034CompactPresentationExampleComponent, isStandalone: true, selector: "praxis-ergadm00034-compact-presentation-example", ngImport: i0, template: "<mat-card class=\"legacy-presentation-card\" data-testid=\"ergadm00034-compact-fixture\">\n <div class=\"legacy-presentation-header\">\n <div>\n <p class=\"examples-eyebrow\">Exemplo visual da lib</p>\n <h2>{{ legacyFrequencyExample.title }}</h2>\n <p>\n Fixture visual representativo de <code>{{ legacyFrequencyExample.resourcePath }}</code>:\n cinco registros densos e detalhe gerado por <code>x-ui.group</code>, <code>order</code>\n e <code>width</code>, sem declarar <code>FormConfig.sections</code> no host.\n </p>\n </div>\n <div class=\"legacy-presentation-badge\">\n <mat-icon aria-hidden=\"true\">view_compact</mat-icon>\n <span>compactPresentation</span>\n </div>\n </div>\n\n <div class=\"legacy-workbench\">\n <section class=\"legacy-records-panel\" aria-labelledby=\"legacy-records-title\">\n <div class=\"legacy-panel-heading\">\n <div>\n <h3 id=\"legacy-records-title\">C\u00F3digos de frequ\u00EAncia</h3>\n <p>5 registros carregados</p>\n </div>\n <span class=\"legacy-count-chip\">fixture local</span>\n </div>\n\n <div class=\"legacy-table-wrap\">\n <table class=\"legacy-record-table\" aria-label=\"C\u00F3digos de frequ\u00EAncia\">\n <thead>\n <tr>\n <th scope=\"col\">Tipo</th>\n <th scope=\"col\">C\u00F3digo</th>\n <th scope=\"col\">Nome</th>\n <th scope=\"col\">Preench.</th>\n <th scope=\"col\">Marcador</th>\n </tr>\n </thead>\n <tbody>\n @for (row of legacyFrequencyRows; track row.codigo) {\n <tr [class.is-selected]=\"row.selected\">\n <td>{{ row.tipo }}</td>\n <td><strong>{{ row.codigo }}</strong></td>\n <td>{{ row.nome }}</td>\n <td>{{ row.preenchimento }}</td>\n <td>{{ row.marcador }}</td>\n </tr>\n }\n </tbody>\n </table>\n </div>\n </section>\n\n <section class=\"legacy-detail-panel\" aria-labelledby=\"legacy-detail-title\">\n <div class=\"legacy-detail-toolbar\">\n <div>\n <p class=\"legacy-detail-kicker\">Registro selecionado</p>\n <h3 id=\"legacy-detail-title\">AFA - Afastamento abonado</h3>\n </div>\n <div class=\"legacy-detail-actions\" aria-label=\"A\u00E7\u00F5es do registro\">\n <button type=\"button\" aria-label=\"Novo c\u00F3digo de frequ\u00EAncia\">\n <mat-icon aria-hidden=\"true\">add</mat-icon>\n </button>\n <button type=\"button\" aria-label=\"Editar c\u00F3digo de frequ\u00EAncia\">\n <mat-icon aria-hidden=\"true\">edit</mat-icon>\n </button>\n </div>\n </div>\n\n <div class=\"legacy-detail-tabs\" aria-label=\"Abas do detalhe\">\n <button type=\"button\" class=\"is-active\">\n <mat-icon aria-hidden=\"true\">fact_check</mat-icon>\n <span>Detalhes</span>\n </button>\n <button type=\"button\">\n <mat-icon aria-hidden=\"true\">gavel</mat-icon>\n <span>Documentos legais</span>\n </button>\n </div>\n\n <praxis-dynamic-form\n class=\"presentation-mode pres-label-left pres-density-compact legacy-frequency-form\"\n data-testid=\"ergadm00034-detail-form\"\n formId=\"legacy-frequency-compact-presentation-demo\"\n [config]=\"legacyFrequencyPresentationConfig\"\n [initialValue]=\"legacyFrequencyInitialValue\"\n mode=\"view\"\n [presentationModeGlobal]=\"true\"\n [enableCustomization]=\"false\"\n [showAiAssistant]=\"false\"\n ></praxis-dynamic-form>\n </section>\n </div>\n\n <section class=\"corporate-format-gallery\" data-testid=\"corporate-format-gallery\">\n <div class=\"corporate-gallery-heading\">\n <div>\n <p class=\"examples-eyebrow\">Valida\u00E7\u00E3o de apresenta\u00E7\u00E3o</p>\n <h2>{{ corporatePresentationExample.title }}</h2>\n <p>\n Fixture de <code>{{ corporatePresentationExample.resourcePath }}</code> para validar\n datas, moedas, percentuais, quantidades, documentos, listas e status em telas densas.\n </p>\n </div>\n <div class=\"corporate-kpi-strip\" aria-label=\"Resumo financeiro\">\n <span>\n <strong>R$ 1,38 mi</strong>\n <small>valor bruto</small>\n </span>\n <span>\n <strong>18,45%</strong>\n <small>margem</small>\n </span>\n <span>\n <strong>42</strong>\n <small>itens</small>\n </span>\n </div>\n </div>\n\n <praxis-dynamic-form\n class=\"presentation-mode pres-label-left pres-density-compact corporate-format-form\"\n data-testid=\"corporate-format-detail-form\"\n formId=\"corporate-format-gallery-demo\"\n [config]=\"corporatePresentationConfig\"\n [initialValue]=\"corporatePresentationInitialValue\"\n mode=\"view\"\n [presentationModeGlobal]=\"true\"\n [enableCustomization]=\"false\"\n [showAiAssistant]=\"false\"\n ></praxis-dynamic-form>\n </section>\n</mat-card>\n", styles: [":host{--pdx-ergadm-bg: var(--mat-sys-surface, var(--md-sys-color-surface, #ffffff));--pdx-ergadm-surface-strong: color-mix( in srgb, var(--mat-sys-surface-container-high, var(--md-sys-color-surface-container-high, #eef3f1)) 90%, var(--pdx-ergadm-bg) );--pdx-ergadm-border: color-mix( in srgb, var(--mat-sys-outline-variant, var(--md-sys-color-outline-variant, #c6d0cb)) 76%, transparent );--pdx-ergadm-text: var(--mat-sys-on-surface, var(--md-sys-color-on-surface, #17221d));--pdx-ergadm-text-muted: var( --mat-sys-on-surface-variant, var(--md-sys-color-on-surface-variant, #53625c) );--pdx-ergadm-primary: var(--mat-sys-primary, var(--md-sys-color-primary, #0f766e));--pdx-ergadm-primary-strong: color-mix(in srgb, var(--pdx-ergadm-primary) 82%, black);--pdx-ergadm-primary-soft: color-mix(in srgb, var(--pdx-ergadm-primary) 14%, transparent);--pdx-ergadm-chip-bg: color-mix( in srgb, var(--mat-sys-primary-container, var(--md-sys-color-primary-container, #dcefeb)) 74%, var(--pdx-ergadm-bg) );--pdx-ergadm-chip-text: var( --mat-sys-on-primary-container, var(--md-sys-color-on-primary-container, #123932) );--pdx-ergadm-shadow-soft: 0 18px 36px rgba(15, 23, 42, .06);display:block;min-width:0;color:var(--pdx-ergadm-text)}.legacy-presentation-card{padding:22px;border-radius:20px;border:1px solid var(--pdx-ergadm-border);background:linear-gradient(180deg,color-mix(in srgb,var(--pdx-ergadm-surface-strong) 86%,var(--pdx-ergadm-bg)) 0%,var(--pdx-ergadm-bg) 100%);box-shadow:var(--pdx-ergadm-shadow-soft)}.legacy-presentation-header{display:flex;align-items:flex-start;justify-content:space-between;gap:18px;margin-bottom:14px}.examples-eyebrow{margin:0;text-transform:uppercase;letter-spacing:.18em;font-size:.76rem;font-weight:800;color:color-mix(in srgb,var(--pdx-ergadm-primary) 84%,var(--pdx-ergadm-text))}.legacy-presentation-header h2{margin:6px 0 8px;font-size:clamp(1.18rem,1.6vw,1.48rem);line-height:1.14}.legacy-presentation-header p{margin:0;max-width:76ch;color:var(--pdx-ergadm-text-muted);line-height:1.55}.legacy-presentation-badge{display:inline-flex;align-items:center;gap:8px;flex:0 0 auto;padding:8px 12px;border-radius:999px;border:1px solid color-mix(in srgb,var(--pdx-ergadm-primary) 18%,transparent);background:var(--pdx-ergadm-chip-bg);color:var(--pdx-ergadm-chip-text);font-size:.82rem;font-weight:800}.legacy-workbench{display:grid;grid-template-columns:minmax(360px,.44fr) minmax(0,1fr);gap:14px;align-items:start}.legacy-records-panel,.legacy-detail-panel{min-width:0;border:1px solid var(--pdx-ergadm-border);border-radius:14px;background:color-mix(in srgb,var(--pdx-ergadm-bg) 88%,var(--pdx-ergadm-surface-strong))}.legacy-records-panel{overflow:hidden}.legacy-detail-panel{padding:12px}.legacy-panel-heading,.legacy-detail-toolbar{display:flex;align-items:flex-start;justify-content:space-between;gap:12px}.legacy-panel-heading{padding:12px 14px 10px;border-bottom:1px solid var(--pdx-ergadm-border)}.legacy-panel-heading h3,.legacy-detail-toolbar h3{margin:0;font-size:.98rem;line-height:1.25}.legacy-panel-heading p,.legacy-detail-kicker{margin:3px 0 0;color:var(--pdx-ergadm-text-muted);font-size:.76rem;line-height:1.35}.legacy-count-chip{flex:0 0 auto;padding:5px 8px;border-radius:999px;background:var(--pdx-ergadm-primary-soft);color:var(--pdx-ergadm-primary-strong);font-size:.68rem;font-weight:800;text-transform:uppercase}.legacy-table-wrap{overflow-x:auto}.legacy-record-table{width:100%;min-width:500px;border-collapse:collapse;font-size:.78rem;line-height:1.25}.legacy-record-table th,.legacy-record-table td{padding:8px 10px;text-align:left;white-space:nowrap;border-bottom:1px solid color-mix(in srgb,var(--pdx-ergadm-border) 78%,transparent)}.legacy-record-table th{color:var(--pdx-ergadm-text-muted);font-size:.66rem;font-weight:800;text-transform:uppercase}.legacy-record-table td:nth-child(3){max-width:190px;overflow:hidden;text-overflow:ellipsis}.legacy-record-table tr:last-child td{border-bottom:0}.legacy-record-table tr.is-selected td{background:color-mix(in srgb,var(--pdx-ergadm-primary) 11%,transparent)}.legacy-detail-actions{display:inline-flex;gap:6px;flex:0 0 auto}.legacy-detail-actions button{display:inline-grid;place-items:center;width:32px;height:32px;border:1px solid var(--pdx-ergadm-border);border-radius:8px;background:var(--pdx-ergadm-bg);color:var(--pdx-ergadm-primary-strong);cursor:default}.legacy-detail-actions mat-icon{width:18px;height:18px;font-size:18px}.legacy-detail-tabs{display:flex;gap:6px;margin:12px 0;padding-bottom:8px;border-bottom:1px solid var(--pdx-ergadm-border);overflow-x:auto}.legacy-detail-tabs button{display:inline-flex;align-items:center;gap:6px;min-height:30px;padding:5px 9px;border:1px solid transparent;border-radius:999px;background:transparent;color:var(--pdx-ergadm-text-muted);font:inherit;font-size:.78rem;font-weight:700;white-space:nowrap}.legacy-detail-tabs button.is-active{border-color:color-mix(in srgb,var(--pdx-ergadm-primary) 18%,transparent);background:var(--pdx-ergadm-primary-soft);color:var(--pdx-ergadm-primary-strong)}.legacy-detail-tabs mat-icon{width:16px;height:16px;font-size:16px}.legacy-frequency-form{--pdx-presentation-label-width: 116px;--pdx-presentation-label-size: .7rem;--pdx-presentation-value-size: .9rem;--pdx-presentation-flag-height: 20px;--pdx-presentation-flag-padding: 0 7px;display:block}.corporate-format-gallery{margin-top:18px;padding-top:18px;border-top:1px solid var(--pdx-ergadm-border)}.corporate-gallery-heading{display:grid;grid-template-columns:minmax(0,1fr) minmax(260px,.34fr);gap:16px;align-items:start;margin-bottom:12px}.corporate-gallery-heading h2{margin:6px 0 8px;font-size:clamp(1.08rem,1.35vw,1.32rem);line-height:1.16}.corporate-gallery-heading p{margin:0;max-width:82ch;color:var(--pdx-ergadm-text-muted);line-height:1.55}.corporate-kpi-strip{display:grid;grid-template-columns:repeat(3,minmax(0,1fr));gap:8px}.corporate-kpi-strip span{min-width:0;padding:10px;border:1px solid var(--pdx-ergadm-border);border-radius:12px;background:color-mix(in srgb,var(--pdx-ergadm-bg) 86%,var(--pdx-ergadm-primary-soft))}.corporate-kpi-strip strong,.corporate-kpi-strip small{display:block;min-width:0;overflow-wrap:anywhere}.corporate-kpi-strip strong{color:var(--pdx-ergadm-primary-strong);font-size:.96rem;line-height:1.2}.corporate-kpi-strip small{margin-top:3px;color:var(--pdx-ergadm-text-muted);font-size:.68rem;font-weight:700;text-transform:uppercase}.corporate-format-form{--pdx-presentation-label-width: 132px;--pdx-presentation-label-size: .7rem;--pdx-presentation-value-size: .9rem;display:block;padding:12px;border:1px solid var(--pdx-ergadm-border);border-radius:14px;background:color-mix(in srgb,var(--pdx-ergadm-bg) 90%,var(--pdx-ergadm-surface-strong))}@media(max-width:960px){.legacy-workbench,.corporate-gallery-heading{grid-template-columns:1fr}}@media(max-width:720px){.legacy-presentation-card{padding:18px;border-radius:20px}.legacy-presentation-header{display:grid}.legacy-presentation-badge{width:fit-content}.legacy-records-panel,.legacy-detail-panel{border-radius:12px}.legacy-panel-heading,.legacy-detail-toolbar{display:grid}.legacy-record-table{min-width:460px}.legacy-frequency-form{--pdx-presentation-label-width: 104px}.corporate-kpi-strip{grid-template-columns:1fr}.corporate-format-form{--pdx-presentation-label-width: 104px;padding:10px}}\n"], dependencies: [{ kind: "ngmodule", type: MatCardModule }, { kind: "component", type: i7$1.MatCard, selector: "mat-card", inputs: ["appearance"], exportAs: ["matCard"] }, { kind: "ngmodule", type: MatIconModule }, { kind: "component", type: i4.MatIcon, selector: "mat-icon", inputs: ["color", "inline", "svgIcon", "fontSet", "fontIcon"], exportAs: ["matIcon"] }, { kind: "component", type: PraxisDynamicForm, selector: "praxis-dynamic-form", inputs: ["resourcePath", "resourceId", "initialValue", "editorialContext", "mode", "config", "actions", "schemaSource", "schemaUrl", "readUrl", "submitUrl", "submitMethod", "submitIdempotencyKey", "submitCorrelationId", "submitResourceVersion", "responseSchemaUrl", "apiEndpointKey", "apiUrlEntry", "enableCustomization", "showAiAssistant", "formId", "componentInstanceId", "configPersistenceStrategy", "layout", "generatedLayoutPreset", "layoutPolicy", "backConfig", "hooks", "removeEmptyContainersOnSave", "reactiveValidation", "reactiveValidationDebounceMs", "notifyIfOutdated", "snoozeMs", "autoOpenSettingsOnOutdated", "readonlyModeGlobal", "disabledModeGlobal", "presentationModeGlobal", "visibleGlobal", "fieldIconPolicy", "domainRules", "customEndpoints"], outputs: ["formSubmit", "formCancel", "formReset", "configChange", "configPatchChange", "formReady", "valueChange", "syncCompleted", "initializationError", "loadingStateChange", "enableCustomizationChange", "customAction", "actionConfirmation", "schemaStatusChange", "fieldRenderError", "ruleDiagnosticsChange", "reactiveDeterminationExecuted", "reactiveDeterminationPendingChange"] }], changeDetection: i0.ChangeDetectionStrategy.OnPush });
31744
32462
  }
31745
32463
  i0.ɵɵngDeclareClassMetadata({ minVersion: "12.0.0", version: "21.2.14", ngImport: i0, type: Ergadm00034CompactPresentationExampleComponent, decorators: [{
31746
32464
  type: Component,
@@ -35317,7 +36035,7 @@ const FORM_COMPONENT_AI_CAPABILITIES = {
35317
36035
  category: 'inputs',
35318
36036
  valueKind: 'enum',
35319
36037
  allowedValues: ENUMS.layoutPolicyPartialRowStrategy,
35320
- description: 'Define se linhas parciais com dois campos ou mais preservam os spans canônicos ou redistribuem apenas campos compatíveis para completar 12 colunas no breakpoint atual.',
36038
+ description: 'Define se cada linha visual parcial, depois de resolver visibilidade responsiva, CSS order e wrap, preserva os spans canônicos ou redistribui apenas campos compatíveis para completar 12 colunas no breakpoint atual.',
35321
36039
  safetyNotes: 'fill-compatible é uma projeção transitória do runtime: não altera x-ui.width nem persiste sections. Controles compactos, uploads e tipos desconhecidos preservam a largura canônica.',
35322
36040
  },
35323
36041
  {