@praxisui/dynamic-form 8.0.0-beta.11 → 8.0.0-beta.12

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.
@@ -23,16 +23,16 @@ import { MatBadgeModule } from '@angular/material/badge';
23
23
  import { firstValueFrom, BehaviorSubject, Subject, throwError, debounceTime as debounceTime$1, takeUntil as takeUntil$1 } from 'rxjs';
24
24
  import { map, take, takeUntil, timeout, tap, debounceTime, finalize } from 'rxjs/operators';
25
25
  import * as i1$2 from '@praxisui/core';
26
- import { PraxisI18nService, PraxisIconDirective, providePraxisI18nConfig, RULE_PROPERTY_SCHEMA, FIELD_METADATA_CAPABILITIES, deepMerge, createDefaultFormConfig, normalizeFormConfig as normalizeFormConfig$1, ensureIds, createEmptyRichContentDocument, ASYNC_CONFIG_STORAGE, migrateFormLayoutRule, LoggerService, createCorporateLoggerConfig, ConsoleLoggerSink, ResourceQuickConnectComponent, composeHeadersWithVersion, buildApiUrl, mapFieldDefinitionsToMetadata, reconcileFormConfig, syncWithServerMetadata, PRAXIS_LOADING_CTX, normalizeControlTypeKey, resolveSpan, resolveOffset, resolveOrder, resolveHidden, 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, PraxisJsonLogicService } from '@praxisui/core';
26
+ import { PraxisI18nService, PraxisIconDirective, providePraxisI18nConfig, RULE_PROPERTY_SCHEMA, FIELD_METADATA_CAPABILITIES, deepMerge, createDefaultFormConfig, normalizeFormConfig as normalizeFormConfig$1, ensureIds, createEmptyRichContentDocument, ASYNC_CONFIG_STORAGE, migrateFormLayoutRule, normalizeFormLayoutItems, createFieldLayoutItem, getFormLayoutFieldNames, LoggerService, createCorporateLoggerConfig, ConsoleLoggerSink, ResourceQuickConnectComponent, composeHeadersWithVersion, buildApiUrl, mapFieldDefinitionsToMetadata, reconcileFormConfig, syncWithServerMetadata, PRAXIS_LOADING_CTX, normalizeControlTypeKey, getFormColumnFieldNames, resolveSpan, resolveOffset, resolveOrder, resolveHidden, 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, PraxisJsonLogicService } from '@praxisui/core';
27
27
  import * as i1 from '@praxisui/dynamic-fields';
28
28
  import { getControlTypeCatalog, ConfirmDialogComponent, DynamicFieldLoaderDirective } from '@praxisui/dynamic-fields';
29
29
  import { BaseAiAdapter, PraxisAiAssistantComponent } from '@praxisui/ai';
30
- import { PraxisRichContent } from '@praxisui/rich-content';
30
+ import { PraxisRichContent, PraxisRichContentConfigEditor } from '@praxisui/rich-content';
31
31
  import * as i6 from '@angular/material/menu';
32
32
  import { MatMenuModule } from '@angular/material/menu';
33
33
  import { produce } from 'immer';
34
34
  import * as i7 from '@praxisui/settings-panel';
35
- import { SETTINGS_PANEL_DATA, GLOBAL_CONFIG_DYNAMIC_FORM_COMPONENT } from '@praxisui/settings-panel';
35
+ import { SettingsPanelService, SETTINGS_PANEL_DATA, GLOBAL_CONFIG_DYNAMIC_FORM_COMPONENT } from '@praxisui/settings-panel';
36
36
  import * as i12 from '@angular/router';
37
37
  import * as i7$3 from '@angular/material/tabs';
38
38
  import { MatTabsModule } from '@angular/material/tabs';
@@ -1157,7 +1157,7 @@ function generateRulePropertyWhenFalseCapabilities(targetType, properties) {
1157
1157
  return result;
1158
1158
  }
1159
1159
  const FORM_AI_CAPABILITIES = {
1160
- version: 'v1.10', // Migrates editorial hosting to RichContentDocument while preserving richer section authoring affordances.
1160
+ version: 'v1.11', // Publishes column layout items and visual block authoring paths.
1161
1161
  enums: ENUMS$1,
1162
1162
  targets: [
1163
1163
  'praxis-dynamic-form',
@@ -1177,7 +1177,8 @@ const FORM_AI_CAPABILITIES = {
1177
1177
  'Este catálogo foca em configurações de alto nível (macro) do formulário e regras.',
1178
1178
  'Detalhes de propriedades internas de campos individuais devem ser tratados em catálogos de microcomponentes.',
1179
1179
  'Referencie campos pelo name em fieldMetadata[].name.',
1180
- 'Para hierarquia do layout use sections[].rows[].columns[].fields (campos por coluna).',
1180
+ 'Para hierarquia do layout use sections[].rows[].columns[].items como contrato canônico ordenado; items kind:"field" referenciam fieldMetadata e items kind:"richContent" são blocos visuais fora do payload.',
1181
+ 'sections[].rows[].columns[].fields permanece como projeção/migração de campos; não use fields para criar blocos visuais.',
1181
1182
  'POLICY: Ao alterar arrays de layout (sections, rows, columns), o patch deve ser tratado como merge/append, não replace total.',
1182
1183
  'Condições booleanas declarativas devem usar Json Logic canônico. Funções, handlers e hooks continuam exigindo revisão de segurança ou wiring pelo host.',
1183
1184
  'Regras condicionais devem usar JSON Logic canônico em rules.condition. Não utilize JS puro nem string ad hoc.',
@@ -1726,18 +1727,71 @@ const FORM_AI_CAPABILITIES = {
1726
1727
  path: 'sections[].rows[].columns[].fields',
1727
1728
  category: 'layout',
1728
1729
  valueKind: 'array',
1729
- description: 'Lista ordenada de nomes de campos (strings) dentro da coluna.',
1730
+ description: 'Projeção legada/derivada dos itens kind:"field" dentro da coluna.',
1730
1731
  critical: true,
1731
1732
  intentExamples: ['mover campo para a primeira coluna', 'reordenar campos na coluna'],
1732
- safetyNotes: 'Apenas nomes de campos (strings). Garanta que o nome do campo referenciado exista em fieldMetadata[].',
1733
+ safetyNotes: 'Use sections[].rows[].columns[].items para patches novos. fields não suporta blocos visuais.',
1733
1734
  },
1734
1735
  {
1735
1736
  path: 'sections[].rows[].columns[].fields[]',
1736
1737
  category: 'layout',
1737
1738
  valueKind: 'string',
1738
- description: 'Nome do campo dentro da coluna.',
1739
+ description: 'Nome do campo dentro da projeção legada/derivada da coluna.',
1739
1740
  critical: true,
1740
- safetyNotes: 'Apenas nomes de campos (strings). Garanta que o nome do campo referenciado exista em fieldMetadata[].',
1741
+ safetyNotes: 'Apenas nomes de campos. Para ordem mista entre campos e blocos visuais, use items[].',
1742
+ },
1743
+ {
1744
+ path: 'sections[].rows[].columns[].items',
1745
+ category: 'layout',
1746
+ valueKind: 'array',
1747
+ description: 'Lista canônica ordenada de itens da coluna: campos e blocos visuais.',
1748
+ critical: true,
1749
+ intentExamples: ['adicionar bloco visual na coluna', 'mover texto entre campos', 'reordenar campo e aviso visual'],
1750
+ safetyNotes: 'Itens kind:"field" devem apontar para fieldMetadata[].name. Itens kind:"richContent" não entram no payload de submit.',
1751
+ },
1752
+ {
1753
+ path: 'sections[].rows[].columns[].items[].kind',
1754
+ category: 'layout',
1755
+ valueKind: 'enum',
1756
+ allowedValues: ['field', 'richContent'],
1757
+ description: 'Tipo do item de layout da coluna.',
1758
+ critical: true,
1759
+ },
1760
+ {
1761
+ path: 'sections[].rows[].columns[].items[].id',
1762
+ category: 'layout',
1763
+ valueKind: 'string',
1764
+ description: 'ID estável do item de layout dentro do formulário.',
1765
+ critical: true,
1766
+ safetyNotes: 'Use IDs estáveis para mover/atualizar/remover itens; não use índice como identidade.',
1767
+ },
1768
+ {
1769
+ path: 'sections[].rows[].columns[].items[].fieldName',
1770
+ category: 'layout',
1771
+ valueKind: 'string',
1772
+ description: 'Nome do campo quando kind é "field".',
1773
+ critical: true,
1774
+ safetyNotes: 'Deve existir em fieldMetadata[].name.',
1775
+ },
1776
+ {
1777
+ path: 'sections[].rows[].columns[].items[].document',
1778
+ category: 'editorial',
1779
+ valueKind: 'object',
1780
+ description: 'RichContentDocument do bloco visual quando kind é "richContent".',
1781
+ safetyNotes: 'Não participa do formData nem do payload HTTP de submissão.',
1782
+ },
1783
+ {
1784
+ path: 'sections[].rows[].columns[].items[].layout',
1785
+ category: 'editorial',
1786
+ valueKind: 'enum',
1787
+ allowedValues: ['block', 'inline'],
1788
+ description: 'Modo de renderização do bloco visual richContent dentro da coluna.',
1789
+ },
1790
+ {
1791
+ path: 'sections[].rows[].columns[].items[].rootClassName',
1792
+ category: 'appearance',
1793
+ valueKind: 'string',
1794
+ description: 'Classe CSS opcional aplicada ao bloco visual richContent.',
1741
1795
  },
1742
1796
  {
1743
1797
  path: 'sections[].rows[].columns[].span.xs',
@@ -3020,6 +3074,13 @@ const TASK_PRESETS = {
3020
3074
  'sections[].headerActions[].disabled',
3021
3075
  'sections[].rows[].gap',
3022
3076
  'sections[].rows[].rowGap',
3077
+ 'sections[].rows[].columns[].items[]',
3078
+ 'sections[].rows[].columns[].items[].kind',
3079
+ 'sections[].rows[].columns[].items[].id',
3080
+ 'sections[].rows[].columns[].items[].fieldName',
3081
+ 'sections[].rows[].columns[].items[].document',
3082
+ 'sections[].rows[].columns[].items[].layout',
3083
+ 'sections[].rows[].columns[].items[].rootClassName',
3023
3084
  'sections[].rows[].columns[].fields[]',
3024
3085
  'sections[].rows[].columns[].span.*',
3025
3086
  'sections[].rows[].columns[].offset.*',
@@ -4347,18 +4408,18 @@ class DynamicFormLayoutService {
4347
4408
  this.changesSubject.next({ timestamp: Date.now(), op, config });
4348
4409
  }
4349
4410
  normalizeConfig(config) {
4350
- return produce(config, (draft) => {
4411
+ return ensureIds(produce(config, (draft) => {
4351
4412
  draft.sections = draft.sections || [];
4352
4413
  draft.sections.forEach((section) => {
4353
4414
  section.rows = section.rows || [];
4354
4415
  section.rows.forEach((row) => {
4355
4416
  row.columns = row.columns || [];
4356
4417
  row.columns.forEach((col) => {
4357
- col.fields = (col.fields || []).map((f) => typeof f === 'string' ? { name: f } : f);
4418
+ this.applyLayoutItemsToColumn(col, normalizeFormLayoutItems(col));
4358
4419
  });
4359
4420
  });
4360
4421
  });
4361
- });
4422
+ }));
4362
4423
  }
4363
4424
  validateConfig(config) {
4364
4425
  const errors = [];
@@ -4373,11 +4434,23 @@ class DynamicFormLayoutService {
4373
4434
  return;
4374
4435
  }
4375
4436
  row.columns.forEach((col, cIdx) => {
4376
- if (!col.fields) {
4377
- errors.push(`section[${sIdx}].row[${rIdx}].column[${cIdx}] missing fields`);
4437
+ const rawItems = col.items;
4438
+ if (Array.isArray(rawItems)) {
4439
+ rawItems.forEach((item, itemIdx) => {
4440
+ if (item?.kind === 'field' && !item.fieldName) {
4441
+ errors.push(`field item at section[${sIdx}].row[${rIdx}].column[${cIdx}].item[${itemIdx}] missing fieldName`);
4442
+ }
4443
+ else if (item?.kind === 'richContent' && !item.document) {
4444
+ errors.push(`richContent item at section[${sIdx}].row[${rIdx}].column[${cIdx}].item[${itemIdx}] missing document`);
4445
+ }
4446
+ else if (item?.kind !== 'field' && item?.kind !== 'richContent') {
4447
+ errors.push(`layout item at section[${sIdx}].row[${rIdx}].column[${cIdx}].item[${itemIdx}] has invalid kind`);
4448
+ }
4449
+ });
4378
4450
  return;
4379
4451
  }
4380
- col.fields.forEach((field, fIdx) => {
4452
+ const fields = Array.isArray(col.fields) ? col.fields : [];
4453
+ fields.forEach((field, fIdx) => {
4381
4454
  const name = typeof field === 'string' ? field : field?.name;
4382
4455
  if (!name) {
4383
4456
  errors.push(`field at section[${sIdx}].row[${rIdx}].column[${cIdx}].field[${fIdx}] missing name`);
@@ -4641,11 +4714,15 @@ class DynamicFormLayoutService {
4641
4714
  // Objetivo: 2 campos por linha em telas md+ (6/12 cada) e 1 por linha em xs/sm (12/12)
4642
4715
  const perRow = Math.max(1, fieldsPerRow || 2);
4643
4716
  const base = Math.max(1, Math.floor(12 / perRow));
4644
- const columns = rowFields.map((field) => ({
4645
- id: this.genId('col'),
4646
- fields: [field.name],
4647
- span: { xs: 12, sm: 12, md: base, lg: base, xl: base },
4648
- }));
4717
+ const columns = rowFields.map((field, index) => {
4718
+ const items = [createFieldLayoutItem(field.name, index)];
4719
+ return {
4720
+ id: this.genId('col'),
4721
+ items,
4722
+ fields: getFormLayoutFieldNames(items),
4723
+ span: { xs: 12, sm: 12, md: base, lg: base, xl: base },
4724
+ };
4725
+ });
4649
4726
  rows.push({ id: this.genId('row'), columns });
4650
4727
  }
4651
4728
  return rows;
@@ -4671,6 +4748,89 @@ class DynamicFormLayoutService {
4671
4748
  this.emit(op, next);
4672
4749
  return { config: next, op };
4673
4750
  }
4751
+ getFieldName(field) {
4752
+ if (typeof field === 'string')
4753
+ return field;
4754
+ if (field && typeof field === 'object') {
4755
+ const name = field.name;
4756
+ return typeof name === 'string' ? name : null;
4757
+ }
4758
+ return null;
4759
+ }
4760
+ findFieldLayoutItemIndex(items, fieldName, fieldIndex) {
4761
+ let visibleFieldIndex = 0;
4762
+ for (let index = 0; index < items.length; index++) {
4763
+ const item = items[index];
4764
+ if (item.kind !== 'field')
4765
+ continue;
4766
+ if (fieldIndex !== undefined && visibleFieldIndex === fieldIndex) {
4767
+ return index;
4768
+ }
4769
+ if (fieldIndex === undefined && fieldName && item.fieldName === fieldName) {
4770
+ return index;
4771
+ }
4772
+ visibleFieldIndex++;
4773
+ }
4774
+ return fieldName
4775
+ ? items.findIndex((item) => item.kind === 'field' && item.fieldName === fieldName)
4776
+ : -1;
4777
+ }
4778
+ getLayoutInsertIndexForFieldIndex(items, fieldIndex) {
4779
+ let visibleFieldIndex = 0;
4780
+ for (let index = 0; index < items.length; index++) {
4781
+ if (items[index].kind !== 'field')
4782
+ continue;
4783
+ if (visibleFieldIndex === fieldIndex)
4784
+ return index;
4785
+ visibleFieldIndex++;
4786
+ }
4787
+ return items.length;
4788
+ }
4789
+ applyLayoutItemsToColumn(column, items) {
4790
+ column.items = items;
4791
+ column.fields = getFormLayoutFieldNames(items);
4792
+ }
4793
+ insertFieldLayoutItem(column, field, fieldIndex) {
4794
+ const fieldName = this.getFieldName(field);
4795
+ if (!fieldName)
4796
+ return;
4797
+ const items = normalizeFormLayoutItems(column);
4798
+ const layoutIndex = this.getLayoutInsertIndexForFieldIndex(items, fieldIndex);
4799
+ items.splice(layoutIndex, 0, createFieldLayoutItem(fieldName, fieldIndex));
4800
+ this.applyLayoutItemsToColumn(column, items);
4801
+ }
4802
+ removeFieldLayoutItem(column, fieldIndex) {
4803
+ const items = normalizeFormLayoutItems(column);
4804
+ const layoutIndex = this.findFieldLayoutItemIndex(items, null, fieldIndex);
4805
+ if (layoutIndex >= 0) {
4806
+ items.splice(layoutIndex, 1);
4807
+ }
4808
+ this.applyLayoutItemsToColumn(column, items);
4809
+ }
4810
+ hasLayoutItems(column) {
4811
+ return normalizeFormLayoutItems(column).length > 0;
4812
+ }
4813
+ moveFieldLayoutItem(sourceColumn, destinationColumn, movedField, fromFieldIndex, toFieldIndex) {
4814
+ const fieldName = this.getFieldName(movedField);
4815
+ if (!fieldName)
4816
+ return;
4817
+ const sourceItems = normalizeFormLayoutItems(sourceColumn);
4818
+ const sourceItemIndex = this.findFieldLayoutItemIndex(sourceItems, fieldName, fromFieldIndex);
4819
+ const [movedItem] = sourceItemIndex >= 0
4820
+ ? sourceItems.splice(sourceItemIndex, 1)
4821
+ : [createFieldLayoutItem(fieldName, toFieldIndex)];
4822
+ if (sourceColumn === destinationColumn) {
4823
+ const destinationIndex = this.getLayoutInsertIndexForFieldIndex(sourceItems, toFieldIndex);
4824
+ sourceItems.splice(destinationIndex, 0, movedItem);
4825
+ this.applyLayoutItemsToColumn(sourceColumn, sourceItems);
4826
+ return;
4827
+ }
4828
+ const destinationItems = normalizeFormLayoutItems(destinationColumn);
4829
+ const destinationIndex = this.getLayoutInsertIndexForFieldIndex(destinationItems, toFieldIndex);
4830
+ destinationItems.splice(destinationIndex, 0, movedItem);
4831
+ this.applyLayoutItemsToColumn(sourceColumn, sourceItems);
4832
+ this.applyLayoutItemsToColumn(destinationColumn, destinationItems);
4833
+ }
4674
4834
  moveSection(config, fromIndex, toIndex) {
4675
4835
  const op = { type: 'moveSection', fromIndex, toIndex };
4676
4836
  if (fromIndex === toIndex) {
@@ -4858,12 +5018,12 @@ class DynamicFormLayoutService {
4858
5018
  columnId: dstCols[to.colIndex].id,
4859
5019
  };
4860
5020
  return this.mutate(config, op, (draft) => {
4861
- const src = draft.sections[from.sectionIndex].rows[from.rowIndex]
4862
- .columns[from.colIndex].fields;
4863
- const [moved] = src.splice(from.fieldIndex, 1);
4864
- const dst = draft.sections[to.sectionIndex].rows[to.rowIndex].columns[to.colIndex].fields;
4865
- dst.splice(to.toFieldIndex, 0, moved);
4866
- if (policy === 'pruneEmptyContainers' && src.length === 0) {
5021
+ const srcColumn = draft.sections[from.sectionIndex].rows[from.rowIndex]
5022
+ .columns[from.colIndex];
5023
+ const dstColumn = draft.sections[to.sectionIndex].rows[to.rowIndex].columns[to.colIndex];
5024
+ const moved = srcColumn.fields[from.fieldIndex];
5025
+ this.moveFieldLayoutItem(srcColumn, dstColumn, moved, from.fieldIndex, to.toFieldIndex);
5026
+ if (policy === 'pruneEmptyContainers' && !this.hasLayoutItems(srcColumn)) {
4867
5027
  draft.sections[from.sectionIndex].rows[from.rowIndex].columns.splice(from.colIndex, 1);
4868
5028
  pruned.push('column');
4869
5029
  const draftRow = draft.sections[from.sectionIndex].rows[from.rowIndex];
@@ -4892,8 +5052,8 @@ class DynamicFormLayoutService {
4892
5052
  this.assertIndex(atIdx, fields.length, 'atIdx', true);
4893
5053
  const op = { type: 'insertField', target, field, atIdx };
4894
5054
  return this.mutate(config, op, (draft) => {
4895
- const draftFields = draft.sections[target.sectionIndex].rows[target.rowIndex].columns[target.colIndex].fields;
4896
- draftFields.splice(atIdx, 0, field);
5055
+ const draftColumn = draft.sections[target.sectionIndex].rows[target.rowIndex].columns[target.colIndex];
5056
+ this.insertFieldLayoutItem(draftColumn, field, atIdx);
4897
5057
  });
4898
5058
  }
4899
5059
  removeField(config, secIdx, rowIdx, colIdx, fieldIndex, options = {}) {
@@ -4928,10 +5088,9 @@ class DynamicFormLayoutService {
4928
5088
  };
4929
5089
  const pruned = [];
4930
5090
  return this.mutate(config, op, (draft) => {
4931
- const draftFields = draft.sections[secIdx].rows[rowIdx].columns[colIdx]
4932
- .fields;
4933
- draftFields.splice(fieldIndex, 1);
4934
- if (policy === 'pruneEmptyContainers' && draftFields.length === 0) {
5091
+ const draftColumn = draft.sections[secIdx].rows[rowIdx].columns[colIdx];
5092
+ this.removeFieldLayoutItem(draftColumn, fieldIndex);
5093
+ if (policy === 'pruneEmptyContainers' && !this.hasLayoutItems(draftColumn)) {
4935
5094
  draft.sections[secIdx].rows[rowIdx].columns.splice(colIdx, 1);
4936
5095
  pruned.push('column');
4937
5096
  if (draft.sections[secIdx].rows[rowIdx].columns.length === 0) {
@@ -5135,13 +5294,13 @@ class DynamicFormLayoutService {
5135
5294
  this.assertIndex(to.toIndex, dstFields.length, 'to.toIndex', true);
5136
5295
  const pruned = [];
5137
5296
  return this.mutate(config, op, (draft) => {
5138
- const src = draft.sections[fromPath.sectionIndex].rows[fromPath.rowIndex]
5139
- .columns[fromPath.colIndex].fields;
5140
- const [moved] = src.splice(fromPath.fieldIndex, 1);
5141
- const dst = draft.sections[toPath.sectionIndex].rows[toPath.rowIndex]
5142
- .columns[toPath.colIndex].fields;
5143
- dst.splice(to.toIndex, 0, moved);
5144
- if (policy === 'pruneEmptyContainers' && src.length === 0) {
5297
+ const srcColumn = draft.sections[fromPath.sectionIndex].rows[fromPath.rowIndex]
5298
+ .columns[fromPath.colIndex];
5299
+ const dstColumn = draft.sections[toPath.sectionIndex].rows[toPath.rowIndex]
5300
+ .columns[toPath.colIndex];
5301
+ const moved = srcColumn.fields[fromPath.fieldIndex];
5302
+ this.moveFieldLayoutItem(srcColumn, dstColumn, moved, fromPath.fieldIndex, to.toIndex);
5303
+ if (policy === 'pruneEmptyContainers' && !this.hasLayoutItems(srcColumn)) {
5145
5304
  draft.sections[fromPath.sectionIndex].rows[fromPath.rowIndex].columns.splice(fromPath.colIndex, 1);
5146
5305
  pruned.push('column');
5147
5306
  const draftRow = draft.sections[fromPath.sectionIndex].rows[fromPath.rowIndex];
@@ -5167,9 +5326,159 @@ class DynamicFormLayoutService {
5167
5326
  this.assertIndex(index, fields.length, 'atIndex', true);
5168
5327
  const op = { type: 'insertField', target, field, atIndex: index };
5169
5328
  return this.mutate(config, op, (draft) => {
5170
- const draftFields = draft.sections[path.sectionIndex].rows[path.rowIndex]
5171
- .columns[path.colIndex].fields;
5172
- draftFields.splice(index, 0, field);
5329
+ const draftColumn = draft.sections[path.sectionIndex].rows[path.rowIndex]
5330
+ .columns[path.colIndex];
5331
+ this.insertFieldLayoutItem(draftColumn, field, index);
5332
+ });
5333
+ }
5334
+ insertLayoutItemById(config, target, item, atIndex) {
5335
+ const path = this.resolvePathByIds(config, target);
5336
+ const column = config.sections[path.sectionIndex].rows[path.rowIndex].columns[path.colIndex];
5337
+ const items = normalizeFormLayoutItems(column);
5338
+ const index = atIndex ?? items.length;
5339
+ this.assertIndex(index, items.length, 'atIndex', true);
5340
+ const op = {
5341
+ type: 'insertLayoutItem',
5342
+ target,
5343
+ itemId: item.id,
5344
+ atIndex: index,
5345
+ };
5346
+ return this.mutate(config, op, (draft) => {
5347
+ const draftColumn = draft.sections[path.sectionIndex].rows[path.rowIndex].columns[path.colIndex];
5348
+ const draftItems = normalizeFormLayoutItems(draftColumn);
5349
+ draftItems.splice(index, 0, item);
5350
+ this.applyLayoutItemsToColumn(draftColumn, draftItems);
5351
+ });
5352
+ }
5353
+ moveLayoutItemById(config, from, to, options = {}) {
5354
+ const fromPath = this.resolvePathByIds(config, from);
5355
+ const toPath = this.resolvePathByIds(config, to);
5356
+ const sourceColumn = config.sections[fromPath.sectionIndex].rows[fromPath.rowIndex].columns[fromPath.colIndex];
5357
+ const sourceItems = normalizeFormLayoutItems(sourceColumn);
5358
+ const fromIndex = sourceItems.findIndex((item) => item.id === from.itemId);
5359
+ if (fromIndex < 0) {
5360
+ throw new Error(`itemId not found: ${from.itemId}`);
5361
+ }
5362
+ const destinationColumn = config.sections[toPath.sectionIndex].rows[toPath.rowIndex].columns[toPath.colIndex];
5363
+ const destinationLength = from.sectionId === to.sectionId &&
5364
+ from.rowId === to.rowId &&
5365
+ from.columnId === to.columnId
5366
+ ? sourceItems.length - 1
5367
+ : normalizeFormLayoutItems(destinationColumn).length;
5368
+ this.assertIndex(to.toIndex, destinationLength, 'to.toIndex', true);
5369
+ const policy = options.policy ?? 'keepEmptyContainers';
5370
+ const op = {
5371
+ type: 'moveLayoutItem',
5372
+ correlationId: options.correlationId,
5373
+ origin: options.origin,
5374
+ from: {
5375
+ sectionId: from.sectionId,
5376
+ rowId: from.rowId,
5377
+ columnId: from.columnId,
5378
+ itemId: from.itemId,
5379
+ },
5380
+ to: {
5381
+ sectionId: to.sectionId,
5382
+ rowId: to.rowId,
5383
+ columnId: to.columnId,
5384
+ toIndex: to.toIndex,
5385
+ },
5386
+ policy,
5387
+ };
5388
+ const pruned = [];
5389
+ return this.mutate(config, op, (draft) => {
5390
+ const draftSourceColumn = draft.sections[fromPath.sectionIndex].rows[fromPath.rowIndex].columns[fromPath.colIndex];
5391
+ const draftSourceItems = normalizeFormLayoutItems(draftSourceColumn);
5392
+ const draftFromIndex = draftSourceItems.findIndex((item) => item.id === from.itemId);
5393
+ const [movedItem] = draftSourceItems.splice(draftFromIndex, 1);
5394
+ if (from.sectionId === to.sectionId &&
5395
+ from.rowId === to.rowId &&
5396
+ from.columnId === to.columnId) {
5397
+ draftSourceItems.splice(to.toIndex, 0, movedItem);
5398
+ this.applyLayoutItemsToColumn(draftSourceColumn, draftSourceItems);
5399
+ }
5400
+ else {
5401
+ const draftDestinationColumn = draft.sections[toPath.sectionIndex].rows[toPath.rowIndex].columns[toPath.colIndex];
5402
+ const draftDestinationItems = normalizeFormLayoutItems(draftDestinationColumn);
5403
+ draftDestinationItems.splice(to.toIndex, 0, movedItem);
5404
+ this.applyLayoutItemsToColumn(draftSourceColumn, draftSourceItems);
5405
+ this.applyLayoutItemsToColumn(draftDestinationColumn, draftDestinationItems);
5406
+ }
5407
+ if (policy === 'pruneEmptyContainers' &&
5408
+ !this.hasLayoutItems(draftSourceColumn)) {
5409
+ draft.sections[fromPath.sectionIndex].rows[fromPath.rowIndex].columns.splice(fromPath.colIndex, 1);
5410
+ pruned.push('column');
5411
+ const draftRow = draft.sections[fromPath.sectionIndex].rows[fromPath.rowIndex];
5412
+ if (draftRow.columns.length === 0) {
5413
+ draft.sections[fromPath.sectionIndex].rows.splice(fromPath.rowIndex, 1);
5414
+ pruned.push('row');
5415
+ if (draft.sections[fromPath.sectionIndex].rows.length === 0) {
5416
+ draft.sections.splice(fromPath.sectionIndex, 1);
5417
+ pruned.push('section');
5418
+ }
5419
+ }
5420
+ }
5421
+ if (pruned.length) {
5422
+ op.meta = { ...(op.meta || {}), pruned };
5423
+ }
5424
+ });
5425
+ }
5426
+ updateLayoutItemById(config, target, item) {
5427
+ const path = this.resolvePathByIds(config, target);
5428
+ const column = config.sections[path.sectionIndex].rows[path.rowIndex].columns[path.colIndex];
5429
+ const itemIndex = normalizeFormLayoutItems(column).findIndex((candidate) => candidate.id === target.itemId);
5430
+ if (itemIndex < 0) {
5431
+ throw new Error(`itemId not found: ${target.itemId}`);
5432
+ }
5433
+ const op = {
5434
+ type: 'updateLayoutItem',
5435
+ target,
5436
+ itemId: target.itemId,
5437
+ };
5438
+ return this.mutate(config, op, (draft) => {
5439
+ const draftColumn = draft.sections[path.sectionIndex].rows[path.rowIndex].columns[path.colIndex];
5440
+ const items = normalizeFormLayoutItems(draftColumn);
5441
+ items[itemIndex] = { ...item, id: target.itemId };
5442
+ this.applyLayoutItemsToColumn(draftColumn, items);
5443
+ });
5444
+ }
5445
+ removeLayoutItemById(config, sectionId, rowId, columnId, itemId, options = {}) {
5446
+ const path = this.resolvePathByIds(config, { sectionId, rowId, columnId });
5447
+ const column = config.sections[path.sectionIndex].rows[path.rowIndex].columns[path.colIndex];
5448
+ const itemIndex = normalizeFormLayoutItems(column).findIndex((item) => item.id === itemId);
5449
+ if (itemIndex < 0) {
5450
+ throw new Error(`itemId not found: ${itemId}`);
5451
+ }
5452
+ const policy = options.policy ?? 'keepEmptyContainers';
5453
+ const op = {
5454
+ type: 'removeLayoutItem',
5455
+ correlationId: options.correlationId,
5456
+ origin: options.origin,
5457
+ from: { sectionId, rowId, columnId, itemId },
5458
+ policy,
5459
+ };
5460
+ const pruned = [];
5461
+ return this.mutate(config, op, (draft) => {
5462
+ const draftColumn = draft.sections[path.sectionIndex].rows[path.rowIndex].columns[path.colIndex];
5463
+ const items = normalizeFormLayoutItems(draftColumn);
5464
+ items.splice(itemIndex, 1);
5465
+ this.applyLayoutItemsToColumn(draftColumn, items);
5466
+ if (policy === 'pruneEmptyContainers' && !this.hasLayoutItems(draftColumn)) {
5467
+ draft.sections[path.sectionIndex].rows[path.rowIndex].columns.splice(path.colIndex, 1);
5468
+ pruned.push('column');
5469
+ const row = draft.sections[path.sectionIndex].rows[path.rowIndex];
5470
+ if (row.columns.length === 0) {
5471
+ draft.sections[path.sectionIndex].rows.splice(path.rowIndex, 1);
5472
+ pruned.push('row');
5473
+ if (draft.sections[path.sectionIndex].rows.length === 0) {
5474
+ draft.sections.splice(path.sectionIndex, 1);
5475
+ pruned.push('section');
5476
+ }
5477
+ }
5478
+ }
5479
+ if (pruned.length) {
5480
+ op.meta = { ...(op.meta || {}), pruned };
5481
+ }
5173
5482
  });
5174
5483
  }
5175
5484
  removeFieldById(config, sectionId, rowId, columnId, fieldName, options = {}) {
@@ -5198,10 +5507,10 @@ class DynamicFormLayoutService {
5198
5507
  };
5199
5508
  const pruned = [];
5200
5509
  return this.mutate(config, op, (draft) => {
5201
- const fields = draft.sections[path.sectionIndex].rows[path.rowIndex]
5202
- .columns[path.colIndex].fields;
5203
- fields.splice(path.fieldIndex, 1);
5204
- if (policy === 'pruneEmptyContainers' && fields.length === 0) {
5510
+ const column = draft.sections[path.sectionIndex].rows[path.rowIndex]
5511
+ .columns[path.colIndex];
5512
+ this.removeFieldLayoutItem(column, path.fieldIndex);
5513
+ if (policy === 'pruneEmptyContainers' && !this.hasLayoutItems(column)) {
5205
5514
  draft.sections[path.sectionIndex].rows[path.rowIndex].columns.splice(path.colIndex, 1);
5206
5515
  pruned.push('column');
5207
5516
  const row = draft.sections[path.sectionIndex].rows[path.rowIndex];
@@ -5228,7 +5537,7 @@ class DynamicFormLayoutService {
5228
5537
  const pruned = this.mutate(config, op, (draft) => {
5229
5538
  draft.sections = (draft.sections || []).filter((section) => {
5230
5539
  section.rows = (section.rows || []).filter((row) => {
5231
- row.columns = (row.columns || []).filter((col) => col.fields?.length > 0);
5540
+ row.columns = (row.columns || []).filter((col) => this.hasLayoutItems(col));
5232
5541
  return row.columns.length > 0;
5233
5542
  });
5234
5543
  return section.rows.length > 0;
@@ -7495,7 +7804,7 @@ class PraxisDynamicForm {
7495
7804
  return true;
7496
7805
  }
7497
7806
  if (Array.isArray(row.columns) && row.columns.length > 0) {
7498
- const columnsWithFields = row.columns.filter((column) => Array.isArray(column.fields) && column.fields.length > 0);
7807
+ const columnsWithFields = row.columns.filter((column) => getFormColumnFieldNames(column).length > 0);
7499
7808
  if (columnsWithFields.length === 0) {
7500
7809
  return true;
7501
7810
  }
@@ -7513,7 +7822,7 @@ class PraxisDynamicForm {
7513
7822
  }
7514
7823
  getRowClasses(row) {
7515
7824
  const props = this.getRowRuleProps(row);
7516
- const key = row?.id || JSON.stringify(row?.columns?.map((column) => column.id || column.fields) || []);
7825
+ const key = row?.id || JSON.stringify(row?.columns?.map((column) => column.id || this.getColumnItemsSignature(column)) || []);
7517
7826
  const signature = String(props.className || '');
7518
7827
  const cached = this.rowClassesCache.get(key);
7519
7828
  if (cached?.signature === signature) {
@@ -7527,7 +7836,7 @@ class PraxisDynamicForm {
7527
7836
  }
7528
7837
  getRowStyles(row) {
7529
7838
  const props = this.getRowRuleProps(row);
7530
- const key = row?.id || JSON.stringify(row?.columns?.map((column) => column.id || column.fields) || []);
7839
+ const key = row?.id || JSON.stringify(row?.columns?.map((column) => column.id || this.getColumnItemsSignature(column)) || []);
7531
7840
  const signature = JSON.stringify(props.style || {});
7532
7841
  const cached = this.rowStylesCache.get(key);
7533
7842
  if (cached?.signature === signature) {
@@ -7886,15 +8195,56 @@ class PraxisDynamicForm {
7886
8195
  const rows = section?.rows || [];
7887
8196
  const fieldCount = rows.reduce((acc, row) => {
7888
8197
  const cols = row?.columns || [];
7889
- const colFields = cols.reduce((cAcc, col) => cAcc + ((col?.fields || []).length), 0);
8198
+ const colFields = cols.reduce((cAcc, col) => cAcc + getFormColumnFieldNames(col).length, 0);
7890
8199
  return acc + colFields;
7891
8200
  }, 0);
7892
8201
  const rowLabel = rows.length === 1 ? 'linha' : 'linhas';
7893
8202
  const fieldLabel = fieldCount === 1 ? 'campo' : 'campos';
7894
8203
  return `${rows.length} ${rowLabel}, ${fieldCount} ${fieldLabel}`;
7895
8204
  }
8205
+ getColumnItems(column) {
8206
+ return normalizeFormLayoutItems(column);
8207
+ }
8208
+ getColumnRenderItems(column) {
8209
+ const renderItems = [];
8210
+ let fieldBatch = [];
8211
+ const flushFieldBatch = () => {
8212
+ if (!fieldBatch.length)
8213
+ return;
8214
+ const batchItems = fieldBatch;
8215
+ fieldBatch = [];
8216
+ const id = `${column.id || 'column'}:fields:${renderItems.length}:${batchItems
8217
+ .map((item) => item.id)
8218
+ .join(',')}`;
8219
+ renderItems.push({
8220
+ kind: 'fields',
8221
+ id,
8222
+ fields: this.getColumnFields({ id, items: batchItems }),
8223
+ });
8224
+ };
8225
+ for (const item of this.getColumnItems(column)) {
8226
+ if (item.kind === 'field') {
8227
+ fieldBatch.push(item);
8228
+ continue;
8229
+ }
8230
+ flushFieldBatch();
8231
+ const document = this.getRichContentLayoutItemDocument(item);
8232
+ if (!document)
8233
+ continue;
8234
+ renderItems.push({
8235
+ kind: 'richContent',
8236
+ id: `${column.id || 'column'}:${item.id}`,
8237
+ document,
8238
+ layout: this.getRichContentLayoutItemLayout(item),
8239
+ rootClassName: item.kind === 'richContent' ? item.rootClassName ?? null : null,
8240
+ });
8241
+ }
8242
+ flushFieldBatch();
8243
+ return renderItems;
8244
+ }
7896
8245
  getColumnFields(column) {
7897
- const key = column.id || JSON.stringify(column.fields);
8246
+ const fieldNames = getFormColumnFieldNames(column);
8247
+ const key = column.id || JSON.stringify(fieldNames);
7898
8248
  const signature = this.getColumnFieldsSignature(column);
7899
8249
  const cached = this.columnFieldsCache.get(key);
7900
8250
  if (cached?.signature === signature) {
@@ -7903,7 +8253,7 @@ class PraxisDynamicForm {
7903
8253
  const fieldMetadata = this.config.fieldMetadata || [];
7904
8254
  const byName = new Map(fieldMetadata.map((f) => [f.name, f]));
7905
8255
  const ordered = [];
7906
- for (const name of column.fields) {
8256
+ for (const name of fieldNames) {
7907
8257
  if (this.fieldVisibility[name] === false)
7908
8258
  continue;
7909
8259
  const meta = byName.get(name);
@@ -7929,8 +8279,16 @@ class PraxisDynamicForm {
7929
8279
  this.columnFieldsCache.set(key, { signature, value: ordered });
7930
8280
  return ordered;
7931
8281
  }
8282
+ getRichContentLayoutItemDocument(item) {
8283
+ return item.kind === 'richContent' && item.document?.kind === 'praxis.rich-content'
8284
+ ? item.document
8285
+ : null;
8286
+ }
8287
+ getRichContentLayoutItemLayout(item) {
8288
+ return item.kind === 'richContent' ? item.layout ?? 'block' : 'block';
8289
+ }
7932
8290
  getColumnFieldsSignature(column) {
7933
- return column.fields
8291
+ return getFormColumnFieldNames(column)
7934
8292
  .map((name) => {
7935
8293
  const visible = this.fieldVisibility[name] === false ? '0' : '1';
7936
8294
  const overrides = this.fieldRuleProps[name];
@@ -7939,6 +8297,17 @@ class PraxisDynamicForm {
7939
8297
  })
7940
8298
  .join('|');
7941
8299
  }
8300
+ getColumnItemsSignature(column) {
8301
+ return normalizeFormLayoutItems(column)
8302
+ .map((item) => {
8303
+ if (item.kind === 'field') {
8304
+ return `field:${item.id}:${item.fieldName}`;
8305
+ }
8306
+ const nodeCount = item.document?.nodes?.length ?? 0;
8307
+ return `richContent:${item.id}:${item.layout ?? 'block'}:${nodeCount}`;
8308
+ })
8309
+ .join('|');
8310
+ }
7942
8311
  getColumnRuleProps(column) {
7943
8312
  if (!column || !column.id)
7944
8313
  return {};
@@ -8138,8 +8507,12 @@ class PraxisDynamicForm {
8138
8507
  return !this.isResponsiveHiddenActive(props.hidden);
8139
8508
  }
8140
8509
  }
8510
+ const items = this.getColumnItems(column);
8511
+ if (items.some((item) => item.kind === 'richContent')) {
8512
+ return true;
8513
+ }
8141
8514
  // A column is visible if at least one of its fields is visible.
8142
- return column.fields.some((fieldName) => this.fieldVisibility[fieldName]);
8515
+ return getFormLayoutFieldNames(items).some((fieldName) => this.fieldVisibility[fieldName]);
8143
8516
  }
8144
8517
  isResponsiveHiddenActive(hidden) {
8145
8518
  if (!hidden || typeof hidden !== 'object' || Array.isArray(hidden)) {
@@ -12282,7 +12655,7 @@ class PraxisDynamicForm {
12282
12655
  }
12283
12656
  }
12284
12657
  static ɵfac = i0.ɵɵngDeclareFactory({ minVersion: "12.0.0", version: "20.3.17", ngImport: i0, type: PraxisDynamicForm, deps: [{ token: i1$2.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$2.DynamicFormService }, { token: i9$1.MatSnackBar }, { token: CanvasStateService }, { token: DynamicFormLayoutService }, { token: i1$2.ErrorMessageService }, { token: i1$2.SchemaNormalizerService }, { token: i1$2.ComponentMetadataRegistry }, { token: i1$2.GlobalConfigService }, { token: i1$2.ComponentKeyService }, { token: i1$2.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$2.FormHooksRegistry, optional: true }, { token: FORM_HOOKS_PRESETS, optional: true }, { token: i1$2.LoggerService, optional: true }], target: i0.ɵɵFactoryTarget.Component });
12285
- static ɵcmp = i0.ɵɵngDeclareComponent({ minVersion: "17.0.0", version: "20.3.17", 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", submitUrl: "submitUrl", submitMethod: "submitMethod", responseSchemaUrl: "responseSchemaUrl", apiEndpointKey: "apiEndpointKey", apiUrlEntry: "apiUrlEntry", enableCustomization: "enableCustomization", formId: "formId", componentInstanceId: "componentInstanceId", layout: "layout", backConfig: "backConfig", hooks: "hooks", removeEmptyContainersOnSave: "removeEmptyContainersOnSave", reactiveValidation: "reactiveValidation", reactiveValidationDebounceMs: "reactiveValidationDebounceMs", notifyIfOutdated: "notifyIfOutdated", snoozeMs: "snoozeMs", autoOpenSettingsOnOutdated: "autoOpenSettingsOnOutdated", readonlyModeGlobal: "readonlyModeGlobal", disabledModeGlobal: "disabledModeGlobal", presentationModeGlobal: "presentationModeGlobal", visibleGlobal: "visibleGlobal", customEndpoints: "customEndpoints" }, outputs: { formSubmit: "formSubmit", formCancel: "formCancel", formReset: "formReset", configChange: "configChange", formReady: "formReady", valueChange: "valueChange", syncCompleted: "syncCompleted", initializationError: "initializationError", loadingStateChange: "loadingStateChange", enableCustomizationChange: "enableCustomizationChange", customAction: "customAction", actionConfirmation: "actionConfirmation", schemaStatusChange: "schemaStatusChange", fieldRenderError: "fieldRenderError" }, 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\"></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 <praxis-ai-assistant [adapter]=\"aiAdapter\"></praxis-ai-assistant>\n <button type=\"button\" mat-icon-button (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 <mat-icon [praxisIcon]=\"'settings'\"></mat-icon>\n </button>\n <button type=\"button\" mat-icon-button (click)=\"disconnect()\" matTooltip=\"Desconectar da fonte de dados\"\n [disabled]=\"isLoading\">\n <mat-icon [praxisIcon]=\"'link_off'\"></mat-icon>\n </button>\n</div>\n}\n\n<!-- Form Content -->\n@if (!resourcePath && (!config.sections || config.sections.length === 0)) {\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 <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 *ngIf=\"enableCustomization && selectedElement\" [selectedElement]=\"selectedElement\"\n [style.transform]=\"toolbarTransform\"></praxis-canvas-toolbar>\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 ></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 [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 let last = $last) {\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]=\"!last ? 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 >\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]=\"getSectionTitleGapBottom(section) ?? 20\" [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\" mat-icon-button (click)=\"openSectionEditor(section, 'title')\"\n aria-label=\"Editar t\u00EDtulo da se\u00E7\u00E3o\" matTooltip=\"Editar t\u00EDtulo\">\n <mat-icon>edit</mat-icon>\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\" mat-icon-button\n (click)=\"openSectionEditor(section, 'description')\" aria-label=\"Editar descri\u00E7\u00E3o da se\u00E7\u00E3o\"\n matTooltip=\"Editar descri\u00E7\u00E3o\">\n <mat-icon>edit</mat-icon>\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 mat-icon-button\n [color]=\"getSectionHeaderActionColor(action)\"\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 <mat-progress-spinner diameter=\"16\" mode=\"indeterminate\"></mat-progress-spinner>\n <span class=\"section-heading-action-sr-only\">{{ getSectionHeaderActionLoadingLabel(action) }}</span>\n } @else {\n <mat-icon [praxisIcon]=\"action.icon\"></mat-icon>\n }\n </button>\n }\n </div>\n }\n @if (isSectionCollapsible(section)) {\n <button type=\"button\" class=\"section-collapse-btn\" mat-icon-button\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 <mat-icon [praxisIcon]=\"isSectionCollapsed(section) ? 'expand_more' : 'expand_less'\"></mat-icon>\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)\"\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 <ng-container dynamicFieldLoader [fields]=\"getColumnFields(column)\" [formGroup]=\"form\"\n [enableExternalControlBinding]=\"true\"\n [readonlyMode]=\"readonlyModeGlobal === null ? null : readonlyModeGlobal\"\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 (renderError)=\"onFieldRenderError($event)\">\n </ng-container>\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 (last && 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 ></praxis-rich-content>\n </section>\n }\n @if (actionPlacement === 'insideLastSection' && last && !(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 [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 diameter=\"40\" color=\"primary\"></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 ></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 [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 ></praxis-rich-content>\n </section>\n }\n</form>\n@if (!enableCustomization && mode === 'view') {\n<div class=\"ai-floating-assistant\">\n <praxis-ai-assistant [adapter]=\"aiAdapter\"></praxis-ai-assistant>\n</div>\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}@media(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}}@media(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}}@media(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}}@media(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}.form-config-controls{position:sticky;top:10px;margin-left:auto;margin-bottom:10px;display:flex;align-items:center;gap:.35rem;z-index:60;background:color-mix(in srgb,var(--md-sys-color-surface) 92%,transparent);padding:6px;border:1px solid color-mix(in srgb,var(--md-sys-color-outline-variant) 82%,transparent);border-radius:999px;-webkit-backdrop-filter:blur(12px);backdrop-filter:blur(12px);box-shadow:0 10px 22px #0f172a14;min-width:0;justify-content:flex-end;pointer-events:none;opacity:.88;transition:opacity .16s ease,box-shadow .16s ease,border-color .16s ease,transform .16s ease}.form-config-controls>*{pointer-events:auto}.praxis-dynamic-form:hover .form-config-controls,.praxis-dynamic-form:focus-within .form-config-controls{opacity:1;border-color:color-mix(in srgb,var(--md-sys-color-primary) 26%,var(--md-sys-color-outline-variant) 74%);box-shadow:0 14px 28px #0f172a1f;transform:translateY(-1px)}.form-config-controls .mat-icon-button{--mdc-icon-button-state-layer-size: 34px;width:34px;height:34px;color:var(--md-sys-color-on-surface-variant);background:color-mix(in srgb,var(--md-sys-color-surface-container-low) 82%,transparent);border:1px solid transparent}.form-config-controls .mat-icon-button:hover{color:var(--md-sys-color-primary);background:var(--md-sys-color-primary-container);border-color:color-mix(in srgb,var(--md-sys-color-primary) 20%,transparent)}.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 praxis-ai-assistant{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;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(--md-sys-color-surface-container-low);--pfx-editorial-form-border: var( --pfx-form-stroke, var(--md-sys-color-outline-variant) );--pfx-editorial-form-text: var(--md-sys-color-on-surface);--pfx-editorial-form-text-muted: 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(--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;--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.editorial-visual-context{font-family:var(--editorial-body-font-family, inherit);font-size:var(--editorial-body-size, 1rem);color:var(--editorial-text-primary, var(--md-sys-color-on-surface));--pfx-editorial-form-surface: var( --editorial-surface-primary, var(--pfx-form-section-surface, var(--md-sys-color-surface-container)) );--pfx-editorial-form-surface-muted: var( --editorial-surface-secondary, var(--md-sys-color-surface-container-low) );--pfx-editorial-form-border: var( --editorial-border-color, var(--pfx-form-stroke, var(--md-sys-color-outline-variant)) );--pfx-editorial-form-text: var( --editorial-text-primary, var(--md-sys-color-on-surface) );--pfx-editorial-form-text-muted: var( --editorial-text-secondary, var(--md-sys-color-on-surface-variant) );--pfx-editorial-form-accent: var( --editorial-cta-primary, var(--editorial-accent, var(--md-sys-color-primary)) );--pfx-editorial-form-accent-text: var( --editorial-cta-primary-text, var(--editorial-accent-contrast, var(--md-sys-color-on-primary)) );--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( --pfx-editorial-form-text, var(--md-sys-color-on-surface) );--md-sys-color-on-surface-variant: var( --pfx-editorial-form-text-muted, var(--md-sys-color-on-surface-variant) );--md-sys-color-primary: var( --pfx-editorial-form-accent, var(--md-sys-color-primary) );--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, var(--md-sys-color-on-surface-rgb) );--mat-sys-on-surface: var( --pfx-editorial-form-text, var(--mat-sys-on-surface) );--mat-sys-on-surface-variant: var( --pfx-editorial-form-text-muted, var(--mat-sys-on-surface-variant) );--mat-sys-on-surface-rgb: var( --editorial-text-primary-rgb, var(--mat-sys-on-surface-rgb, var(--md-sys-color-on-surface-rgb)) );color:var(--pfx-editorial-form-text);color-scheme:light}.praxis-dynamic-form.presentation-mode .form-row,.praxis-dynamic-form.readonly-mode .form-row{gap:.5rem;margin-bottom:.5rem}.praxis-dynamic-form.presentation-mode .form-section,.praxis-dynamic-form.readonly-mode .form-section{padding:.75rem .875rem}.praxis-dynamic-form.pres-compact .form-row{gap:.35rem;margin-bottom:.35rem}.praxis-dynamic-form.pres-compact .form-section{padding:.5rem .75rem}.praxis-dynamic-form.pres-label-left .praxis-presentation{display:grid;grid-template-columns:var(--pfx-presentation-label-w, 220px) 1fr;align-items:baseline;column-gap:10px}.praxis-dynamic-form.pres-label-left .praxis-presentation__label{text-align:right;margin-bottom:0}.form-section{border:1px solid var(--pfx-form-section-divider);border-radius:var(--pfx-editorial-form-radius);padding:var(--pfx-form-section-padding);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;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] .form-actions{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{display:flex;align-items:flex-start;gap:12px;margin-bottom:18px;padding-bottom:18px;border-bottom:1px solid var(--pfx-form-section-divider)}.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 .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:16px;border-bottom:1px solid var(--pfx-form-section-divider)}.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>praxis-form-actions[data-actions-placement=afterSections] .form-actions{margin-top:18px;padding-top:0}.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;--mdc-icon-button-size: 28px;--mdc-icon-button-icon-size: 16px}.inline-edit-btn mat-icon{font-size:16px;width:16px;height:16px}.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);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=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;align-content:start;gap:var(--pfx-field-gap, 10px);flex:1;min-width:0;transition:all .2s ease;border-radius:4px;position:relative}.form-row.grid-12{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){.form-row{flex-direction:column;gap:.5rem}.form-section{padding:1rem}.section-heading{gap:10px;margin-bottom:16px;padding-bottom:14px}}.section-title{display:flex;align-items:center;gap:8px}.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$1.NgClass, selector: "[ngClass]", inputs: ["class", "ngClass"] }, { kind: "directive", type: i1$1.NgIf, selector: "[ngIf]", inputs: ["ngIf", "ngIfThen", "ngIfElse"] }, { kind: "directive", type: i1$1.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],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"] }, { kind: "ngmodule", type: MatIconModule }, { kind: "component", type: i5.MatIcon, selector: "mat-icon", inputs: ["color", "inline", "svgIcon", "fontSet", "fontIcon"], exportAs: ["matIcon"] }, { kind: "ngmodule", type: MatButtonModule }, { kind: "component", type: i4.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: i4.MatIconButton, selector: "button[mat-icon-button], a[mat-icon-button], button[matIconButton], a[matIconButton]", exportAs: ["matButton", "matAnchor"] }, { kind: "component", type: i4.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: i9.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: "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", "formId", "actionOverrides"], outputs: ["action"] }, { kind: "component", type: EmptyStateCardComponent, selector: "praxis-empty-state-card", inputs: ["icon", "title", "description", "primaryAction", "secondaryActions", "inline", "tone"] }, { kind: "component", type: PraxisAiAssistantComponent, selector: "praxis-ai-assistant", inputs: ["adapter", "riskPolicy", "allowManualPatchEdit"] }, { kind: "component", type: PraxisRichContent, selector: "praxis-rich-content", inputs: ["document", "nodes", "context", "hostCapabilities", "layout", "rootClassName"] }] });
12658
+ static ɵcmp = i0.ɵɵngDeclareComponent({ minVersion: "17.0.0", version: "20.3.17", 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", submitUrl: "submitUrl", submitMethod: "submitMethod", responseSchemaUrl: "responseSchemaUrl", apiEndpointKey: "apiEndpointKey", apiUrlEntry: "apiUrlEntry", enableCustomization: "enableCustomization", formId: "formId", componentInstanceId: "componentInstanceId", layout: "layout", backConfig: "backConfig", hooks: "hooks", removeEmptyContainersOnSave: "removeEmptyContainersOnSave", reactiveValidation: "reactiveValidation", reactiveValidationDebounceMs: "reactiveValidationDebounceMs", notifyIfOutdated: "notifyIfOutdated", snoozeMs: "snoozeMs", autoOpenSettingsOnOutdated: "autoOpenSettingsOnOutdated", readonlyModeGlobal: "readonlyModeGlobal", disabledModeGlobal: "disabledModeGlobal", presentationModeGlobal: "presentationModeGlobal", visibleGlobal: "visibleGlobal", customEndpoints: "customEndpoints" }, outputs: { formSubmit: "formSubmit", formCancel: "formCancel", formReset: "formReset", configChange: "configChange", formReady: "formReady", valueChange: "valueChange", syncCompleted: "syncCompleted", initializationError: "initializationError", loadingStateChange: "loadingStateChange", enableCustomizationChange: "enableCustomizationChange", customAction: "customAction", actionConfirmation: "actionConfirmation", schemaStatusChange: "schemaStatusChange", fieldRenderError: "fieldRenderError" }, 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\"></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 <praxis-ai-assistant [adapter]=\"aiAdapter\"></praxis-ai-assistant>\n <button type=\"button\" mat-icon-button (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 <mat-icon [praxisIcon]=\"'settings'\"></mat-icon>\n </button>\n <button type=\"button\" mat-icon-button (click)=\"disconnect()\" matTooltip=\"Desconectar da fonte de dados\"\n [disabled]=\"isLoading\">\n <mat-icon [praxisIcon]=\"'link_off'\"></mat-icon>\n </button>\n</div>\n}\n\n<!-- Form Content -->\n@if (!resourcePath && (!config.sections || config.sections.length === 0)) {\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 <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 *ngIf=\"enableCustomization && selectedElement\" [selectedElement]=\"selectedElement\"\n [style.transform]=\"toolbarTransform\"></praxis-canvas-toolbar>\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 ></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 [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 let last = $last) {\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]=\"!last ? 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 >\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]=\"getSectionTitleGapBottom(section) ?? 20\" [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\" mat-icon-button (click)=\"openSectionEditor(section, 'title')\"\n aria-label=\"Editar t\u00EDtulo da se\u00E7\u00E3o\" matTooltip=\"Editar t\u00EDtulo\">\n <mat-icon>edit</mat-icon>\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\" mat-icon-button\n (click)=\"openSectionEditor(section, 'description')\" aria-label=\"Editar descri\u00E7\u00E3o da se\u00E7\u00E3o\"\n matTooltip=\"Editar descri\u00E7\u00E3o\">\n <mat-icon>edit</mat-icon>\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 mat-icon-button\n [color]=\"getSectionHeaderActionColor(action)\"\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 <mat-progress-spinner diameter=\"16\" mode=\"indeterminate\"></mat-progress-spinner>\n <span class=\"section-heading-action-sr-only\">{{ getSectionHeaderActionLoadingLabel(action) }}</span>\n } @else {\n <mat-icon [praxisIcon]=\"action.icon\"></mat-icon>\n }\n </button>\n }\n </div>\n }\n @if (isSectionCollapsible(section)) {\n <button type=\"button\" class=\"section-collapse-btn\" mat-icon-button\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 <mat-icon [praxisIcon]=\"isSectionCollapsed(section) ? 'expand_more' : 'expand_less'\"></mat-icon>\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)\"\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]=\"renderItem.fields\" [formGroup]=\"form\"\n [enableExternalControlBinding]=\"true\"\n [readonlyMode]=\"readonlyModeGlobal === null ? null : readonlyModeGlobal\"\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 (renderError)=\"onFieldRenderError($event)\">\n </ng-container>\n } @else {\n <praxis-rich-content\n class=\"form-layout-rich-content\"\n [document]=\"renderItem.document\"\n [layout]=\"renderItem.layout\"\n [rootClassName]=\"renderItem.rootClassName || ''\"\n [context]=\"getEditorialRichContentContext()\"\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 (last && 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 ></praxis-rich-content>\n </section>\n }\n @if (actionPlacement === 'insideLastSection' && last && !(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 [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 diameter=\"40\" color=\"primary\"></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 ></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 [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 ></praxis-rich-content>\n </section>\n }\n</form>\n@if (!enableCustomization && mode === 'view') {\n<div class=\"ai-floating-assistant\">\n <praxis-ai-assistant [adapter]=\"aiAdapter\"></praxis-ai-assistant>\n</div>\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}@media(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}}@media(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}}@media(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}}@media(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}.form-config-controls{position:sticky;top:10px;margin-left:auto;margin-bottom:10px;display:flex;align-items:center;gap:.35rem;z-index:60;background:color-mix(in srgb,var(--md-sys-color-surface) 92%,transparent);padding:6px;border:1px solid color-mix(in srgb,var(--md-sys-color-outline-variant) 82%,transparent);border-radius:999px;-webkit-backdrop-filter:blur(12px);backdrop-filter:blur(12px);box-shadow:0 10px 22px #0f172a14;min-width:0;justify-content:flex-end;pointer-events:none;opacity:.88;transition:opacity .16s ease,box-shadow .16s ease,border-color .16s ease,transform .16s ease}.form-config-controls>*{pointer-events:auto}.praxis-dynamic-form:hover .form-config-controls,.praxis-dynamic-form:focus-within .form-config-controls{opacity:1;border-color:color-mix(in srgb,var(--md-sys-color-primary) 26%,var(--md-sys-color-outline-variant) 74%);box-shadow:0 14px 28px #0f172a1f;transform:translateY(-1px)}.form-config-controls .mat-icon-button{--mdc-icon-button-state-layer-size: 34px;width:34px;height:34px;color:var(--md-sys-color-on-surface-variant);background:color-mix(in srgb,var(--md-sys-color-surface-container-low) 82%,transparent);border:1px solid transparent}.form-config-controls .mat-icon-button:hover{color:var(--md-sys-color-primary);background:var(--md-sys-color-primary-container);border-color:color-mix(in srgb,var(--md-sys-color-primary) 20%,transparent)}.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 praxis-ai-assistant{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;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(--md-sys-color-surface-container-low);--pfx-editorial-form-border: var( --pfx-form-stroke, var(--md-sys-color-outline-variant) );--pfx-editorial-form-text: var(--md-sys-color-on-surface);--pfx-editorial-form-text-muted: 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(--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;--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.editorial-visual-context{font-family:var(--editorial-body-font-family, inherit);font-size:var(--editorial-body-size, 1rem);color:var(--editorial-text-primary, var(--md-sys-color-on-surface));--pfx-editorial-form-surface: var( --editorial-surface-primary, var(--pfx-form-section-surface, var(--md-sys-color-surface-container)) );--pfx-editorial-form-surface-muted: var( --editorial-surface-secondary, var(--md-sys-color-surface-container-low) );--pfx-editorial-form-border: var( --editorial-border-color, var(--pfx-form-stroke, var(--md-sys-color-outline-variant)) );--pfx-editorial-form-text: var( --editorial-text-primary, var(--md-sys-color-on-surface) );--pfx-editorial-form-text-muted: var( --editorial-text-secondary, var(--md-sys-color-on-surface-variant) );--pfx-editorial-form-accent: var( --editorial-cta-primary, var(--editorial-accent, var(--md-sys-color-primary)) );--pfx-editorial-form-accent-text: var( --editorial-cta-primary-text, var(--editorial-accent-contrast, var(--md-sys-color-on-primary)) );--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( --pfx-editorial-form-text, var(--md-sys-color-on-surface) );--md-sys-color-on-surface-variant: var( --pfx-editorial-form-text-muted, var(--md-sys-color-on-surface-variant) );--md-sys-color-primary: var( --pfx-editorial-form-accent, var(--md-sys-color-primary) );--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, var(--md-sys-color-on-surface-rgb) );--mat-sys-on-surface: var( --pfx-editorial-form-text, var(--mat-sys-on-surface) );--mat-sys-on-surface-variant: var( --pfx-editorial-form-text-muted, var(--mat-sys-on-surface-variant) );--mat-sys-on-surface-rgb: var( --editorial-text-primary-rgb, var(--mat-sys-on-surface-rgb, var(--md-sys-color-on-surface-rgb)) );color:var(--pfx-editorial-form-text);color-scheme:light}.praxis-dynamic-form.presentation-mode .form-row,.praxis-dynamic-form.readonly-mode .form-row{gap:.5rem;margin-bottom:.5rem}.praxis-dynamic-form.presentation-mode .form-section,.praxis-dynamic-form.readonly-mode .form-section{padding:.75rem .875rem}.praxis-dynamic-form.pres-compact .form-row{gap:.35rem;margin-bottom:.35rem}.praxis-dynamic-form.pres-compact .form-section{padding:.5rem .75rem}.praxis-dynamic-form.pres-label-left .praxis-presentation{display:grid;grid-template-columns:var(--pfx-presentation-label-w, 220px) 1fr;align-items:baseline;column-gap:10px}.praxis-dynamic-form.pres-label-left .praxis-presentation__label{text-align:right;margin-bottom:0}.form-section{border:1px solid var(--pfx-form-section-divider);border-radius:var(--pfx-editorial-form-radius);padding:var(--pfx-form-section-padding);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;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] .form-actions{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{display:flex;align-items:flex-start;gap:12px;margin-bottom:18px;padding-bottom:18px;border-bottom:1px solid var(--pfx-form-section-divider)}.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 .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:16px;border-bottom:1px solid var(--pfx-form-section-divider)}.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>praxis-form-actions[data-actions-placement=afterSections] .form-actions{margin-top:18px;padding-top:0}.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;--mdc-icon-button-size: 28px;--mdc-icon-button-icon-size: 16px}.inline-edit-btn mat-icon{font-size:16px;width:16px;height:16px}.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);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=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;align-content:start;gap:var(--pfx-field-gap, 10px);flex:1;min-width:0;transition:all .2s ease;border-radius:4px;position:relative}.form-row.grid-12{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){.form-row{flex-direction:column;gap:.5rem}.form-section{padding:1rem}.section-heading{gap:10px;margin-bottom:16px;padding-bottom:14px}}.section-title{display:flex;align-items:center;gap:8px}.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$1.NgClass, selector: "[ngClass]", inputs: ["class", "ngClass"] }, { kind: "directive", type: i1$1.NgIf, selector: "[ngIf]", inputs: ["ngIf", "ngIfThen", "ngIfElse"] }, { kind: "directive", type: i1$1.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],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"] }, { kind: "ngmodule", type: MatIconModule }, { kind: "component", type: i5.MatIcon, selector: "mat-icon", inputs: ["color", "inline", "svgIcon", "fontSet", "fontIcon"], exportAs: ["matIcon"] }, { kind: "ngmodule", type: MatButtonModule }, { kind: "component", type: i4.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: i4.MatIconButton, selector: "button[mat-icon-button], a[mat-icon-button], button[matIconButton], a[matIconButton]", exportAs: ["matButton", "matAnchor"] }, { kind: "component", type: i4.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: i9.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: "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", "formId", "actionOverrides"], outputs: ["action"] }, { kind: "component", type: EmptyStateCardComponent, selector: "praxis-empty-state-card", inputs: ["icon", "title", "description", "primaryAction", "secondaryActions", "inline", "tone"] }, { kind: "component", type: PraxisAiAssistantComponent, selector: "praxis-ai-assistant", inputs: ["adapter", "riskPolicy", "allowManualPatchEdit"] }, { kind: "component", type: PraxisRichContent, selector: "praxis-rich-content", inputs: ["document", "nodes", "context", "hostCapabilities", "layout", "rootClassName"] }] });
12286
12659
  }
12287
12660
  i0.ɵɵngDeclareClassMetadata({ minVersion: "12.0.0", version: "20.3.17", ngImport: i0, type: PraxisDynamicForm, decorators: [{
12288
12661
  type: Component,
@@ -12303,7 +12676,7 @@ i0.ɵɵngDeclareClassMetadata({ minVersion: "12.0.0", version: "20.3.17", ngImpo
12303
12676
  EmptyStateCardComponent,
12304
12677
  PraxisAiAssistantComponent,
12305
12678
  PraxisRichContent,
12306
- ], 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\"></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 <praxis-ai-assistant [adapter]=\"aiAdapter\"></praxis-ai-assistant>\n <button type=\"button\" mat-icon-button (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 <mat-icon [praxisIcon]=\"'settings'\"></mat-icon>\n </button>\n <button type=\"button\" mat-icon-button (click)=\"disconnect()\" matTooltip=\"Desconectar da fonte de dados\"\n [disabled]=\"isLoading\">\n <mat-icon [praxisIcon]=\"'link_off'\"></mat-icon>\n </button>\n</div>\n}\n\n<!-- Form Content -->\n@if (!resourcePath && (!config.sections || config.sections.length === 0)) {\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 <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 *ngIf=\"enableCustomization && selectedElement\" [selectedElement]=\"selectedElement\"\n [style.transform]=\"toolbarTransform\"></praxis-canvas-toolbar>\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 ></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 [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 let last = $last) {\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]=\"!last ? 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 >\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]=\"getSectionTitleGapBottom(section) ?? 20\" [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\" mat-icon-button (click)=\"openSectionEditor(section, 'title')\"\n aria-label=\"Editar t\u00EDtulo da se\u00E7\u00E3o\" matTooltip=\"Editar t\u00EDtulo\">\n <mat-icon>edit</mat-icon>\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\" mat-icon-button\n (click)=\"openSectionEditor(section, 'description')\" aria-label=\"Editar descri\u00E7\u00E3o da se\u00E7\u00E3o\"\n matTooltip=\"Editar descri\u00E7\u00E3o\">\n <mat-icon>edit</mat-icon>\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 mat-icon-button\n [color]=\"getSectionHeaderActionColor(action)\"\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 <mat-progress-spinner diameter=\"16\" mode=\"indeterminate\"></mat-progress-spinner>\n <span class=\"section-heading-action-sr-only\">{{ getSectionHeaderActionLoadingLabel(action) }}</span>\n } @else {\n <mat-icon [praxisIcon]=\"action.icon\"></mat-icon>\n }\n </button>\n }\n </div>\n }\n @if (isSectionCollapsible(section)) {\n <button type=\"button\" class=\"section-collapse-btn\" mat-icon-button\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 <mat-icon [praxisIcon]=\"isSectionCollapsed(section) ? 'expand_more' : 'expand_less'\"></mat-icon>\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)\"\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 <ng-container dynamicFieldLoader [fields]=\"getColumnFields(column)\" [formGroup]=\"form\"\n [enableExternalControlBinding]=\"true\"\n [readonlyMode]=\"readonlyModeGlobal === null ? null : readonlyModeGlobal\"\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 (renderError)=\"onFieldRenderError($event)\">\n </ng-container>\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 (last && 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 ></praxis-rich-content>\n </section>\n }\n @if (actionPlacement === 'insideLastSection' && last && !(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 [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 diameter=\"40\" color=\"primary\"></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 ></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 [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 ></praxis-rich-content>\n </section>\n }\n</form>\n@if (!enableCustomization && mode === 'view') {\n<div class=\"ai-floating-assistant\">\n <praxis-ai-assistant [adapter]=\"aiAdapter\"></praxis-ai-assistant>\n</div>\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}@media(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}}@media(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}}@media(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}}@media(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}.form-config-controls{position:sticky;top:10px;margin-left:auto;margin-bottom:10px;display:flex;align-items:center;gap:.35rem;z-index:60;background:color-mix(in srgb,var(--md-sys-color-surface) 92%,transparent);padding:6px;border:1px solid color-mix(in srgb,var(--md-sys-color-outline-variant) 82%,transparent);border-radius:999px;-webkit-backdrop-filter:blur(12px);backdrop-filter:blur(12px);box-shadow:0 10px 22px #0f172a14;min-width:0;justify-content:flex-end;pointer-events:none;opacity:.88;transition:opacity .16s ease,box-shadow .16s ease,border-color .16s ease,transform .16s ease}.form-config-controls>*{pointer-events:auto}.praxis-dynamic-form:hover .form-config-controls,.praxis-dynamic-form:focus-within .form-config-controls{opacity:1;border-color:color-mix(in srgb,var(--md-sys-color-primary) 26%,var(--md-sys-color-outline-variant) 74%);box-shadow:0 14px 28px #0f172a1f;transform:translateY(-1px)}.form-config-controls .mat-icon-button{--mdc-icon-button-state-layer-size: 34px;width:34px;height:34px;color:var(--md-sys-color-on-surface-variant);background:color-mix(in srgb,var(--md-sys-color-surface-container-low) 82%,transparent);border:1px solid transparent}.form-config-controls .mat-icon-button:hover{color:var(--md-sys-color-primary);background:var(--md-sys-color-primary-container);border-color:color-mix(in srgb,var(--md-sys-color-primary) 20%,transparent)}.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 praxis-ai-assistant{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;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(--md-sys-color-surface-container-low);--pfx-editorial-form-border: var( --pfx-form-stroke, var(--md-sys-color-outline-variant) );--pfx-editorial-form-text: var(--md-sys-color-on-surface);--pfx-editorial-form-text-muted: 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(--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;--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.editorial-visual-context{font-family:var(--editorial-body-font-family, inherit);font-size:var(--editorial-body-size, 1rem);color:var(--editorial-text-primary, var(--md-sys-color-on-surface));--pfx-editorial-form-surface: var( --editorial-surface-primary, var(--pfx-form-section-surface, var(--md-sys-color-surface-container)) );--pfx-editorial-form-surface-muted: var( --editorial-surface-secondary, var(--md-sys-color-surface-container-low) );--pfx-editorial-form-border: var( --editorial-border-color, var(--pfx-form-stroke, var(--md-sys-color-outline-variant)) );--pfx-editorial-form-text: var( --editorial-text-primary, var(--md-sys-color-on-surface) );--pfx-editorial-form-text-muted: var( --editorial-text-secondary, var(--md-sys-color-on-surface-variant) );--pfx-editorial-form-accent: var( --editorial-cta-primary, var(--editorial-accent, var(--md-sys-color-primary)) );--pfx-editorial-form-accent-text: var( --editorial-cta-primary-text, var(--editorial-accent-contrast, var(--md-sys-color-on-primary)) );--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( --pfx-editorial-form-text, var(--md-sys-color-on-surface) );--md-sys-color-on-surface-variant: var( --pfx-editorial-form-text-muted, var(--md-sys-color-on-surface-variant) );--md-sys-color-primary: var( --pfx-editorial-form-accent, var(--md-sys-color-primary) );--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, var(--md-sys-color-on-surface-rgb) );--mat-sys-on-surface: var( --pfx-editorial-form-text, var(--mat-sys-on-surface) );--mat-sys-on-surface-variant: var( --pfx-editorial-form-text-muted, var(--mat-sys-on-surface-variant) );--mat-sys-on-surface-rgb: var( --editorial-text-primary-rgb, var(--mat-sys-on-surface-rgb, var(--md-sys-color-on-surface-rgb)) );color:var(--pfx-editorial-form-text);color-scheme:light}.praxis-dynamic-form.presentation-mode .form-row,.praxis-dynamic-form.readonly-mode .form-row{gap:.5rem;margin-bottom:.5rem}.praxis-dynamic-form.presentation-mode .form-section,.praxis-dynamic-form.readonly-mode .form-section{padding:.75rem .875rem}.praxis-dynamic-form.pres-compact .form-row{gap:.35rem;margin-bottom:.35rem}.praxis-dynamic-form.pres-compact .form-section{padding:.5rem .75rem}.praxis-dynamic-form.pres-label-left .praxis-presentation{display:grid;grid-template-columns:var(--pfx-presentation-label-w, 220px) 1fr;align-items:baseline;column-gap:10px}.praxis-dynamic-form.pres-label-left .praxis-presentation__label{text-align:right;margin-bottom:0}.form-section{border:1px solid var(--pfx-form-section-divider);border-radius:var(--pfx-editorial-form-radius);padding:var(--pfx-form-section-padding);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;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] .form-actions{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{display:flex;align-items:flex-start;gap:12px;margin-bottom:18px;padding-bottom:18px;border-bottom:1px solid var(--pfx-form-section-divider)}.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 .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:16px;border-bottom:1px solid var(--pfx-form-section-divider)}.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>praxis-form-actions[data-actions-placement=afterSections] .form-actions{margin-top:18px;padding-top:0}.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;--mdc-icon-button-size: 28px;--mdc-icon-button-icon-size: 16px}.inline-edit-btn mat-icon{font-size:16px;width:16px;height:16px}.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);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=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;align-content:start;gap:var(--pfx-field-gap, 10px);flex:1;min-width:0;transition:all .2s ease;border-radius:4px;position:relative}.form-row.grid-12{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){.form-row{flex-direction:column;gap:.5rem}.form-section{padding:1rem}.section-heading{gap:10px;margin-bottom:16px;padding-bottom:14px}}.section-title{display:flex;align-items:center;gap:8px}.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"] }]
12679
+ ], 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\"></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 <praxis-ai-assistant [adapter]=\"aiAdapter\"></praxis-ai-assistant>\n <button type=\"button\" mat-icon-button (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 <mat-icon [praxisIcon]=\"'settings'\"></mat-icon>\n </button>\n <button type=\"button\" mat-icon-button (click)=\"disconnect()\" matTooltip=\"Desconectar da fonte de dados\"\n [disabled]=\"isLoading\">\n <mat-icon [praxisIcon]=\"'link_off'\"></mat-icon>\n </button>\n</div>\n}\n\n<!-- Form Content -->\n@if (!resourcePath && (!config.sections || config.sections.length === 0)) {\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 <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 *ngIf=\"enableCustomization && selectedElement\" [selectedElement]=\"selectedElement\"\n [style.transform]=\"toolbarTransform\"></praxis-canvas-toolbar>\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 ></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 [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 let last = $last) {\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]=\"!last ? 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 >\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]=\"getSectionTitleGapBottom(section) ?? 20\" [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\" mat-icon-button (click)=\"openSectionEditor(section, 'title')\"\n aria-label=\"Editar t\u00EDtulo da se\u00E7\u00E3o\" matTooltip=\"Editar t\u00EDtulo\">\n <mat-icon>edit</mat-icon>\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\" mat-icon-button\n (click)=\"openSectionEditor(section, 'description')\" aria-label=\"Editar descri\u00E7\u00E3o da se\u00E7\u00E3o\"\n matTooltip=\"Editar descri\u00E7\u00E3o\">\n <mat-icon>edit</mat-icon>\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 mat-icon-button\n [color]=\"getSectionHeaderActionColor(action)\"\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 <mat-progress-spinner diameter=\"16\" mode=\"indeterminate\"></mat-progress-spinner>\n <span class=\"section-heading-action-sr-only\">{{ getSectionHeaderActionLoadingLabel(action) }}</span>\n } @else {\n <mat-icon [praxisIcon]=\"action.icon\"></mat-icon>\n }\n </button>\n }\n </div>\n }\n @if (isSectionCollapsible(section)) {\n <button type=\"button\" class=\"section-collapse-btn\" mat-icon-button\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 <mat-icon [praxisIcon]=\"isSectionCollapsed(section) ? 'expand_more' : 'expand_less'\"></mat-icon>\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)\"\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]=\"renderItem.fields\" [formGroup]=\"form\"\n [enableExternalControlBinding]=\"true\"\n [readonlyMode]=\"readonlyModeGlobal === null ? null : readonlyModeGlobal\"\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 (renderError)=\"onFieldRenderError($event)\">\n </ng-container>\n } @else {\n <praxis-rich-content\n class=\"form-layout-rich-content\"\n [document]=\"renderItem.document\"\n [layout]=\"renderItem.layout\"\n [rootClassName]=\"renderItem.rootClassName || ''\"\n [context]=\"getEditorialRichContentContext()\"\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 (last && 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 ></praxis-rich-content>\n </section>\n }\n @if (actionPlacement === 'insideLastSection' && last && !(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 [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 diameter=\"40\" color=\"primary\"></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 ></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 [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 ></praxis-rich-content>\n </section>\n }\n</form>\n@if (!enableCustomization && mode === 'view') {\n<div class=\"ai-floating-assistant\">\n <praxis-ai-assistant [adapter]=\"aiAdapter\"></praxis-ai-assistant>\n</div>\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}@media(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}}@media(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}}@media(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}}@media(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}.form-config-controls{position:sticky;top:10px;margin-left:auto;margin-bottom:10px;display:flex;align-items:center;gap:.35rem;z-index:60;background:color-mix(in srgb,var(--md-sys-color-surface) 92%,transparent);padding:6px;border:1px solid color-mix(in srgb,var(--md-sys-color-outline-variant) 82%,transparent);border-radius:999px;-webkit-backdrop-filter:blur(12px);backdrop-filter:blur(12px);box-shadow:0 10px 22px #0f172a14;min-width:0;justify-content:flex-end;pointer-events:none;opacity:.88;transition:opacity .16s ease,box-shadow .16s ease,border-color .16s ease,transform .16s ease}.form-config-controls>*{pointer-events:auto}.praxis-dynamic-form:hover .form-config-controls,.praxis-dynamic-form:focus-within .form-config-controls{opacity:1;border-color:color-mix(in srgb,var(--md-sys-color-primary) 26%,var(--md-sys-color-outline-variant) 74%);box-shadow:0 14px 28px #0f172a1f;transform:translateY(-1px)}.form-config-controls .mat-icon-button{--mdc-icon-button-state-layer-size: 34px;width:34px;height:34px;color:var(--md-sys-color-on-surface-variant);background:color-mix(in srgb,var(--md-sys-color-surface-container-low) 82%,transparent);border:1px solid transparent}.form-config-controls .mat-icon-button:hover{color:var(--md-sys-color-primary);background:var(--md-sys-color-primary-container);border-color:color-mix(in srgb,var(--md-sys-color-primary) 20%,transparent)}.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 praxis-ai-assistant{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;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(--md-sys-color-surface-container-low);--pfx-editorial-form-border: var( --pfx-form-stroke, var(--md-sys-color-outline-variant) );--pfx-editorial-form-text: var(--md-sys-color-on-surface);--pfx-editorial-form-text-muted: 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(--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;--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.editorial-visual-context{font-family:var(--editorial-body-font-family, inherit);font-size:var(--editorial-body-size, 1rem);color:var(--editorial-text-primary, var(--md-sys-color-on-surface));--pfx-editorial-form-surface: var( --editorial-surface-primary, var(--pfx-form-section-surface, var(--md-sys-color-surface-container)) );--pfx-editorial-form-surface-muted: var( --editorial-surface-secondary, var(--md-sys-color-surface-container-low) );--pfx-editorial-form-border: var( --editorial-border-color, var(--pfx-form-stroke, var(--md-sys-color-outline-variant)) );--pfx-editorial-form-text: var( --editorial-text-primary, var(--md-sys-color-on-surface) );--pfx-editorial-form-text-muted: var( --editorial-text-secondary, var(--md-sys-color-on-surface-variant) );--pfx-editorial-form-accent: var( --editorial-cta-primary, var(--editorial-accent, var(--md-sys-color-primary)) );--pfx-editorial-form-accent-text: var( --editorial-cta-primary-text, var(--editorial-accent-contrast, var(--md-sys-color-on-primary)) );--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( --pfx-editorial-form-text, var(--md-sys-color-on-surface) );--md-sys-color-on-surface-variant: var( --pfx-editorial-form-text-muted, var(--md-sys-color-on-surface-variant) );--md-sys-color-primary: var( --pfx-editorial-form-accent, var(--md-sys-color-primary) );--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, var(--md-sys-color-on-surface-rgb) );--mat-sys-on-surface: var( --pfx-editorial-form-text, var(--mat-sys-on-surface) );--mat-sys-on-surface-variant: var( --pfx-editorial-form-text-muted, var(--mat-sys-on-surface-variant) );--mat-sys-on-surface-rgb: var( --editorial-text-primary-rgb, var(--mat-sys-on-surface-rgb, var(--md-sys-color-on-surface-rgb)) );color:var(--pfx-editorial-form-text);color-scheme:light}.praxis-dynamic-form.presentation-mode .form-row,.praxis-dynamic-form.readonly-mode .form-row{gap:.5rem;margin-bottom:.5rem}.praxis-dynamic-form.presentation-mode .form-section,.praxis-dynamic-form.readonly-mode .form-section{padding:.75rem .875rem}.praxis-dynamic-form.pres-compact .form-row{gap:.35rem;margin-bottom:.35rem}.praxis-dynamic-form.pres-compact .form-section{padding:.5rem .75rem}.praxis-dynamic-form.pres-label-left .praxis-presentation{display:grid;grid-template-columns:var(--pfx-presentation-label-w, 220px) 1fr;align-items:baseline;column-gap:10px}.praxis-dynamic-form.pres-label-left .praxis-presentation__label{text-align:right;margin-bottom:0}.form-section{border:1px solid var(--pfx-form-section-divider);border-radius:var(--pfx-editorial-form-radius);padding:var(--pfx-form-section-padding);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;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] .form-actions{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{display:flex;align-items:flex-start;gap:12px;margin-bottom:18px;padding-bottom:18px;border-bottom:1px solid var(--pfx-form-section-divider)}.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 .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:16px;border-bottom:1px solid var(--pfx-form-section-divider)}.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>praxis-form-actions[data-actions-placement=afterSections] .form-actions{margin-top:18px;padding-top:0}.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;--mdc-icon-button-size: 28px;--mdc-icon-button-icon-size: 16px}.inline-edit-btn mat-icon{font-size:16px;width:16px;height:16px}.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);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=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;align-content:start;gap:var(--pfx-field-gap, 10px);flex:1;min-width:0;transition:all .2s ease;border-radius:4px;position:relative}.form-row.grid-12{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){.form-row{flex-direction:column;gap:.5rem}.form-section{padding:1rem}.section-heading{gap:10px;margin-bottom:16px;padding-bottom:14px}}.section-title{display:flex;align-items:center;gap:8px}.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"] }]
12307
12680
  }], ctorParameters: () => [{ type: i1$2.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: [{
12308
12681
  type: Inject,
12309
12682
  args: [ASYNC_CONFIG_STORAGE]
@@ -13110,9 +13483,123 @@ i0.ɵɵngDeclareClassMetadata({ minVersion: "12.0.0", version: "20.3.17", ngImpo
13110
13483
  type: Input
13111
13484
  }] } });
13112
13485
 
13486
+ const LAYOUT_EDITOR_I18N_NAMESPACE = 'praxisDynamicFormLayoutEditor';
13487
+ const LAYOUT_EDITOR_DEFAULT_COPY = {
13488
+ 'apiFields.heading': 'Campos da API',
13489
+ 'apiFields.hint': 'Campos do fieldMetadata ainda não alocados no layout.',
13490
+ 'apiFields.addAction': 'Adicionar campo da API',
13491
+ 'apiFields.empty': 'Nenhum campo da API disponível',
13492
+ 'apiFields.addTooltip': 'Adicionar campo existente da API nesta coluna',
13493
+ 'visualBlock.label': 'Bloco visual',
13494
+ 'visualBlock.addAction': 'Adicionar bloco visual',
13495
+ 'visualBlock.addTooltip': 'Adicionar texto ou bloco visual nesta coluna',
13496
+ 'visualBlock.editTitle': 'Editar bloco visual',
13497
+ 'visualBlock.editAction': 'Editar bloco visual',
13498
+ 'visualBlock.removeAction': 'Remover bloco visual',
13499
+ 'visualBlock.moveUp': 'Mover bloco visual para cima',
13500
+ 'visualBlock.moveDown': 'Mover bloco visual para baixo',
13501
+ 'visualBlock.movePreviousColumn': 'Mover bloco visual para a coluna anterior',
13502
+ 'visualBlock.moveNextColumn': 'Mover bloco visual para a próxima coluna',
13503
+ 'visualBlock.preset.text': 'Texto',
13504
+ 'visualBlock.preset.notice': 'Aviso',
13505
+ 'visualBlock.preset.divider': 'Separador',
13506
+ 'visualBlock.preset.infoCard': 'Card informativo',
13507
+ 'visualBlock.preset.text.default': 'Novo texto',
13508
+ 'visualBlock.preset.notice.default': 'Revise as informações antes de continuar.',
13509
+ 'visualBlock.preset.divider.default': 'Separador',
13510
+ 'visualBlock.preset.infoCard.title': 'Informação importante',
13511
+ 'visualBlock.preset.infoCard.body': 'Use este espaço para orientar o preenchimento.',
13512
+ };
13513
+ const LAYOUT_EDITOR_I18N_CONFIG = {
13514
+ namespaces: {
13515
+ [LAYOUT_EDITOR_I18N_NAMESPACE]: {
13516
+ 'pt-BR': LAYOUT_EDITOR_DEFAULT_COPY,
13517
+ 'en-US': {
13518
+ 'apiFields.heading': 'API fields',
13519
+ 'apiFields.hint': 'fieldMetadata fields not yet allocated in the layout.',
13520
+ 'apiFields.addAction': 'Add API field',
13521
+ 'apiFields.empty': 'No API field available',
13522
+ 'apiFields.addTooltip': 'Add an existing API field to this column',
13523
+ 'visualBlock.label': 'Visual block',
13524
+ 'visualBlock.addAction': 'Add visual block',
13525
+ 'visualBlock.addTooltip': 'Add text or a visual block to this column',
13526
+ 'visualBlock.editTitle': 'Edit visual block',
13527
+ 'visualBlock.editAction': 'Edit visual block',
13528
+ 'visualBlock.removeAction': 'Remove visual block',
13529
+ 'visualBlock.moveUp': 'Move visual block up',
13530
+ 'visualBlock.moveDown': 'Move visual block down',
13531
+ 'visualBlock.movePreviousColumn': 'Move visual block to the previous column',
13532
+ 'visualBlock.moveNextColumn': 'Move visual block to the next column',
13533
+ 'visualBlock.preset.text': 'Text',
13534
+ 'visualBlock.preset.notice': 'Notice',
13535
+ 'visualBlock.preset.divider': 'Divider',
13536
+ 'visualBlock.preset.infoCard': 'Info card',
13537
+ 'visualBlock.preset.text.default': 'New text',
13538
+ 'visualBlock.preset.notice.default': 'Review the information before continuing.',
13539
+ 'visualBlock.preset.divider.default': 'Divider',
13540
+ 'visualBlock.preset.infoCard.title': 'Important information',
13541
+ 'visualBlock.preset.infoCard.body': 'Use this space to guide completion.',
13542
+ },
13543
+ },
13544
+ },
13545
+ };
13546
+
13547
+ const VISUAL_BLOCK_PRESETS = [
13548
+ { id: 'text', labelKey: 'visualBlock.preset.text', icon: 'short_text' },
13549
+ { id: 'notice', labelKey: 'visualBlock.preset.notice', icon: 'error_outline' },
13550
+ { id: 'divider', labelKey: 'visualBlock.preset.divider', icon: 'horizontal_rule' },
13551
+ { id: 'infoCard', labelKey: 'visualBlock.preset.infoCard', icon: 'info' },
13552
+ ];
13553
+ function createVisualBlockItemFromPreset(presetId, id, copy) {
13554
+ return {
13555
+ kind: 'richContent',
13556
+ id,
13557
+ document: createVisualBlockDocument(presetId, copy),
13558
+ layout: 'block',
13559
+ };
13560
+ }
13561
+ function createVisualBlockDocument(presetId, copy) {
13562
+ return {
13563
+ kind: 'praxis.rich-content',
13564
+ version: '1.0.0',
13565
+ nodes: [createPresetNode(presetId, copy)],
13566
+ };
13567
+ }
13568
+ function createPresetNode(presetId, copy) {
13569
+ switch (presetId) {
13570
+ case 'notice':
13571
+ return {
13572
+ type: 'compose',
13573
+ direction: 'row',
13574
+ gap: 'sm',
13575
+ className: 'praxis-rich-content-notice',
13576
+ items: [
13577
+ { type: 'icon', icon: 'error_outline', ariaLabel: copy.notice },
13578
+ { type: 'text', text: copy.notice },
13579
+ ],
13580
+ };
13581
+ case 'divider':
13582
+ return {
13583
+ type: 'text',
13584
+ text: copy.divider,
13585
+ className: 'praxis-rich-content-divider',
13586
+ };
13587
+ case 'infoCard':
13588
+ return {
13589
+ type: 'card',
13590
+ title: copy.infoCardTitle,
13591
+ content: [{ type: 'text', text: copy.infoCardBody }],
13592
+ };
13593
+ case 'text':
13594
+ default:
13595
+ return { type: 'text', text: copy.text };
13596
+ }
13597
+ }
13598
+
13113
13599
  class RowConfiguratorComponent {
13114
13600
  row;
13115
13601
  fieldMetadata = [];
13602
+ availableFields = [];
13116
13603
  sectionIndex;
13117
13604
  rowIndex;
13118
13605
  isLastRow = false;
@@ -13125,9 +13612,17 @@ class RowConfiguratorComponent {
13125
13612
  remove = new EventEmitter();
13126
13613
  applyRowGapAll = new EventEmitter();
13127
13614
  fieldDrop = new EventEmitter();
13615
+ addVisualBlock = new EventEmitter();
13616
+ addApiField = new EventEmitter();
13617
+ editVisualBlock = new EventEmitter();
13618
+ moveVisualBlock = new EventEmitter();
13619
+ moveVisualBlockToColumn = new EventEmitter();
13620
+ removeVisualBlock = new EventEmitter();
13128
13621
  select = new EventEmitter();
13129
13622
  // Debounced dropzone highlight
13130
13623
  activeDropIndex = null;
13624
+ visualBlockPresets = VISUAL_BLOCK_PRESETS;
13625
+ i18n = inject(PraxisI18nService);
13131
13626
  hoverTimer = null;
13132
13627
  breakpoints = ['xs', 'sm', 'md', 'lg', 'xl'];
13133
13628
  previewBreakpoint = 'md';
@@ -13174,6 +13669,107 @@ class RowConfiguratorComponent {
13174
13669
  controlType: FieldControlType.INPUT,
13175
13670
  });
13176
13671
  }
13672
+ getColumnLayoutItems(column) {
13673
+ return normalizeFormLayoutItems(column);
13674
+ }
13675
+ hasColumnContent(column) {
13676
+ return this.getColumnLayoutItems(column).length > 0;
13677
+ }
13678
+ getVisualBlockLabel(item) {
13679
+ if (item.kind !== 'richContent')
13680
+ return '';
13681
+ return this.findRichContentLabel(item.document?.nodes) || this.t('visualBlock.label');
13682
+ }
13683
+ findRichContentLabel(nodes) {
13684
+ if (!Array.isArray(nodes))
13685
+ return null;
13686
+ for (const node of nodes) {
13687
+ const label = this.findRichNodeLabel(node);
13688
+ if (label)
13689
+ return label;
13690
+ }
13691
+ return null;
13692
+ }
13693
+ findRichNodeLabel(node) {
13694
+ if (!node || typeof node !== 'object')
13695
+ return null;
13696
+ const richNode = node;
13697
+ for (const value of [richNode.text, richNode.label, richNode.title, richNode.subtitle]) {
13698
+ if (typeof value === 'string' && value.trim())
13699
+ return value.trim();
13700
+ }
13701
+ for (const nested of [richNode.items, richNode.content, richNode.trailing]) {
13702
+ const label = this.findRichContentLabel(nested);
13703
+ if (label)
13704
+ return label;
13705
+ }
13706
+ return this.findRichNodeLabel(richNode.avatar) || this.findRichNodeLabel(richNode.meta);
13707
+ }
13708
+ t(key, params) {
13709
+ return this.i18n.t(key, params, LAYOUT_EDITOR_DEFAULT_COPY[key] ?? key, LAYOUT_EDITOR_I18N_NAMESPACE);
13710
+ }
13711
+ getFieldLabel(field) {
13712
+ return field.label || field.name;
13713
+ }
13714
+ selectVisualBlock(columnIndex, item, event) {
13715
+ event.stopPropagation();
13716
+ if (item.kind !== 'richContent')
13717
+ return;
13718
+ this.select.emit({
13719
+ type: 'visualBlock',
13720
+ sectionIndex: this.sectionIndex,
13721
+ rowIndex: this.rowIndex,
13722
+ columnIndex,
13723
+ itemId: item.id,
13724
+ });
13725
+ }
13726
+ openVisualBlockEditor(columnIndex, item, event) {
13727
+ this.selectVisualBlock(columnIndex, item, event);
13728
+ if (item.kind !== 'richContent')
13729
+ return;
13730
+ this.editVisualBlock.emit({
13731
+ rowIndex: this.rowIndex,
13732
+ columnIndex,
13733
+ itemId: item.id,
13734
+ });
13735
+ }
13736
+ moveVisualBlockItem(columnIndex, item, direction, event) {
13737
+ this.selectVisualBlock(columnIndex, item, event);
13738
+ if (item.kind !== 'richContent')
13739
+ return;
13740
+ this.moveVisualBlock.emit({
13741
+ rowIndex: this.rowIndex,
13742
+ columnIndex,
13743
+ itemId: item.id,
13744
+ direction,
13745
+ });
13746
+ }
13747
+ canMoveVisualBlockToColumn(columnIndex, direction) {
13748
+ const targetColumnIndex = columnIndex + direction;
13749
+ return targetColumnIndex >= 0 && targetColumnIndex < (this.row?.columns?.length ?? 0);
13750
+ }
13751
+ moveVisualBlockToAdjacentColumn(columnIndex, item, direction, event) {
13752
+ this.selectVisualBlock(columnIndex, item, event);
13753
+ if (item.kind !== 'richContent' || !this.canMoveVisualBlockToColumn(columnIndex, direction)) {
13754
+ return;
13755
+ }
13756
+ this.moveVisualBlockToColumn.emit({
13757
+ rowIndex: this.rowIndex,
13758
+ columnIndex,
13759
+ targetColumnIndex: columnIndex + direction,
13760
+ itemId: item.id,
13761
+ });
13762
+ }
13763
+ removeVisualBlockItem(columnIndex, item, event) {
13764
+ this.selectVisualBlock(columnIndex, item, event);
13765
+ if (item.kind !== 'richContent')
13766
+ return;
13767
+ this.removeVisualBlock.emit({
13768
+ rowIndex: this.rowIndex,
13769
+ columnIndex,
13770
+ itemId: item.id,
13771
+ });
13772
+ }
13177
13773
  drop(event) {
13178
13774
  this.fieldDrop.emit(event);
13179
13775
  }
@@ -13293,13 +13889,30 @@ class RowConfiguratorComponent {
13293
13889
  this.rowChange.emit(updated);
13294
13890
  }
13295
13891
  clearColumn(index) {
13296
- if (!confirm('Tem certeza que deseja remover todos os campos desta coluna?'))
13892
+ if (!confirm('Tem certeza que deseja remover todo o conteudo desta coluna?'))
13297
13893
  return;
13298
13894
  const updated = produce(this.row, (draft) => {
13299
13895
  draft.columns[index].fields = [];
13896
+ draft.columns[index].items = [];
13300
13897
  });
13301
13898
  this.rowChange.emit(updated);
13302
13899
  }
13900
+ addVisualBlockToColumn(index, presetId) {
13901
+ this.addVisualBlock.emit({
13902
+ rowIndex: this.rowIndex,
13903
+ columnIndex: index,
13904
+ presetId,
13905
+ });
13906
+ }
13907
+ addApiFieldToColumn(index, fieldName) {
13908
+ if (!fieldName)
13909
+ return;
13910
+ this.addApiField.emit({
13911
+ rowIndex: this.rowIndex,
13912
+ columnIndex: index,
13913
+ fieldName,
13914
+ });
13915
+ }
13303
13916
  addFieldToColumn(index) {
13304
13917
  if (!this.fieldMetadata || this.fieldMetadata.length === 0)
13305
13918
  return;
@@ -13502,7 +14115,7 @@ class RowConfiguratorComponent {
13502
14115
  return null;
13503
14116
  }
13504
14117
  static ɵfac = i0.ɵɵngDeclareFactory({ minVersion: "12.0.0", version: "20.3.17", ngImport: i0, type: RowConfiguratorComponent, deps: [], target: i0.ɵɵFactoryTarget.Component });
13505
- static ɵcmp = i0.ɵɵngDeclareComponent({ minVersion: "14.0.0", version: "20.3.17", type: RowConfiguratorComponent, isStandalone: true, selector: "praxis-row-configurator", inputs: { row: "row", fieldMetadata: "fieldMetadata", sectionIndex: "sectionIndex", rowIndex: "rowIndex", isLastRow: "isLastRow", selected: "selected", availableFieldsListId: "availableFieldsListId", connectedDropListIds: "connectedDropListIds", gapGlobal: "gapGlobal" }, outputs: { rowChange: "rowChange", remove: "remove", applyRowGapAll: "applyRowGapAll", fieldDrop: "fieldDrop", select: "select" }, usesOnChanges: true, ngImport: i0, template: "<div class=\"row-meta\" *ngIf=\"row\">\n <div class=\"bp-toggle\" role=\"group\" aria-label=\"Breakpoint de visualiza\u00E7\u00E3o\">\n <button\n *ngFor=\"let bp of breakpoints\"\n type=\"button\"\n mat-stroked-button\n class=\"bp-toggle__btn\"\n [class.active]=\"previewBreakpoint === bp\"\n (click)=\"previewBreakpoint = bp\"\n >\n {{ bp }}\n </button>\n </div>\n <div class=\"gap-controls\">\n <div class=\"gap-chip\" *ngIf=\"hasMultipleColumns()\" matTooltip=\"Gap entre colunas (px)\"\n aria-label=\"Gap entre colunas\">\n <span class=\"chip-title\">Colunas</span>\n <button mat-icon-button class=\"gap-chip__btn\" (click)=\"adjustRowGapDelta('gap', -2)\"\n aria-label=\"Reduzir gap de colunas\">\n <mat-icon>remove</mat-icon>\n </button>\n <input class=\"gap-chip__input\" type=\"number\" min=\"0\" [ngModel]=\"row.gap ?? gapGlobal\"\n (ngModelChange)=\"updateRowGap('gap', $event)\" aria-label=\"Valor do gap entre colunas\" />\n <span class=\"gap-chip__suffix\">px</span>\n <button mat-icon-button class=\"gap-chip__btn\" (click)=\"adjustRowGapDelta('gap', 2)\"\n aria-label=\"Aumentar gap de colunas\">\n <mat-icon>add</mat-icon>\n </button>\n </div>\n <div class=\"gap-chip\" matTooltip=\"Gap abaixo da linha (px)\" aria-label=\"Gap abaixo da linha\">\n <span class=\"chip-title\">Linha</span>\n <button mat-icon-button class=\"gap-chip__btn\" (click)=\"adjustRowGapDelta('rowGap', -2)\"\n aria-label=\"Reduzir espa\u00E7o entre campos da linha\" matTooltip=\"Reduz o espa\u00E7o entre campos desta linha\">\n <mat-icon>remove</mat-icon>\n </button>\n <input class=\"gap-chip__input\" type=\"number\" min=\"0\" [ngModel]=\"row.rowGap ?? 0\"\n (ngModelChange)=\"updateRowGap('rowGap', $event)\" aria-label=\"Espa\u00E7o entre campos desta linha\" />\n <span class=\"gap-chip__suffix\">px</span>\n <button mat-icon-button class=\"gap-chip__btn\" (click)=\"adjustRowGapDelta('rowGap', 2)\"\n aria-label=\"Aumentar espa\u00E7o entre campos da linha\" matTooltip=\"Aumenta o espa\u00E7o entre campos desta linha\">\n <mat-icon>add</mat-icon>\n </button>\n <button mat-icon-button class=\"gap-chip__btn\" [matMenuTriggerFor]=\"rowGapMenu\"\n matTooltip=\"Mais op\u00E7\u00F5es para aplicar este espa\u00E7o\" aria-label=\"Mais op\u00E7\u00F5es de aplica\u00E7\u00E3o\">\n <mat-icon>done_all</mat-icon>\n </button>\n <mat-menu #rowGapMenu=\"matMenu\">\n <button mat-menu-item (click)=\"applyRowGapToAll()\">\n <mat-icon>done_all</mat-icon>\n <span>Aplicar em todas as linhas da se\u00E7\u00E3o</span>\n </button>\n <button mat-menu-item (click)=\"clearRowGap()\">\n <mat-icon>undo</mat-icon>\n <span>Voltar ao padr\u00E3o</span>\n </button>\n </mat-menu>\n </div>\n <div class=\"gap-pill\" aria-label=\"Resumo de espa\u00E7amentos\">\n Campos: {{ (row.rowGap ?? 'padr\u00E3o') }}px \u00B7 Colunas: {{ (row.gap ?? gapGlobal) }}px\n </div>\n <div class=\"row-actions-meta\">\n <button mat-icon-button [matMenuTriggerFor]=\"rowMenu\" (click)=\"openRowMenu()\" matTooltip=\"Op\u00E7\u00F5es da linha\">\n <mat-icon>more_vert</mat-icon>\n </button>\n <mat-menu #rowMenu=\"matMenu\" (closed)=\"onMenuClosed()\">\n <ng-container *ngIf=\"menuContext?.type === 'column'; else rowMenuContent\">\n <button mat-menu-item (click)=\"toggleHidden(menuContext!.columnIndex!)\">\n <mat-icon>{{ getHiddenFor(row.columns[menuContext!.columnIndex!]) ? 'visibility' : 'visibility_off'\n }}</mat-icon>\n <span>{{ getHiddenFor(row.columns[menuContext!.columnIndex!]) ? 'Mostrar neste breakpoint' : 'Ocultar neste\n breakpoint' }}</span>\n </button>\n <button mat-menu-item (click)=\"removeColumn(menuContext!.columnIndex!)\">\n <mat-icon color=\"warn\">delete</mat-icon>\n <span>Remover coluna</span>\n </button>\n </ng-container>\n <ng-template #rowMenuContent>\n <div mat-menu-item disabled>Presets de colunas</div>\n <button mat-menu-item (click)=\"applyPreset([12])\"><mat-icon>view_column</mat-icon><span>1/1</span></button>\n <button mat-menu-item (click)=\"applyPreset([6,6])\"><mat-icon>view_column</mat-icon><span>1/2 \u2014\n 1/2</span></button>\n <button mat-menu-item (click)=\"applyPreset([4,8])\"><mat-icon>view_column</mat-icon><span>1/3 \u2014\n 2/3</span></button>\n <button mat-menu-item (click)=\"applyPreset([8,4])\"><mat-icon>view_column</mat-icon><span>2/3 \u2014\n 1/3</span></button>\n <button mat-menu-item (click)=\"applyPreset([4,4,4])\"><mat-icon>view_column</mat-icon><span>1/3 \u2014 1/3 \u2014\n 1/3</span></button>\n <button mat-menu-item (click)=\"applyPreset([3,3,3,3])\"><mat-icon>view_column</mat-icon><span>1/4 \u2014 1/4 \u2014 1/4 \u2014\n 1/4</span></button>\n <button mat-menu-item (click)=\"addColumn()\"><mat-icon>add</mat-icon><span>Adicionar coluna</span></button>\n <button mat-menu-item (click)=\"removeRow()\"><mat-icon>delete</mat-icon><span>Remover linha</span></button>\n </ng-template>\n </mat-menu>\n </div>\n </div>\n <div class=\"span-warning\" *ngIf=\"getSpanTotal(previewBreakpoint) !== 12\">\n <mat-icon color=\"warn\">warning</mat-icon>\n Soma de spans = {{ getSpanTotal(previewBreakpoint) }} (ideal: 12)\n </div>\n</div>\n\n<div class=\"row-container\" [style.marginBottom.px]=\"!isLastRow ? (row.rowGap || null) : null\">\n <ng-container *ngIf=\"row.columns.length > 0; else emptyRow\">\n <div class=\"row grid-12\" cdkDropListGroup (click)=\"selectRow()\" [class.selected]=\"isRowSelected()\" tabindex=\"0\"\n role=\"button\" [attr.aria-label]=\"'Linha ' + (rowIndex + 1)\" [attr.aria-selected]=\"isRowSelected()\"\n [style.--pfx-grid-gap.px]=\"row.gap || null\" [style.--px-row-field-gap.px]=\"row.rowGap ?? null\">\n <div class=\"row-label\" aria-hidden=\"true\">Linha {{ rowIndex + 1 }}</div>\n <div *ngFor=\"let column of row.columns; let i = index\" class=\"column\" [id]=\"getColumnId(i)\" cdkDropList\n [cdkDropListData]=\"column.fields\" [cdkDropListConnectedTo]=\"connectedColumns(i)\"\n (cdkDropListDropped)=\"drop($event)\" (cdkDropListEntered)=\"onDropEnter(i)\" (cdkDropListExited)=\"onDropExit(i)\"\n (click)=\"selectColumn(i, $event)\" [class.drop-active]=\"activeDropIndex === i\"\n [class.selected]=\"isColumnSelected(i)\" [ngClass]=\"getColumnClassList(column)\"\n [style.grid-column]=\"'span ' + getSpanFor(column)\" tabindex=\"0\" role=\"button\"\n [attr.aria-label]=\"'Coluna ' + (i + 1) + ' de Linha ' + (rowIndex + 1) + '; Largura ' + getSpanFor(column)\"\n [attr.aria-selected]=\"isColumnSelected(i)\">\n <div class=\"column-header\">\n <div class=\"column-status-pill\" [matMenuTriggerFor]=\"columnSettingsMenu\"\n matTooltip=\"Clique para ajustar largura e offset\" [class.active]=\"isColumnSelected(i)\">\n <span class=\"status-bp\">{{ previewBreakpoint }}</span>\n <span class=\"status-divider\">\u00B7</span>\n <span class=\"status-span\">\n <mat-icon>view_column</mat-icon>\n {{ getSpanFor(column) }}/12\n </span>\n <span class=\"status-divider\">\u00B7</span>\n <span class=\"status-offset\">\n off {{ getOffsetFor(column) }}\n </span>\n <span class=\"status-hidden\" *ngIf=\"getHiddenFor(column)\">\n <mat-icon>visibility_off</mat-icon>\n </span>\n </div>\n\n <div class=\"column-actions\">\n <button mat-icon-button class=\"action-btn\" [matMenuTriggerFor]=\"columnOverflowMenu\"\n (click)=\"$event.stopPropagation()\" matTooltip=\"Op\u00E7\u00F5es da coluna\">\n <mat-icon>more_vert</mat-icon>\n </button>\n </div>\n </div>\n\n <mat-menu #columnSettingsMenu=\"matMenu\" class=\"column-settings-popover\">\n <div class=\"popover-content\" (click)=\"$event.stopPropagation()\">\n <div class=\"control-group\" *ngIf=\"getSuggestedSpan(i) as suggested\">\n <button mat-flat-button color=\"primary\" (click)=\"setSpan(i, suggested)\"\n matTooltip=\"Ajustar largura para completar 12 colunas\">\n <mat-icon>auto_fix_high</mat-icon>\n Ajustar para {{ suggested }} (Total 12)\n </button>\n </div>\n <div class=\"control-group\">\n <label>Largura ({{ previewBreakpoint }})</label>\n <div class=\"control-row\">\n <button mat-icon-button (click)=\"adjustSpan(i, -1)\"><mat-icon>remove</mat-icon></button>\n <span class=\"value-display\">{{ getSpanFor(column) }} / 12</span>\n <button mat-icon-button (click)=\"adjustSpan(i, 1)\"><mat-icon>add</mat-icon></button>\n </div>\n </div>\n <div class=\"control-group\">\n <label>Offset ({{ previewBreakpoint }})</label>\n <div class=\"control-row\">\n <button mat-icon-button (click)=\"adjustOffset(i, -1)\"><mat-icon>chevron_left</mat-icon></button>\n <span class=\"value-display\">{{ getOffsetFor(column) }}</span>\n <button mat-icon-button (click)=\"adjustOffset(i, 1)\"><mat-icon>chevron_right</mat-icon></button>\n </div>\n </div>\n <div class=\"control-group\">\n <button mat-stroked-button (click)=\"toggleHidden(i)\" [color]=\"getHiddenFor(column) ? 'warn' : ''\">\n <mat-icon>{{ getHiddenFor(column) ? 'visibility' : 'visibility_off' }}</mat-icon>\n {{ getHiddenFor(column) ? 'Mostrar' : 'Ocultar' }}\n </button>\n </div>\n </div>\n </mat-menu>\n\n <mat-menu #columnOverflowMenu=\"matMenu\">\n <button mat-menu-item (click)=\"openColumnConfig(i)\" matTooltip=\"Abrir painel de configura\u00E7\u00E3o completa\">\n <mat-icon>tune</mat-icon>\n <span>Configurar coluna</span>\n </button>\n <mat-divider></mat-divider>\n <button mat-menu-item (click)=\"moveColumn(i, -1)\" [disabled]=\"i === 0\"\n matTooltip=\"Mover coluna para a esquerda\">\n <mat-icon>arrow_back</mat-icon>\n <span>Mover para esquerda</span>\n </button>\n <button mat-menu-item (click)=\"moveColumn(i, 1)\" [disabled]=\"i === row.columns.length - 1\"\n matTooltip=\"Mover coluna para a direita\">\n <mat-icon>arrow_forward</mat-icon>\n <span>Mover para direita</span>\n </button>\n\n <button mat-menu-item (click)=\"clearColumn(i)\" [disabled]=\"column.fields.length === 0\"\n matTooltip=\"Remover todos os campos desta coluna\">\n <mat-icon>backspace</mat-icon>\n <span>Limpar conte\u00FAdo</span>\n </button>\n <mat-divider></mat-divider>\n <button mat-menu-item (click)=\"removeColumn(i)\" matTooltip=\"Excluir esta coluna\">\n <mat-icon color=\"warn\">delete</mat-icon>\n <span>Remover coluna</span>\n </button>\n </mat-menu>\n <div class=\"column-content\">\n <div class=\"hidden-overlay\" *ngIf=\"getHiddenFor(column)\">\n <mat-icon aria-hidden=\"true\">visibility_off</mat-icon>\n <span>Oculta em {{ previewBreakpoint }}</span>\n </div>\n <ng-container *ngIf=\"column.fields.length > 0; else emptyColumn\">\n <div *ngFor=\"let fieldName of column.fields\" (click)=\"selectField(fieldName, $event)\"\n [class.selected]=\"isFieldSelected(fieldName)\">\n <praxis-field-configurator [field]=\"getFieldByName(fieldName)\"></praxis-field-configurator>\n </div>\n </ng-container>\n <ng-template #emptyColumn>\n <div class=\"column-placeholder\">\n <span>Coluna vazia \u2014 solte um campo ou remova.</span>\n </div>\n </ng-template>\n </div>\n </div>\n </div>\n </ng-container>\n <ng-template #emptyRow>\n <div class=\"row-empty-placeholder\">\n <span>Linha vazia \u2014 crie colunas ou remova.</span>\n <div class=\"row-placeholder-actions\">\n <button mat-stroked-button (click)=\"addColumn()\" matTooltip=\"Adicionar coluna\">\n <mat-icon>add</mat-icon> Adicionar coluna\n </button>\n <button mat-stroked-button color=\"warn\" (click)=\"removeRow()\" matTooltip=\"Remover linha\">\n <mat-icon>delete</mat-icon> Remover linha\n </button>\n </div>\n </div>\n </ng-template>\n</div>\n", styles: [".row-meta{display:flex;align-items:center;gap:8px;margin-bottom:8px;flex-wrap:wrap}.bp-toggle{display:inline-flex;gap:4px;align-items:center}.bp-toggle__btn{min-width:34px;height:30px;line-height:30px;padding:0 8px;text-transform:uppercase}.bp-toggle__btn.active{background:var(--md-sys-color-primary-container);color:var(--md-sys-color-on-primary-container)}.gap-controls{display:flex;gap:8px;flex-wrap:wrap;align-items:center}.gap-chip{display:inline-flex;align-items:center;gap:2px;padding:0 4px;height:32px;border-radius:8px;border:1px solid var(--md-sys-color-outline-variant);background:var(--md-sys-color-surface-variant)}.gap-chip__btn{width:24px;height:24px;line-height:24px;min-width:0;padding:0;--mdc-icon-button-size: 24px;--mdc-icon-button-state-layer-size: 24px}.gap-chip .mat-mdc-button-touch-target{width:24px;height:24px}.gap-chip mat-icon{font-size:16px;width:16px;height:16px;line-height:16px}.gap-chip__input{width:42px;border:none;background:transparent;color:var(--md-sys-color-on-surface);font:var(--mdc-typography-body-medium, 600 13px/18px system-ui);text-align:center;outline:none;-moz-appearance:textfield}.gap-chip__input::-webkit-outer-spin-button,.gap-chip__input::-webkit-inner-spin-button{-webkit-appearance:none;margin:0}.gap-chip__suffix{color:var(--md-sys-color-on-surface-variant);font:var(--mdc-typography-label-medium, 500 12px/16px system-ui)}.gap-pill{display:inline-flex;align-items:center;gap:6px;padding:4px 8px;border-radius:12px;background:var(--md-sys-color-surface-variant);color:var(--md-sys-color-on-surface-variant);font:var(--mdc-typography-label-medium, 500 12px/16px system-ui)}.chip-title{font:var(--mdc-typography-label-medium, 600 12px/16px system-ui);color:var(--md-sys-color-on-surface-variant);text-transform:uppercase;letter-spacing:.03em}.span-warning{display:inline-flex;align-items:center;gap:6px;color:var(--md-sys-color-on-error);background:var(--md-sys-color-error-container);border:1px solid var(--md-sys-color-error);border-radius:6px;padding:4px 8px}.row-container{position:relative;display:flex;align-items:stretch}.row{display:flex;flex-grow:1;position:relative;padding-right:0;border-radius:6px;transition:box-shadow .2s ease;gap:var(--pfx-grid-gap, 12px)}.row:focus{outline:none;box-shadow:0 0 0 2px var(--md-sys-color-primary)}.row:focus-visible{box-shadow:0 0 0 2px var(--md-sys-color-primary)}.row.grid-12{display:grid;grid-template-columns:repeat(12,minmax(0,1fr));gap:var(--pfx-grid-gap, 16px)}.row.selected{box-shadow:0 0 0 2px var(--md-sys-color-primary)}.row-label{position:absolute;left:-4px;top:-10px;transform:translateY(-100%);background:var(--md-sys-color-surface-variant);color:var(--md-sys-color-on-surface-variant);border:1px solid var(--md-sys-color-outline-variant);border-radius:10px;padding:2px 6px;font-size:11px;opacity:0;transition:opacity .15s ease;pointer-events:none}.row:hover .row-label,.row.selected .row-label{opacity:1}.row-actions-meta{margin-left:auto}.column{position:relative;flex:1;display:flex;flex-direction:column;border:1px dashed var(--md-sys-color-outline-variant);margin:0;background:var(--md-sys-color-surface-container);transition:background-color .2s ease,border-color .2s ease;border-radius:8px;overflow:hidden}.column-header{display:flex;align-items:center;justify-content:space-between;padding:4px 8px;background:var(--md-sys-color-surface-variant);border-bottom:1px solid var(--md-sys-color-outline-variant);min-height:36px}.column-content{flex:1;display:grid;align-content:start;gap:var(--px-row-field-gap, 6px);padding:8px}.column-status-pill{display:inline-flex;align-items:center;gap:6px;padding:2px 8px;border-radius:12px;background:var(--md-sys-color-surface);border:1px solid var(--md-sys-color-outline-variant);cursor:pointer;transition:all .2s ease;-webkit-user-select:none;user-select:none}.column-status-pill:hover,.column-status-pill.active{background:var(--md-sys-color-surface-variant);border-color:var(--md-sys-color-outline)}.status-bp{font-weight:700;text-transform:uppercase;font-size:11px;color:var(--md-sys-color-primary)}.status-divider{color:var(--md-sys-color-outline-variant)}.status-span,.status-offset{display:inline-flex;align-items:center;gap:4px;font-size:12px;color:var(--md-sys-color-on-surface)}.status-span mat-icon{font-size:14px;width:14px;height:14px}.status-hidden{color:var(--md-sys-color-error);display:flex;align-items:center}.status-hidden mat-icon{font-size:14px;width:14px;height:14px}.column-actions{display:flex;align-items:center;opacity:0;transition:opacity .2s ease}.column:hover .column-actions,.column.selected .column-actions,.column-actions:focus-within{opacity:1}.action-btn{width:24px;height:24px;line-height:24px;padding:0}.action-btn mat-icon{font-size:18px;width:18px;height:18px;line-height:18px}.popover-content{padding:12px;display:flex;flex-direction:column;gap:12px;min-width:200px}.control-group{display:flex;flex-direction:column;gap:4px}.control-group label{font-size:11px;color:var(--md-sys-color-on-surface-variant);text-transform:uppercase;font-weight:600}.control-row{display:flex;align-items:center;justify-content:space-between;background:var(--md-sys-color-surface-container-high);border-radius:8px;padding:2px}.value-display{font-weight:600;font-size:13px}.row.grid-12 .column{flex:unset}.column>div{margin:0}.column:focus{outline:none;box-shadow:0 0 0 2px var(--md-sys-color-primary)}.column:focus-visible{box-shadow:0 0 0 2px var(--md-sys-color-primary)}.column.drop-active{border-color:var(--md-sys-color-primary);background:var(--md-sys-color-surface-variant)}.column.selected{border-color:var(--md-sys-color-primary);box-shadow:0 0 0 2px var(--md-sys-color-primary)}.column.cdk-drop-list-receiving{animation:columnHighlight .3s ease-in-out}@keyframes columnHighlight{0%{box-shadow:0 0 0 2px var(--md-sys-color-primary)}to{box-shadow:none}}.field-selected-highlight.selected .field-item,.selected>.field-item{border-color:var(--md-sys-color-primary)!important;box-shadow:0 0 0 2px var(--md-sys-color-primary)}.row-empty-placeholder{flex:1;border:1px dashed var(--md-sys-color-outline-variant);margin:0;padding:16px;text-align:center;color:var(--md-sys-color-on-surface-variant);background:var(--md-sys-color-surface-container)}.row-placeholder-actions{margin-top:8px;display:flex;gap:8px;justify-content:center}.hidden-overlay{position:absolute;inset:0;background:var(--md-sys-color-surface-container-low);border:1px dashed var(--md-sys-color-outline);display:flex;align-items:center;justify-content:center;gap:6px;color:var(--md-sys-color-on-surface-variant);z-index:2;pointer-events:none}\n"], dependencies: [{ kind: "ngmodule", type: CommonModule }, { kind: "directive", type: i1$1.NgClass, selector: "[ngClass]", inputs: ["class", "ngClass"] }, { kind: "directive", type: i1$1.NgForOf, selector: "[ngFor][ngForOf]", inputs: ["ngForOf", "ngForTrackBy", "ngForTemplate"] }, { kind: "directive", type: i1$1.NgIf, selector: "[ngIf]", inputs: ["ngIf", "ngIfThen", "ngIfElse"] }, { kind: "ngmodule", type: DragDropModule }, { kind: "directive", type: i2$2.CdkDropList, selector: "[cdkDropList], cdk-drop-list", inputs: ["cdkDropListConnectedTo", "cdkDropListData", "cdkDropListOrientation", "id", "cdkDropListLockAxis", "cdkDropListDisabled", "cdkDropListSortingDisabled", "cdkDropListEnterPredicate", "cdkDropListSortPredicate", "cdkDropListAutoScrollDisabled", "cdkDropListAutoScrollStep", "cdkDropListElementContainer", "cdkDropListHasAnchor"], outputs: ["cdkDropListDropped", "cdkDropListEntered", "cdkDropListExited", "cdkDropListSorted"], exportAs: ["cdkDropList"] }, { kind: "directive", type: i2$2.CdkDropListGroup, selector: "[cdkDropListGroup]", inputs: ["cdkDropListGroupDisabled"], exportAs: ["cdkDropListGroup"] }, { kind: "component", type: FieldConfiguratorComponent, selector: "praxis-field-configurator", inputs: ["field"] }, { kind: "ngmodule", type: FormsModule }, { kind: "directive", type: i1$3.DefaultValueAccessor, selector: "input:not([type=checkbox])[formControlName],textarea[formControlName],input:not([type=checkbox])[formControl],textarea[formControl],input:not([type=checkbox])[ngModel],textarea[ngModel],[ngDefaultControl]" }, { kind: "directive", type: i1$3.NumberValueAccessor, selector: "input[type=number][formControlName],input[type=number][formControl],input[type=number][ngModel]" }, { kind: "directive", type: i1$3.NgControlStatus, selector: "[formControlName],[ngModel],[formControl]" }, { kind: "directive", type: i1$3.MinValidator, selector: "input[type=number][min][formControlName],input[type=number][min][formControl],input[type=number][min][ngModel]", inputs: ["min"] }, { kind: "directive", type: i1$3.NgModel, selector: "[ngModel]:not([formControlName]):not([formControl])", inputs: ["name", "disabled", "ngModel", "ngModelOptions"], outputs: ["ngModelChange"], exportAs: ["ngModel"] }, { kind: "ngmodule", type: MatButtonModule }, { kind: "component", type: i4.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: i4.MatIconButton, selector: "button[mat-icon-button], a[mat-icon-button], button[matIconButton], a[matIconButton]", exportAs: ["matButton", "matAnchor"] }, { kind: "ngmodule", type: MatIconModule }, { kind: "component", type: i5.MatIcon, selector: "mat-icon", inputs: ["color", "inline", "svgIcon", "fontSet", "fontIcon"], exportAs: ["matIcon"] }, { kind: "ngmodule", type: MatTooltipModule }, { kind: "directive", type: i9.MatTooltip, selector: "[matTooltip]", inputs: ["matTooltipPosition", "matTooltipPositionAtOrigin", "matTooltipDisabled", "matTooltipShowDelay", "matTooltipHideDelay", "matTooltipTouchGestures", "matTooltip", "matTooltipClass"], exportAs: ["matTooltip"] }, { kind: "ngmodule", type: MatMenuModule }, { kind: "component", type: i6.MatMenu, selector: "mat-menu", inputs: ["backdropClass", "aria-label", "aria-labelledby", "aria-describedby", "xPosition", "yPosition", "overlapTrigger", "hasBackdrop", "class", "classList"], outputs: ["closed", "close"], exportAs: ["matMenu"] }, { kind: "component", type: i6.MatMenuItem, selector: "[mat-menu-item]", inputs: ["role", "disabled", "disableRipple"], exportAs: ["matMenuItem"] }, { kind: "directive", type: i6.MatMenuTrigger, selector: "[mat-menu-trigger-for], [matMenuTriggerFor]", inputs: ["mat-menu-trigger-for", "matMenuTriggerFor", "matMenuTriggerData", "matMenuTriggerRestoreFocus"], outputs: ["menuOpened", "onMenuOpen", "menuClosed", "onMenuClose"], exportAs: ["matMenuTrigger"] }, { kind: "ngmodule", type: MatDividerModule }, { kind: "component", type: i11.MatDivider, selector: "mat-divider", inputs: ["vertical", "inset"] }] });
14118
+ static ɵcmp = i0.ɵɵngDeclareComponent({ minVersion: "14.0.0", version: "20.3.17", type: RowConfiguratorComponent, isStandalone: true, selector: "praxis-row-configurator", inputs: { row: "row", fieldMetadata: "fieldMetadata", availableFields: "availableFields", sectionIndex: "sectionIndex", rowIndex: "rowIndex", isLastRow: "isLastRow", selected: "selected", availableFieldsListId: "availableFieldsListId", connectedDropListIds: "connectedDropListIds", gapGlobal: "gapGlobal" }, outputs: { rowChange: "rowChange", remove: "remove", applyRowGapAll: "applyRowGapAll", fieldDrop: "fieldDrop", addVisualBlock: "addVisualBlock", addApiField: "addApiField", editVisualBlock: "editVisualBlock", moveVisualBlock: "moveVisualBlock", moveVisualBlockToColumn: "moveVisualBlockToColumn", removeVisualBlock: "removeVisualBlock", select: "select" }, providers: [providePraxisI18nConfig(LAYOUT_EDITOR_I18N_CONFIG)], usesOnChanges: true, ngImport: i0, template: "<div class=\"row-meta\" *ngIf=\"row\">\n <div class=\"bp-toggle\" role=\"group\" aria-label=\"Breakpoint de visualiza\u00E7\u00E3o\">\n <button\n *ngFor=\"let bp of breakpoints\"\n type=\"button\"\n mat-stroked-button\n class=\"bp-toggle__btn\"\n [class.active]=\"previewBreakpoint === bp\"\n (click)=\"previewBreakpoint = bp\"\n >\n {{ bp }}\n </button>\n </div>\n <div class=\"gap-controls\">\n <div class=\"gap-chip\" *ngIf=\"hasMultipleColumns()\" matTooltip=\"Gap entre colunas (px)\"\n aria-label=\"Gap entre colunas\">\n <span class=\"chip-title\">Colunas</span>\n <button mat-icon-button class=\"gap-chip__btn\" (click)=\"adjustRowGapDelta('gap', -2)\"\n aria-label=\"Reduzir gap de colunas\">\n <mat-icon>remove</mat-icon>\n </button>\n <input class=\"gap-chip__input\" type=\"number\" min=\"0\" [ngModel]=\"row.gap ?? gapGlobal\"\n (ngModelChange)=\"updateRowGap('gap', $event)\" aria-label=\"Valor do gap entre colunas\" />\n <span class=\"gap-chip__suffix\">px</span>\n <button mat-icon-button class=\"gap-chip__btn\" (click)=\"adjustRowGapDelta('gap', 2)\"\n aria-label=\"Aumentar gap de colunas\">\n <mat-icon>add</mat-icon>\n </button>\n </div>\n <div class=\"gap-chip\" matTooltip=\"Gap abaixo da linha (px)\" aria-label=\"Gap abaixo da linha\">\n <span class=\"chip-title\">Linha</span>\n <button mat-icon-button class=\"gap-chip__btn\" (click)=\"adjustRowGapDelta('rowGap', -2)\"\n aria-label=\"Reduzir espa\u00E7o entre campos da linha\" matTooltip=\"Reduz o espa\u00E7o entre campos desta linha\">\n <mat-icon>remove</mat-icon>\n </button>\n <input class=\"gap-chip__input\" type=\"number\" min=\"0\" [ngModel]=\"row.rowGap ?? 0\"\n (ngModelChange)=\"updateRowGap('rowGap', $event)\" aria-label=\"Espa\u00E7o entre campos desta linha\" />\n <span class=\"gap-chip__suffix\">px</span>\n <button mat-icon-button class=\"gap-chip__btn\" (click)=\"adjustRowGapDelta('rowGap', 2)\"\n aria-label=\"Aumentar espa\u00E7o entre campos da linha\" matTooltip=\"Aumenta o espa\u00E7o entre campos desta linha\">\n <mat-icon>add</mat-icon>\n </button>\n <button mat-icon-button class=\"gap-chip__btn\" [matMenuTriggerFor]=\"rowGapMenu\"\n matTooltip=\"Mais op\u00E7\u00F5es para aplicar este espa\u00E7o\" aria-label=\"Mais op\u00E7\u00F5es de aplica\u00E7\u00E3o\">\n <mat-icon>done_all</mat-icon>\n </button>\n <mat-menu #rowGapMenu=\"matMenu\">\n <button mat-menu-item (click)=\"applyRowGapToAll()\">\n <mat-icon>done_all</mat-icon>\n <span>Aplicar em todas as linhas da se\u00E7\u00E3o</span>\n </button>\n <button mat-menu-item (click)=\"clearRowGap()\">\n <mat-icon>undo</mat-icon>\n <span>Voltar ao padr\u00E3o</span>\n </button>\n </mat-menu>\n </div>\n <div class=\"gap-pill\" aria-label=\"Resumo de espa\u00E7amentos\">\n Campos: {{ (row.rowGap ?? 'padr\u00E3o') }}px \u00B7 Colunas: {{ (row.gap ?? gapGlobal) }}px\n </div>\n <div class=\"row-actions-meta\">\n <button mat-icon-button [matMenuTriggerFor]=\"rowMenu\" (click)=\"openRowMenu()\" matTooltip=\"Op\u00E7\u00F5es da linha\">\n <mat-icon>more_vert</mat-icon>\n </button>\n <mat-menu #rowMenu=\"matMenu\" (closed)=\"onMenuClosed()\">\n <ng-container *ngIf=\"menuContext?.type === 'column'; else rowMenuContent\">\n <button mat-menu-item (click)=\"toggleHidden(menuContext!.columnIndex!)\">\n <mat-icon>{{ getHiddenFor(row.columns[menuContext!.columnIndex!]) ? 'visibility' : 'visibility_off'\n }}</mat-icon>\n <span>{{ getHiddenFor(row.columns[menuContext!.columnIndex!]) ? 'Mostrar neste breakpoint' : 'Ocultar neste\n breakpoint' }}</span>\n </button>\n <button mat-menu-item (click)=\"removeColumn(menuContext!.columnIndex!)\">\n <mat-icon color=\"warn\">delete</mat-icon>\n <span>Remover coluna</span>\n </button>\n </ng-container>\n <ng-template #rowMenuContent>\n <div mat-menu-item disabled>Presets de colunas</div>\n <button mat-menu-item (click)=\"applyPreset([12])\"><mat-icon>view_column</mat-icon><span>1/1</span></button>\n <button mat-menu-item (click)=\"applyPreset([6,6])\"><mat-icon>view_column</mat-icon><span>1/2 \u2014\n 1/2</span></button>\n <button mat-menu-item (click)=\"applyPreset([4,8])\"><mat-icon>view_column</mat-icon><span>1/3 \u2014\n 2/3</span></button>\n <button mat-menu-item (click)=\"applyPreset([8,4])\"><mat-icon>view_column</mat-icon><span>2/3 \u2014\n 1/3</span></button>\n <button mat-menu-item (click)=\"applyPreset([4,4,4])\"><mat-icon>view_column</mat-icon><span>1/3 \u2014 1/3 \u2014\n 1/3</span></button>\n <button mat-menu-item (click)=\"applyPreset([3,3,3,3])\"><mat-icon>view_column</mat-icon><span>1/4 \u2014 1/4 \u2014 1/4 \u2014\n 1/4</span></button>\n <button mat-menu-item (click)=\"addColumn()\"><mat-icon>add</mat-icon><span>Adicionar coluna</span></button>\n <button mat-menu-item (click)=\"removeRow()\"><mat-icon>delete</mat-icon><span>Remover linha</span></button>\n </ng-template>\n </mat-menu>\n </div>\n </div>\n <div class=\"span-warning\" *ngIf=\"getSpanTotal(previewBreakpoint) !== 12\">\n <mat-icon color=\"warn\">warning</mat-icon>\n Soma de spans = {{ getSpanTotal(previewBreakpoint) }} (ideal: 12)\n </div>\n</div>\n\n<div class=\"row-container\" [style.marginBottom.px]=\"!isLastRow ? (row.rowGap || null) : null\">\n <ng-container *ngIf=\"row.columns.length > 0; else emptyRow\">\n <div class=\"row grid-12\" cdkDropListGroup (click)=\"selectRow()\" [class.selected]=\"isRowSelected()\" tabindex=\"0\"\n role=\"button\" [attr.aria-label]=\"'Linha ' + (rowIndex + 1)\" [attr.aria-selected]=\"isRowSelected()\"\n [style.--pfx-grid-gap.px]=\"row.gap || null\" [style.--px-row-field-gap.px]=\"row.rowGap ?? null\">\n <div class=\"row-label\" aria-hidden=\"true\">Linha {{ rowIndex + 1 }}</div>\n <div *ngFor=\"let column of row.columns; let i = index\" class=\"column\" [id]=\"getColumnId(i)\" cdkDropList\n [cdkDropListData]=\"column.fields\" [cdkDropListConnectedTo]=\"connectedColumns(i)\"\n (cdkDropListDropped)=\"drop($event)\" (cdkDropListEntered)=\"onDropEnter(i)\" (cdkDropListExited)=\"onDropExit(i)\"\n (click)=\"selectColumn(i, $event)\" [class.drop-active]=\"activeDropIndex === i\"\n [class.selected]=\"isColumnSelected(i)\" [ngClass]=\"getColumnClassList(column)\"\n [style.grid-column]=\"'span ' + getSpanFor(column)\" tabindex=\"0\" role=\"button\"\n [attr.aria-label]=\"'Coluna ' + (i + 1) + ' de Linha ' + (rowIndex + 1) + '; Largura ' + getSpanFor(column)\"\n [attr.aria-selected]=\"isColumnSelected(i)\">\n <div class=\"column-header\">\n <div class=\"column-status-pill\" [matMenuTriggerFor]=\"columnSettingsMenu\"\n matTooltip=\"Clique para ajustar largura e offset\" [class.active]=\"isColumnSelected(i)\">\n <span class=\"status-bp\">{{ previewBreakpoint }}</span>\n <span class=\"status-divider\">\u00B7</span>\n <span class=\"status-span\">\n <mat-icon>view_column</mat-icon>\n {{ getSpanFor(column) }}/12\n </span>\n <span class=\"status-divider\">\u00B7</span>\n <span class=\"status-offset\">\n off {{ getOffsetFor(column) }}\n </span>\n <span class=\"status-hidden\" *ngIf=\"getHiddenFor(column)\">\n <mat-icon>visibility_off</mat-icon>\n </span>\n </div>\n\n <div class=\"column-actions\">\n <button mat-icon-button class=\"action-btn\" [matMenuTriggerFor]=\"columnOverflowMenu\"\n (click)=\"$event.stopPropagation()\" matTooltip=\"Op\u00E7\u00F5es da coluna\">\n <mat-icon>more_vert</mat-icon>\n </button>\n </div>\n </div>\n\n <mat-menu #columnSettingsMenu=\"matMenu\" class=\"column-settings-popover\">\n <div class=\"popover-content\" (click)=\"$event.stopPropagation()\">\n <div class=\"control-group\" *ngIf=\"getSuggestedSpan(i) as suggested\">\n <button mat-flat-button color=\"primary\" (click)=\"setSpan(i, suggested)\"\n matTooltip=\"Ajustar largura para completar 12 colunas\">\n <mat-icon>auto_fix_high</mat-icon>\n Ajustar para {{ suggested }} (Total 12)\n </button>\n </div>\n <div class=\"control-group\">\n <label>Largura ({{ previewBreakpoint }})</label>\n <div class=\"control-row\">\n <button mat-icon-button (click)=\"adjustSpan(i, -1)\"><mat-icon>remove</mat-icon></button>\n <span class=\"value-display\">{{ getSpanFor(column) }} / 12</span>\n <button mat-icon-button (click)=\"adjustSpan(i, 1)\"><mat-icon>add</mat-icon></button>\n </div>\n </div>\n <div class=\"control-group\">\n <label>Offset ({{ previewBreakpoint }})</label>\n <div class=\"control-row\">\n <button mat-icon-button (click)=\"adjustOffset(i, -1)\"><mat-icon>chevron_left</mat-icon></button>\n <span class=\"value-display\">{{ getOffsetFor(column) }}</span>\n <button mat-icon-button (click)=\"adjustOffset(i, 1)\"><mat-icon>chevron_right</mat-icon></button>\n </div>\n </div>\n <div class=\"control-group\">\n <button mat-stroked-button (click)=\"toggleHidden(i)\" [color]=\"getHiddenFor(column) ? 'warn' : ''\">\n <mat-icon>{{ getHiddenFor(column) ? 'visibility' : 'visibility_off' }}</mat-icon>\n {{ getHiddenFor(column) ? 'Mostrar' : 'Ocultar' }}\n </button>\n </div>\n </div>\n </mat-menu>\n\n <mat-menu #columnOverflowMenu=\"matMenu\">\n <button mat-menu-item (click)=\"openColumnConfig(i)\" matTooltip=\"Abrir painel de configura\u00E7\u00E3o completa\">\n <mat-icon>tune</mat-icon>\n <span>Configurar coluna</span>\n </button>\n <button mat-menu-item [matMenuTriggerFor]=\"apiFieldMenu\" [matTooltip]=\"t('apiFields.addTooltip')\">\n <mat-icon>input</mat-icon>\n <span>{{ t('apiFields.addAction') }}</span>\n </button>\n <mat-menu #apiFieldMenu=\"matMenu\">\n <button\n mat-menu-item\n *ngFor=\"let field of availableFields\"\n (click)=\"addApiFieldToColumn(i, field.name)\"\n >\n <mat-icon>short_text</mat-icon>\n <span>{{ getFieldLabel(field) }}</span>\n </button>\n <button mat-menu-item disabled *ngIf=\"!availableFields.length\">\n <span>{{ t('apiFields.empty') }}</span>\n </button>\n </mat-menu>\n <button mat-menu-item [matMenuTriggerFor]=\"visualBlockPresetMenu\" [matTooltip]=\"t('visualBlock.addTooltip')\">\n <mat-icon>notes</mat-icon>\n <span>{{ t('visualBlock.addAction') }}</span>\n </button>\n <mat-menu #visualBlockPresetMenu=\"matMenu\">\n <button\n mat-menu-item\n *ngFor=\"let preset of visualBlockPresets\"\n (click)=\"addVisualBlockToColumn(i, preset.id)\"\n >\n <mat-icon>{{ preset.icon }}</mat-icon>\n <span>{{ t(preset.labelKey) }}</span>\n </button>\n </mat-menu>\n <mat-divider></mat-divider>\n <button mat-menu-item (click)=\"moveColumn(i, -1)\" [disabled]=\"i === 0\"\n matTooltip=\"Mover coluna para a esquerda\">\n <mat-icon>arrow_back</mat-icon>\n <span>Mover para esquerda</span>\n </button>\n <button mat-menu-item (click)=\"moveColumn(i, 1)\" [disabled]=\"i === row.columns.length - 1\"\n matTooltip=\"Mover coluna para a direita\">\n <mat-icon>arrow_forward</mat-icon>\n <span>Mover para direita</span>\n </button>\n\n <button mat-menu-item (click)=\"clearColumn(i)\" [disabled]=\"!hasColumnContent(column)\"\n matTooltip=\"Remover todo o conte\u00C3\u00BAdo desta coluna\">\n <mat-icon>backspace</mat-icon>\n <span>Limpar conte\u00FAdo</span>\n </button>\n <mat-divider></mat-divider>\n <button mat-menu-item (click)=\"removeColumn(i)\" matTooltip=\"Excluir esta coluna\">\n <mat-icon color=\"warn\">delete</mat-icon>\n <span>Remover coluna</span>\n </button>\n </mat-menu>\n <div class=\"column-content\">\n <div class=\"hidden-overlay\" *ngIf=\"getHiddenFor(column)\">\n <mat-icon aria-hidden=\"true\">visibility_off</mat-icon>\n <span>Oculta em {{ previewBreakpoint }}</span>\n </div>\n <ng-container *ngIf=\"hasColumnContent(column); else emptyColumn\">\n <ng-container *ngFor=\"let item of getColumnLayoutItems(column); let itemIndex = index\">\n <div *ngIf=\"item.kind === 'field'; else visualBlockItem\" (click)=\"selectField(item.fieldName, $event)\"\n [class.selected]=\"isFieldSelected(item.fieldName)\">\n <praxis-field-configurator [field]=\"getFieldByName(item.fieldName)\"></praxis-field-configurator>\n </div>\n <ng-template #visualBlockItem>\n <div\n class=\"visual-block-preview\"\n *ngIf=\"item.kind === 'richContent'\"\n role=\"button\"\n tabindex=\"0\"\n [class.selected]=\"selected?.type === 'visualBlock' && selected?.itemId === item.id\"\n (click)=\"selectVisualBlock(i, item, $event)\"\n (dblclick)=\"openVisualBlockEditor(i, item, $event)\"\n >\n <mat-icon aria-hidden=\"true\">notes</mat-icon>\n <span>{{ getVisualBlockLabel(item) }}</span>\n <span class=\"visual-block-preview__actions\">\n <button\n mat-icon-button\n class=\"visual-block-preview__action\"\n type=\"button\"\n [matTooltip]=\"t('visualBlock.moveUp')\"\n [attr.aria-label]=\"t('visualBlock.moveUp')\"\n [disabled]=\"itemIndex === 0\"\n (click)=\"moveVisualBlockItem(i, item, -1, $event)\"\n >\n <mat-icon>arrow_upward</mat-icon>\n </button>\n <button\n mat-icon-button\n class=\"visual-block-preview__action\"\n type=\"button\"\n [matTooltip]=\"t('visualBlock.moveDown')\"\n [attr.aria-label]=\"t('visualBlock.moveDown')\"\n [disabled]=\"itemIndex === getColumnLayoutItems(column).length - 1\"\n (click)=\"moveVisualBlockItem(i, item, 1, $event)\"\n >\n <mat-icon>arrow_downward</mat-icon>\n </button>\n <button\n mat-icon-button\n class=\"visual-block-preview__action\"\n type=\"button\"\n [matTooltip]=\"t('visualBlock.movePreviousColumn')\"\n [attr.aria-label]=\"t('visualBlock.movePreviousColumn')\"\n [disabled]=\"!canMoveVisualBlockToColumn(i, -1)\"\n (click)=\"moveVisualBlockToAdjacentColumn(i, item, -1, $event)\"\n >\n <mat-icon>arrow_back</mat-icon>\n </button>\n <button\n mat-icon-button\n class=\"visual-block-preview__action\"\n type=\"button\"\n [matTooltip]=\"t('visualBlock.moveNextColumn')\"\n [attr.aria-label]=\"t('visualBlock.moveNextColumn')\"\n [disabled]=\"!canMoveVisualBlockToColumn(i, 1)\"\n (click)=\"moveVisualBlockToAdjacentColumn(i, item, 1, $event)\"\n >\n <mat-icon>arrow_forward</mat-icon>\n </button>\n <button\n mat-icon-button\n class=\"visual-block-preview__action\"\n type=\"button\"\n [matTooltip]=\"t('visualBlock.editAction')\"\n [attr.aria-label]=\"t('visualBlock.editAction')\"\n (click)=\"openVisualBlockEditor(i, item, $event)\"\n >\n <mat-icon>edit</mat-icon>\n </button>\n <button\n mat-icon-button\n class=\"visual-block-preview__action\"\n type=\"button\"\n color=\"warn\"\n [matTooltip]=\"t('visualBlock.removeAction')\"\n [attr.aria-label]=\"t('visualBlock.removeAction')\"\n (click)=\"removeVisualBlockItem(i, item, $event)\"\n >\n <mat-icon>delete</mat-icon>\n </button>\n </span>\n </div>\n </ng-template>\n </ng-container>\n </ng-container>\n <ng-template #emptyColumn>\n <div class=\"column-placeholder\">\n <span>Coluna vazia \u2014 solte um campo ou remova.</span>\n </div>\n </ng-template>\n </div>\n </div>\n </div>\n </ng-container>\n <ng-template #emptyRow>\n <div class=\"row-empty-placeholder\">\n <span>Linha vazia \u2014 crie colunas ou remova.</span>\n <div class=\"row-placeholder-actions\">\n <button mat-stroked-button (click)=\"addColumn()\" matTooltip=\"Adicionar coluna\">\n <mat-icon>add</mat-icon> Adicionar coluna\n </button>\n <button mat-stroked-button color=\"warn\" (click)=\"removeRow()\" matTooltip=\"Remover linha\">\n <mat-icon>delete</mat-icon> Remover linha\n </button>\n </div>\n </div>\n </ng-template>\n</div>\n", styles: [".row-meta{display:flex;align-items:center;gap:8px;margin-bottom:8px;flex-wrap:wrap}.bp-toggle{display:inline-flex;gap:4px;align-items:center}.bp-toggle__btn{min-width:34px;height:30px;line-height:30px;padding:0 8px;text-transform:uppercase}.bp-toggle__btn.active{background:var(--md-sys-color-primary-container);color:var(--md-sys-color-on-primary-container)}.gap-controls{display:flex;gap:8px;flex-wrap:wrap;align-items:center}.gap-chip{display:inline-flex;align-items:center;gap:2px;padding:0 4px;height:32px;border-radius:8px;border:1px solid var(--md-sys-color-outline-variant);background:var(--md-sys-color-surface-variant)}.gap-chip__btn{width:24px;height:24px;line-height:24px;min-width:0;padding:0;--mdc-icon-button-size: 24px;--mdc-icon-button-state-layer-size: 24px}.gap-chip .mat-mdc-button-touch-target{width:24px;height:24px}.gap-chip mat-icon{font-size:16px;width:16px;height:16px;line-height:16px}.gap-chip__input{width:42px;border:none;background:transparent;color:var(--md-sys-color-on-surface);font:var(--mdc-typography-body-medium, 600 13px/18px system-ui);text-align:center;outline:none;-moz-appearance:textfield}.gap-chip__input::-webkit-outer-spin-button,.gap-chip__input::-webkit-inner-spin-button{-webkit-appearance:none;margin:0}.gap-chip__suffix{color:var(--md-sys-color-on-surface-variant);font:var(--mdc-typography-label-medium, 500 12px/16px system-ui)}.gap-pill{display:inline-flex;align-items:center;gap:6px;padding:4px 8px;border-radius:12px;background:var(--md-sys-color-surface-variant);color:var(--md-sys-color-on-surface-variant);font:var(--mdc-typography-label-medium, 500 12px/16px system-ui)}.chip-title{font:var(--mdc-typography-label-medium, 600 12px/16px system-ui);color:var(--md-sys-color-on-surface-variant);text-transform:uppercase;letter-spacing:.03em}.span-warning{display:inline-flex;align-items:center;gap:6px;color:var(--md-sys-color-on-error);background:var(--md-sys-color-error-container);border:1px solid var(--md-sys-color-error);border-radius:6px;padding:4px 8px}.row-container{position:relative;display:flex;align-items:stretch}.row{display:flex;flex-grow:1;position:relative;padding-right:0;border-radius:6px;transition:box-shadow .2s ease;gap:var(--pfx-grid-gap, 12px)}.row:focus{outline:none;box-shadow:0 0 0 2px var(--md-sys-color-primary)}.row:focus-visible{box-shadow:0 0 0 2px var(--md-sys-color-primary)}.row.grid-12{display:grid;grid-template-columns:repeat(12,minmax(0,1fr));gap:var(--pfx-grid-gap, 16px)}.row.selected{box-shadow:0 0 0 2px var(--md-sys-color-primary)}.row-label{position:absolute;left:-4px;top:-10px;transform:translateY(-100%);background:var(--md-sys-color-surface-variant);color:var(--md-sys-color-on-surface-variant);border:1px solid var(--md-sys-color-outline-variant);border-radius:10px;padding:2px 6px;font-size:11px;opacity:0;transition:opacity .15s ease;pointer-events:none}.row:hover .row-label,.row.selected .row-label{opacity:1}.row-actions-meta{margin-left:auto}.column{position:relative;flex:1;display:flex;flex-direction:column;border:1px dashed var(--md-sys-color-outline-variant);margin:0;background:var(--md-sys-color-surface-container);transition:background-color .2s ease,border-color .2s ease;border-radius:8px;overflow:hidden}.column-header{display:flex;align-items:center;justify-content:space-between;padding:4px 8px;background:var(--md-sys-color-surface-variant);border-bottom:1px solid var(--md-sys-color-outline-variant);min-height:36px}.column-content{flex:1;display:grid;align-content:start;gap:var(--px-row-field-gap, 6px);padding:8px}.column-status-pill{display:inline-flex;align-items:center;gap:6px;padding:2px 8px;border-radius:12px;background:var(--md-sys-color-surface);border:1px solid var(--md-sys-color-outline-variant);cursor:pointer;transition:all .2s ease;-webkit-user-select:none;user-select:none}.column-status-pill:hover,.column-status-pill.active{background:var(--md-sys-color-surface-variant);border-color:var(--md-sys-color-outline)}.status-bp{font-weight:700;text-transform:uppercase;font-size:11px;color:var(--md-sys-color-primary)}.status-divider{color:var(--md-sys-color-outline-variant)}.status-span,.status-offset{display:inline-flex;align-items:center;gap:4px;font-size:12px;color:var(--md-sys-color-on-surface)}.status-span mat-icon{font-size:14px;width:14px;height:14px}.status-hidden{color:var(--md-sys-color-error);display:flex;align-items:center}.status-hidden mat-icon{font-size:14px;width:14px;height:14px}.column-actions{display:flex;align-items:center;opacity:0;transition:opacity .2s ease}.column:hover .column-actions,.column.selected .column-actions,.column-actions:focus-within{opacity:1}.action-btn{width:24px;height:24px;line-height:24px;padding:0}.action-btn mat-icon{font-size:18px;width:18px;height:18px;line-height:18px}.popover-content{padding:12px;display:flex;flex-direction:column;gap:12px;min-width:200px}.control-group{display:flex;flex-direction:column;gap:4px}.control-group label{font-size:11px;color:var(--md-sys-color-on-surface-variant);text-transform:uppercase;font-weight:600}.control-row{display:flex;align-items:center;justify-content:space-between;background:var(--md-sys-color-surface-container-high);border-radius:8px;padding:2px}.value-display{font-weight:600;font-size:13px}.row.grid-12 .column{flex:unset}.column>div{margin:0}.column:focus{outline:none;box-shadow:0 0 0 2px var(--md-sys-color-primary)}.column:focus-visible{box-shadow:0 0 0 2px var(--md-sys-color-primary)}.column.drop-active{border-color:var(--md-sys-color-primary);background:var(--md-sys-color-surface-variant)}.column.selected{border-color:var(--md-sys-color-primary);box-shadow:0 0 0 2px var(--md-sys-color-primary)}.column.cdk-drop-list-receiving{animation:columnHighlight .3s ease-in-out}@keyframes columnHighlight{0%{box-shadow:0 0 0 2px var(--md-sys-color-primary)}to{box-shadow:none}}.field-selected-highlight.selected .field-item,.selected>.field-item{border-color:var(--md-sys-color-primary)!important;box-shadow:0 0 0 2px var(--md-sys-color-primary)}.visual-block-preview{display:flex;align-items:center;gap:8px;min-height:36px;padding:8px;border:1px dashed var(--md-sys-color-outline-variant);border-radius:6px;background:var(--md-sys-color-surface);color:var(--md-sys-color-on-surface-variant);font-size:13px;cursor:pointer}.visual-block-preview.selected{border-color:var(--md-sys-color-primary);box-shadow:0 0 0 2px var(--md-sys-color-primary)}.visual-block-preview mat-icon{font-size:18px;width:18px;height:18px}.visual-block-preview__actions{margin-left:auto;display:inline-flex;align-items:center;gap:2px}.visual-block-preview__action{width:28px;height:28px;--mdc-icon-button-size: 28px;--mdc-icon-button-state-layer-size: 28px}.row-empty-placeholder{flex:1;border:1px dashed var(--md-sys-color-outline-variant);margin:0;padding:16px;text-align:center;color:var(--md-sys-color-on-surface-variant);background:var(--md-sys-color-surface-container)}.row-placeholder-actions{margin-top:8px;display:flex;gap:8px;justify-content:center}.hidden-overlay{position:absolute;inset:0;background:var(--md-sys-color-surface-container-low);border:1px dashed var(--md-sys-color-outline);display:flex;align-items:center;justify-content:center;gap:6px;color:var(--md-sys-color-on-surface-variant);z-index:2;pointer-events:none}\n"], dependencies: [{ kind: "ngmodule", type: CommonModule }, { kind: "directive", type: i1$1.NgClass, selector: "[ngClass]", inputs: ["class", "ngClass"] }, { kind: "directive", type: i1$1.NgForOf, selector: "[ngFor][ngForOf]", inputs: ["ngForOf", "ngForTrackBy", "ngForTemplate"] }, { kind: "directive", type: i1$1.NgIf, selector: "[ngIf]", inputs: ["ngIf", "ngIfThen", "ngIfElse"] }, { kind: "ngmodule", type: DragDropModule }, { kind: "directive", type: i2$2.CdkDropList, selector: "[cdkDropList], cdk-drop-list", inputs: ["cdkDropListConnectedTo", "cdkDropListData", "cdkDropListOrientation", "id", "cdkDropListLockAxis", "cdkDropListDisabled", "cdkDropListSortingDisabled", "cdkDropListEnterPredicate", "cdkDropListSortPredicate", "cdkDropListAutoScrollDisabled", "cdkDropListAutoScrollStep", "cdkDropListElementContainer", "cdkDropListHasAnchor"], outputs: ["cdkDropListDropped", "cdkDropListEntered", "cdkDropListExited", "cdkDropListSorted"], exportAs: ["cdkDropList"] }, { kind: "directive", type: i2$2.CdkDropListGroup, selector: "[cdkDropListGroup]", inputs: ["cdkDropListGroupDisabled"], exportAs: ["cdkDropListGroup"] }, { kind: "component", type: FieldConfiguratorComponent, selector: "praxis-field-configurator", inputs: ["field"] }, { kind: "ngmodule", type: FormsModule }, { kind: "directive", type: i1$3.DefaultValueAccessor, selector: "input:not([type=checkbox])[formControlName],textarea[formControlName],input:not([type=checkbox])[formControl],textarea[formControl],input:not([type=checkbox])[ngModel],textarea[ngModel],[ngDefaultControl]" }, { kind: "directive", type: i1$3.NumberValueAccessor, selector: "input[type=number][formControlName],input[type=number][formControl],input[type=number][ngModel]" }, { kind: "directive", type: i1$3.NgControlStatus, selector: "[formControlName],[ngModel],[formControl]" }, { kind: "directive", type: i1$3.MinValidator, selector: "input[type=number][min][formControlName],input[type=number][min][formControl],input[type=number][min][ngModel]", inputs: ["min"] }, { kind: "directive", type: i1$3.NgModel, selector: "[ngModel]:not([formControlName]):not([formControl])", inputs: ["name", "disabled", "ngModel", "ngModelOptions"], outputs: ["ngModelChange"], exportAs: ["ngModel"] }, { kind: "ngmodule", type: MatButtonModule }, { kind: "component", type: i4.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: i4.MatIconButton, selector: "button[mat-icon-button], a[mat-icon-button], button[matIconButton], a[matIconButton]", exportAs: ["matButton", "matAnchor"] }, { kind: "ngmodule", type: MatIconModule }, { kind: "component", type: i5.MatIcon, selector: "mat-icon", inputs: ["color", "inline", "svgIcon", "fontSet", "fontIcon"], exportAs: ["matIcon"] }, { kind: "ngmodule", type: MatTooltipModule }, { kind: "directive", type: i9.MatTooltip, selector: "[matTooltip]", inputs: ["matTooltipPosition", "matTooltipPositionAtOrigin", "matTooltipDisabled", "matTooltipShowDelay", "matTooltipHideDelay", "matTooltipTouchGestures", "matTooltip", "matTooltipClass"], exportAs: ["matTooltip"] }, { kind: "ngmodule", type: MatMenuModule }, { kind: "component", type: i6.MatMenu, selector: "mat-menu", inputs: ["backdropClass", "aria-label", "aria-labelledby", "aria-describedby", "xPosition", "yPosition", "overlapTrigger", "hasBackdrop", "class", "classList"], outputs: ["closed", "close"], exportAs: ["matMenu"] }, { kind: "component", type: i6.MatMenuItem, selector: "[mat-menu-item]", inputs: ["role", "disabled", "disableRipple"], exportAs: ["matMenuItem"] }, { kind: "directive", type: i6.MatMenuTrigger, selector: "[mat-menu-trigger-for], [matMenuTriggerFor]", inputs: ["mat-menu-trigger-for", "matMenuTriggerFor", "matMenuTriggerData", "matMenuTriggerRestoreFocus"], outputs: ["menuOpened", "onMenuOpen", "menuClosed", "onMenuClose"], exportAs: ["matMenuTrigger"] }, { kind: "ngmodule", type: MatDividerModule }, { kind: "component", type: i11.MatDivider, selector: "mat-divider", inputs: ["vertical", "inset"] }] });
13506
14119
  }
13507
14120
  i0.ɵɵngDeclareClassMetadata({ minVersion: "12.0.0", version: "20.3.17", ngImport: i0, type: RowConfiguratorComponent, decorators: [{
13508
14121
  type: Component,
@@ -13516,11 +14129,13 @@ i0.ɵɵngDeclareClassMetadata({ minVersion: "12.0.0", version: "20.3.17", ngImpo
13516
14129
  MatTooltipModule,
13517
14130
  MatMenuModule,
13518
14131
  MatDividerModule,
13519
- ], template: "<div class=\"row-meta\" *ngIf=\"row\">\n <div class=\"bp-toggle\" role=\"group\" aria-label=\"Breakpoint de visualiza\u00E7\u00E3o\">\n <button\n *ngFor=\"let bp of breakpoints\"\n type=\"button\"\n mat-stroked-button\n class=\"bp-toggle__btn\"\n [class.active]=\"previewBreakpoint === bp\"\n (click)=\"previewBreakpoint = bp\"\n >\n {{ bp }}\n </button>\n </div>\n <div class=\"gap-controls\">\n <div class=\"gap-chip\" *ngIf=\"hasMultipleColumns()\" matTooltip=\"Gap entre colunas (px)\"\n aria-label=\"Gap entre colunas\">\n <span class=\"chip-title\">Colunas</span>\n <button mat-icon-button class=\"gap-chip__btn\" (click)=\"adjustRowGapDelta('gap', -2)\"\n aria-label=\"Reduzir gap de colunas\">\n <mat-icon>remove</mat-icon>\n </button>\n <input class=\"gap-chip__input\" type=\"number\" min=\"0\" [ngModel]=\"row.gap ?? gapGlobal\"\n (ngModelChange)=\"updateRowGap('gap', $event)\" aria-label=\"Valor do gap entre colunas\" />\n <span class=\"gap-chip__suffix\">px</span>\n <button mat-icon-button class=\"gap-chip__btn\" (click)=\"adjustRowGapDelta('gap', 2)\"\n aria-label=\"Aumentar gap de colunas\">\n <mat-icon>add</mat-icon>\n </button>\n </div>\n <div class=\"gap-chip\" matTooltip=\"Gap abaixo da linha (px)\" aria-label=\"Gap abaixo da linha\">\n <span class=\"chip-title\">Linha</span>\n <button mat-icon-button class=\"gap-chip__btn\" (click)=\"adjustRowGapDelta('rowGap', -2)\"\n aria-label=\"Reduzir espa\u00E7o entre campos da linha\" matTooltip=\"Reduz o espa\u00E7o entre campos desta linha\">\n <mat-icon>remove</mat-icon>\n </button>\n <input class=\"gap-chip__input\" type=\"number\" min=\"0\" [ngModel]=\"row.rowGap ?? 0\"\n (ngModelChange)=\"updateRowGap('rowGap', $event)\" aria-label=\"Espa\u00E7o entre campos desta linha\" />\n <span class=\"gap-chip__suffix\">px</span>\n <button mat-icon-button class=\"gap-chip__btn\" (click)=\"adjustRowGapDelta('rowGap', 2)\"\n aria-label=\"Aumentar espa\u00E7o entre campos da linha\" matTooltip=\"Aumenta o espa\u00E7o entre campos desta linha\">\n <mat-icon>add</mat-icon>\n </button>\n <button mat-icon-button class=\"gap-chip__btn\" [matMenuTriggerFor]=\"rowGapMenu\"\n matTooltip=\"Mais op\u00E7\u00F5es para aplicar este espa\u00E7o\" aria-label=\"Mais op\u00E7\u00F5es de aplica\u00E7\u00E3o\">\n <mat-icon>done_all</mat-icon>\n </button>\n <mat-menu #rowGapMenu=\"matMenu\">\n <button mat-menu-item (click)=\"applyRowGapToAll()\">\n <mat-icon>done_all</mat-icon>\n <span>Aplicar em todas as linhas da se\u00E7\u00E3o</span>\n </button>\n <button mat-menu-item (click)=\"clearRowGap()\">\n <mat-icon>undo</mat-icon>\n <span>Voltar ao padr\u00E3o</span>\n </button>\n </mat-menu>\n </div>\n <div class=\"gap-pill\" aria-label=\"Resumo de espa\u00E7amentos\">\n Campos: {{ (row.rowGap ?? 'padr\u00E3o') }}px \u00B7 Colunas: {{ (row.gap ?? gapGlobal) }}px\n </div>\n <div class=\"row-actions-meta\">\n <button mat-icon-button [matMenuTriggerFor]=\"rowMenu\" (click)=\"openRowMenu()\" matTooltip=\"Op\u00E7\u00F5es da linha\">\n <mat-icon>more_vert</mat-icon>\n </button>\n <mat-menu #rowMenu=\"matMenu\" (closed)=\"onMenuClosed()\">\n <ng-container *ngIf=\"menuContext?.type === 'column'; else rowMenuContent\">\n <button mat-menu-item (click)=\"toggleHidden(menuContext!.columnIndex!)\">\n <mat-icon>{{ getHiddenFor(row.columns[menuContext!.columnIndex!]) ? 'visibility' : 'visibility_off'\n }}</mat-icon>\n <span>{{ getHiddenFor(row.columns[menuContext!.columnIndex!]) ? 'Mostrar neste breakpoint' : 'Ocultar neste\n breakpoint' }}</span>\n </button>\n <button mat-menu-item (click)=\"removeColumn(menuContext!.columnIndex!)\">\n <mat-icon color=\"warn\">delete</mat-icon>\n <span>Remover coluna</span>\n </button>\n </ng-container>\n <ng-template #rowMenuContent>\n <div mat-menu-item disabled>Presets de colunas</div>\n <button mat-menu-item (click)=\"applyPreset([12])\"><mat-icon>view_column</mat-icon><span>1/1</span></button>\n <button mat-menu-item (click)=\"applyPreset([6,6])\"><mat-icon>view_column</mat-icon><span>1/2 \u2014\n 1/2</span></button>\n <button mat-menu-item (click)=\"applyPreset([4,8])\"><mat-icon>view_column</mat-icon><span>1/3 \u2014\n 2/3</span></button>\n <button mat-menu-item (click)=\"applyPreset([8,4])\"><mat-icon>view_column</mat-icon><span>2/3 \u2014\n 1/3</span></button>\n <button mat-menu-item (click)=\"applyPreset([4,4,4])\"><mat-icon>view_column</mat-icon><span>1/3 \u2014 1/3 \u2014\n 1/3</span></button>\n <button mat-menu-item (click)=\"applyPreset([3,3,3,3])\"><mat-icon>view_column</mat-icon><span>1/4 \u2014 1/4 \u2014 1/4 \u2014\n 1/4</span></button>\n <button mat-menu-item (click)=\"addColumn()\"><mat-icon>add</mat-icon><span>Adicionar coluna</span></button>\n <button mat-menu-item (click)=\"removeRow()\"><mat-icon>delete</mat-icon><span>Remover linha</span></button>\n </ng-template>\n </mat-menu>\n </div>\n </div>\n <div class=\"span-warning\" *ngIf=\"getSpanTotal(previewBreakpoint) !== 12\">\n <mat-icon color=\"warn\">warning</mat-icon>\n Soma de spans = {{ getSpanTotal(previewBreakpoint) }} (ideal: 12)\n </div>\n</div>\n\n<div class=\"row-container\" [style.marginBottom.px]=\"!isLastRow ? (row.rowGap || null) : null\">\n <ng-container *ngIf=\"row.columns.length > 0; else emptyRow\">\n <div class=\"row grid-12\" cdkDropListGroup (click)=\"selectRow()\" [class.selected]=\"isRowSelected()\" tabindex=\"0\"\n role=\"button\" [attr.aria-label]=\"'Linha ' + (rowIndex + 1)\" [attr.aria-selected]=\"isRowSelected()\"\n [style.--pfx-grid-gap.px]=\"row.gap || null\" [style.--px-row-field-gap.px]=\"row.rowGap ?? null\">\n <div class=\"row-label\" aria-hidden=\"true\">Linha {{ rowIndex + 1 }}</div>\n <div *ngFor=\"let column of row.columns; let i = index\" class=\"column\" [id]=\"getColumnId(i)\" cdkDropList\n [cdkDropListData]=\"column.fields\" [cdkDropListConnectedTo]=\"connectedColumns(i)\"\n (cdkDropListDropped)=\"drop($event)\" (cdkDropListEntered)=\"onDropEnter(i)\" (cdkDropListExited)=\"onDropExit(i)\"\n (click)=\"selectColumn(i, $event)\" [class.drop-active]=\"activeDropIndex === i\"\n [class.selected]=\"isColumnSelected(i)\" [ngClass]=\"getColumnClassList(column)\"\n [style.grid-column]=\"'span ' + getSpanFor(column)\" tabindex=\"0\" role=\"button\"\n [attr.aria-label]=\"'Coluna ' + (i + 1) + ' de Linha ' + (rowIndex + 1) + '; Largura ' + getSpanFor(column)\"\n [attr.aria-selected]=\"isColumnSelected(i)\">\n <div class=\"column-header\">\n <div class=\"column-status-pill\" [matMenuTriggerFor]=\"columnSettingsMenu\"\n matTooltip=\"Clique para ajustar largura e offset\" [class.active]=\"isColumnSelected(i)\">\n <span class=\"status-bp\">{{ previewBreakpoint }}</span>\n <span class=\"status-divider\">\u00B7</span>\n <span class=\"status-span\">\n <mat-icon>view_column</mat-icon>\n {{ getSpanFor(column) }}/12\n </span>\n <span class=\"status-divider\">\u00B7</span>\n <span class=\"status-offset\">\n off {{ getOffsetFor(column) }}\n </span>\n <span class=\"status-hidden\" *ngIf=\"getHiddenFor(column)\">\n <mat-icon>visibility_off</mat-icon>\n </span>\n </div>\n\n <div class=\"column-actions\">\n <button mat-icon-button class=\"action-btn\" [matMenuTriggerFor]=\"columnOverflowMenu\"\n (click)=\"$event.stopPropagation()\" matTooltip=\"Op\u00E7\u00F5es da coluna\">\n <mat-icon>more_vert</mat-icon>\n </button>\n </div>\n </div>\n\n <mat-menu #columnSettingsMenu=\"matMenu\" class=\"column-settings-popover\">\n <div class=\"popover-content\" (click)=\"$event.stopPropagation()\">\n <div class=\"control-group\" *ngIf=\"getSuggestedSpan(i) as suggested\">\n <button mat-flat-button color=\"primary\" (click)=\"setSpan(i, suggested)\"\n matTooltip=\"Ajustar largura para completar 12 colunas\">\n <mat-icon>auto_fix_high</mat-icon>\n Ajustar para {{ suggested }} (Total 12)\n </button>\n </div>\n <div class=\"control-group\">\n <label>Largura ({{ previewBreakpoint }})</label>\n <div class=\"control-row\">\n <button mat-icon-button (click)=\"adjustSpan(i, -1)\"><mat-icon>remove</mat-icon></button>\n <span class=\"value-display\">{{ getSpanFor(column) }} / 12</span>\n <button mat-icon-button (click)=\"adjustSpan(i, 1)\"><mat-icon>add</mat-icon></button>\n </div>\n </div>\n <div class=\"control-group\">\n <label>Offset ({{ previewBreakpoint }})</label>\n <div class=\"control-row\">\n <button mat-icon-button (click)=\"adjustOffset(i, -1)\"><mat-icon>chevron_left</mat-icon></button>\n <span class=\"value-display\">{{ getOffsetFor(column) }}</span>\n <button mat-icon-button (click)=\"adjustOffset(i, 1)\"><mat-icon>chevron_right</mat-icon></button>\n </div>\n </div>\n <div class=\"control-group\">\n <button mat-stroked-button (click)=\"toggleHidden(i)\" [color]=\"getHiddenFor(column) ? 'warn' : ''\">\n <mat-icon>{{ getHiddenFor(column) ? 'visibility' : 'visibility_off' }}</mat-icon>\n {{ getHiddenFor(column) ? 'Mostrar' : 'Ocultar' }}\n </button>\n </div>\n </div>\n </mat-menu>\n\n <mat-menu #columnOverflowMenu=\"matMenu\">\n <button mat-menu-item (click)=\"openColumnConfig(i)\" matTooltip=\"Abrir painel de configura\u00E7\u00E3o completa\">\n <mat-icon>tune</mat-icon>\n <span>Configurar coluna</span>\n </button>\n <mat-divider></mat-divider>\n <button mat-menu-item (click)=\"moveColumn(i, -1)\" [disabled]=\"i === 0\"\n matTooltip=\"Mover coluna para a esquerda\">\n <mat-icon>arrow_back</mat-icon>\n <span>Mover para esquerda</span>\n </button>\n <button mat-menu-item (click)=\"moveColumn(i, 1)\" [disabled]=\"i === row.columns.length - 1\"\n matTooltip=\"Mover coluna para a direita\">\n <mat-icon>arrow_forward</mat-icon>\n <span>Mover para direita</span>\n </button>\n\n <button mat-menu-item (click)=\"clearColumn(i)\" [disabled]=\"column.fields.length === 0\"\n matTooltip=\"Remover todos os campos desta coluna\">\n <mat-icon>backspace</mat-icon>\n <span>Limpar conte\u00FAdo</span>\n </button>\n <mat-divider></mat-divider>\n <button mat-menu-item (click)=\"removeColumn(i)\" matTooltip=\"Excluir esta coluna\">\n <mat-icon color=\"warn\">delete</mat-icon>\n <span>Remover coluna</span>\n </button>\n </mat-menu>\n <div class=\"column-content\">\n <div class=\"hidden-overlay\" *ngIf=\"getHiddenFor(column)\">\n <mat-icon aria-hidden=\"true\">visibility_off</mat-icon>\n <span>Oculta em {{ previewBreakpoint }}</span>\n </div>\n <ng-container *ngIf=\"column.fields.length > 0; else emptyColumn\">\n <div *ngFor=\"let fieldName of column.fields\" (click)=\"selectField(fieldName, $event)\"\n [class.selected]=\"isFieldSelected(fieldName)\">\n <praxis-field-configurator [field]=\"getFieldByName(fieldName)\"></praxis-field-configurator>\n </div>\n </ng-container>\n <ng-template #emptyColumn>\n <div class=\"column-placeholder\">\n <span>Coluna vazia \u2014 solte um campo ou remova.</span>\n </div>\n </ng-template>\n </div>\n </div>\n </div>\n </ng-container>\n <ng-template #emptyRow>\n <div class=\"row-empty-placeholder\">\n <span>Linha vazia \u2014 crie colunas ou remova.</span>\n <div class=\"row-placeholder-actions\">\n <button mat-stroked-button (click)=\"addColumn()\" matTooltip=\"Adicionar coluna\">\n <mat-icon>add</mat-icon> Adicionar coluna\n </button>\n <button mat-stroked-button color=\"warn\" (click)=\"removeRow()\" matTooltip=\"Remover linha\">\n <mat-icon>delete</mat-icon> Remover linha\n </button>\n </div>\n </div>\n </ng-template>\n</div>\n", styles: [".row-meta{display:flex;align-items:center;gap:8px;margin-bottom:8px;flex-wrap:wrap}.bp-toggle{display:inline-flex;gap:4px;align-items:center}.bp-toggle__btn{min-width:34px;height:30px;line-height:30px;padding:0 8px;text-transform:uppercase}.bp-toggle__btn.active{background:var(--md-sys-color-primary-container);color:var(--md-sys-color-on-primary-container)}.gap-controls{display:flex;gap:8px;flex-wrap:wrap;align-items:center}.gap-chip{display:inline-flex;align-items:center;gap:2px;padding:0 4px;height:32px;border-radius:8px;border:1px solid var(--md-sys-color-outline-variant);background:var(--md-sys-color-surface-variant)}.gap-chip__btn{width:24px;height:24px;line-height:24px;min-width:0;padding:0;--mdc-icon-button-size: 24px;--mdc-icon-button-state-layer-size: 24px}.gap-chip .mat-mdc-button-touch-target{width:24px;height:24px}.gap-chip mat-icon{font-size:16px;width:16px;height:16px;line-height:16px}.gap-chip__input{width:42px;border:none;background:transparent;color:var(--md-sys-color-on-surface);font:var(--mdc-typography-body-medium, 600 13px/18px system-ui);text-align:center;outline:none;-moz-appearance:textfield}.gap-chip__input::-webkit-outer-spin-button,.gap-chip__input::-webkit-inner-spin-button{-webkit-appearance:none;margin:0}.gap-chip__suffix{color:var(--md-sys-color-on-surface-variant);font:var(--mdc-typography-label-medium, 500 12px/16px system-ui)}.gap-pill{display:inline-flex;align-items:center;gap:6px;padding:4px 8px;border-radius:12px;background:var(--md-sys-color-surface-variant);color:var(--md-sys-color-on-surface-variant);font:var(--mdc-typography-label-medium, 500 12px/16px system-ui)}.chip-title{font:var(--mdc-typography-label-medium, 600 12px/16px system-ui);color:var(--md-sys-color-on-surface-variant);text-transform:uppercase;letter-spacing:.03em}.span-warning{display:inline-flex;align-items:center;gap:6px;color:var(--md-sys-color-on-error);background:var(--md-sys-color-error-container);border:1px solid var(--md-sys-color-error);border-radius:6px;padding:4px 8px}.row-container{position:relative;display:flex;align-items:stretch}.row{display:flex;flex-grow:1;position:relative;padding-right:0;border-radius:6px;transition:box-shadow .2s ease;gap:var(--pfx-grid-gap, 12px)}.row:focus{outline:none;box-shadow:0 0 0 2px var(--md-sys-color-primary)}.row:focus-visible{box-shadow:0 0 0 2px var(--md-sys-color-primary)}.row.grid-12{display:grid;grid-template-columns:repeat(12,minmax(0,1fr));gap:var(--pfx-grid-gap, 16px)}.row.selected{box-shadow:0 0 0 2px var(--md-sys-color-primary)}.row-label{position:absolute;left:-4px;top:-10px;transform:translateY(-100%);background:var(--md-sys-color-surface-variant);color:var(--md-sys-color-on-surface-variant);border:1px solid var(--md-sys-color-outline-variant);border-radius:10px;padding:2px 6px;font-size:11px;opacity:0;transition:opacity .15s ease;pointer-events:none}.row:hover .row-label,.row.selected .row-label{opacity:1}.row-actions-meta{margin-left:auto}.column{position:relative;flex:1;display:flex;flex-direction:column;border:1px dashed var(--md-sys-color-outline-variant);margin:0;background:var(--md-sys-color-surface-container);transition:background-color .2s ease,border-color .2s ease;border-radius:8px;overflow:hidden}.column-header{display:flex;align-items:center;justify-content:space-between;padding:4px 8px;background:var(--md-sys-color-surface-variant);border-bottom:1px solid var(--md-sys-color-outline-variant);min-height:36px}.column-content{flex:1;display:grid;align-content:start;gap:var(--px-row-field-gap, 6px);padding:8px}.column-status-pill{display:inline-flex;align-items:center;gap:6px;padding:2px 8px;border-radius:12px;background:var(--md-sys-color-surface);border:1px solid var(--md-sys-color-outline-variant);cursor:pointer;transition:all .2s ease;-webkit-user-select:none;user-select:none}.column-status-pill:hover,.column-status-pill.active{background:var(--md-sys-color-surface-variant);border-color:var(--md-sys-color-outline)}.status-bp{font-weight:700;text-transform:uppercase;font-size:11px;color:var(--md-sys-color-primary)}.status-divider{color:var(--md-sys-color-outline-variant)}.status-span,.status-offset{display:inline-flex;align-items:center;gap:4px;font-size:12px;color:var(--md-sys-color-on-surface)}.status-span mat-icon{font-size:14px;width:14px;height:14px}.status-hidden{color:var(--md-sys-color-error);display:flex;align-items:center}.status-hidden mat-icon{font-size:14px;width:14px;height:14px}.column-actions{display:flex;align-items:center;opacity:0;transition:opacity .2s ease}.column:hover .column-actions,.column.selected .column-actions,.column-actions:focus-within{opacity:1}.action-btn{width:24px;height:24px;line-height:24px;padding:0}.action-btn mat-icon{font-size:18px;width:18px;height:18px;line-height:18px}.popover-content{padding:12px;display:flex;flex-direction:column;gap:12px;min-width:200px}.control-group{display:flex;flex-direction:column;gap:4px}.control-group label{font-size:11px;color:var(--md-sys-color-on-surface-variant);text-transform:uppercase;font-weight:600}.control-row{display:flex;align-items:center;justify-content:space-between;background:var(--md-sys-color-surface-container-high);border-radius:8px;padding:2px}.value-display{font-weight:600;font-size:13px}.row.grid-12 .column{flex:unset}.column>div{margin:0}.column:focus{outline:none;box-shadow:0 0 0 2px var(--md-sys-color-primary)}.column:focus-visible{box-shadow:0 0 0 2px var(--md-sys-color-primary)}.column.drop-active{border-color:var(--md-sys-color-primary);background:var(--md-sys-color-surface-variant)}.column.selected{border-color:var(--md-sys-color-primary);box-shadow:0 0 0 2px var(--md-sys-color-primary)}.column.cdk-drop-list-receiving{animation:columnHighlight .3s ease-in-out}@keyframes columnHighlight{0%{box-shadow:0 0 0 2px var(--md-sys-color-primary)}to{box-shadow:none}}.field-selected-highlight.selected .field-item,.selected>.field-item{border-color:var(--md-sys-color-primary)!important;box-shadow:0 0 0 2px var(--md-sys-color-primary)}.row-empty-placeholder{flex:1;border:1px dashed var(--md-sys-color-outline-variant);margin:0;padding:16px;text-align:center;color:var(--md-sys-color-on-surface-variant);background:var(--md-sys-color-surface-container)}.row-placeholder-actions{margin-top:8px;display:flex;gap:8px;justify-content:center}.hidden-overlay{position:absolute;inset:0;background:var(--md-sys-color-surface-container-low);border:1px dashed var(--md-sys-color-outline);display:flex;align-items:center;justify-content:center;gap:6px;color:var(--md-sys-color-on-surface-variant);z-index:2;pointer-events:none}\n"] }]
14132
+ ], providers: [providePraxisI18nConfig(LAYOUT_EDITOR_I18N_CONFIG)], template: "<div class=\"row-meta\" *ngIf=\"row\">\n <div class=\"bp-toggle\" role=\"group\" aria-label=\"Breakpoint de visualiza\u00E7\u00E3o\">\n <button\n *ngFor=\"let bp of breakpoints\"\n type=\"button\"\n mat-stroked-button\n class=\"bp-toggle__btn\"\n [class.active]=\"previewBreakpoint === bp\"\n (click)=\"previewBreakpoint = bp\"\n >\n {{ bp }}\n </button>\n </div>\n <div class=\"gap-controls\">\n <div class=\"gap-chip\" *ngIf=\"hasMultipleColumns()\" matTooltip=\"Gap entre colunas (px)\"\n aria-label=\"Gap entre colunas\">\n <span class=\"chip-title\">Colunas</span>\n <button mat-icon-button class=\"gap-chip__btn\" (click)=\"adjustRowGapDelta('gap', -2)\"\n aria-label=\"Reduzir gap de colunas\">\n <mat-icon>remove</mat-icon>\n </button>\n <input class=\"gap-chip__input\" type=\"number\" min=\"0\" [ngModel]=\"row.gap ?? gapGlobal\"\n (ngModelChange)=\"updateRowGap('gap', $event)\" aria-label=\"Valor do gap entre colunas\" />\n <span class=\"gap-chip__suffix\">px</span>\n <button mat-icon-button class=\"gap-chip__btn\" (click)=\"adjustRowGapDelta('gap', 2)\"\n aria-label=\"Aumentar gap de colunas\">\n <mat-icon>add</mat-icon>\n </button>\n </div>\n <div class=\"gap-chip\" matTooltip=\"Gap abaixo da linha (px)\" aria-label=\"Gap abaixo da linha\">\n <span class=\"chip-title\">Linha</span>\n <button mat-icon-button class=\"gap-chip__btn\" (click)=\"adjustRowGapDelta('rowGap', -2)\"\n aria-label=\"Reduzir espa\u00E7o entre campos da linha\" matTooltip=\"Reduz o espa\u00E7o entre campos desta linha\">\n <mat-icon>remove</mat-icon>\n </button>\n <input class=\"gap-chip__input\" type=\"number\" min=\"0\" [ngModel]=\"row.rowGap ?? 0\"\n (ngModelChange)=\"updateRowGap('rowGap', $event)\" aria-label=\"Espa\u00E7o entre campos desta linha\" />\n <span class=\"gap-chip__suffix\">px</span>\n <button mat-icon-button class=\"gap-chip__btn\" (click)=\"adjustRowGapDelta('rowGap', 2)\"\n aria-label=\"Aumentar espa\u00E7o entre campos da linha\" matTooltip=\"Aumenta o espa\u00E7o entre campos desta linha\">\n <mat-icon>add</mat-icon>\n </button>\n <button mat-icon-button class=\"gap-chip__btn\" [matMenuTriggerFor]=\"rowGapMenu\"\n matTooltip=\"Mais op\u00E7\u00F5es para aplicar este espa\u00E7o\" aria-label=\"Mais op\u00E7\u00F5es de aplica\u00E7\u00E3o\">\n <mat-icon>done_all</mat-icon>\n </button>\n <mat-menu #rowGapMenu=\"matMenu\">\n <button mat-menu-item (click)=\"applyRowGapToAll()\">\n <mat-icon>done_all</mat-icon>\n <span>Aplicar em todas as linhas da se\u00E7\u00E3o</span>\n </button>\n <button mat-menu-item (click)=\"clearRowGap()\">\n <mat-icon>undo</mat-icon>\n <span>Voltar ao padr\u00E3o</span>\n </button>\n </mat-menu>\n </div>\n <div class=\"gap-pill\" aria-label=\"Resumo de espa\u00E7amentos\">\n Campos: {{ (row.rowGap ?? 'padr\u00E3o') }}px \u00B7 Colunas: {{ (row.gap ?? gapGlobal) }}px\n </div>\n <div class=\"row-actions-meta\">\n <button mat-icon-button [matMenuTriggerFor]=\"rowMenu\" (click)=\"openRowMenu()\" matTooltip=\"Op\u00E7\u00F5es da linha\">\n <mat-icon>more_vert</mat-icon>\n </button>\n <mat-menu #rowMenu=\"matMenu\" (closed)=\"onMenuClosed()\">\n <ng-container *ngIf=\"menuContext?.type === 'column'; else rowMenuContent\">\n <button mat-menu-item (click)=\"toggleHidden(menuContext!.columnIndex!)\">\n <mat-icon>{{ getHiddenFor(row.columns[menuContext!.columnIndex!]) ? 'visibility' : 'visibility_off'\n }}</mat-icon>\n <span>{{ getHiddenFor(row.columns[menuContext!.columnIndex!]) ? 'Mostrar neste breakpoint' : 'Ocultar neste\n breakpoint' }}</span>\n </button>\n <button mat-menu-item (click)=\"removeColumn(menuContext!.columnIndex!)\">\n <mat-icon color=\"warn\">delete</mat-icon>\n <span>Remover coluna</span>\n </button>\n </ng-container>\n <ng-template #rowMenuContent>\n <div mat-menu-item disabled>Presets de colunas</div>\n <button mat-menu-item (click)=\"applyPreset([12])\"><mat-icon>view_column</mat-icon><span>1/1</span></button>\n <button mat-menu-item (click)=\"applyPreset([6,6])\"><mat-icon>view_column</mat-icon><span>1/2 \u2014\n 1/2</span></button>\n <button mat-menu-item (click)=\"applyPreset([4,8])\"><mat-icon>view_column</mat-icon><span>1/3 \u2014\n 2/3</span></button>\n <button mat-menu-item (click)=\"applyPreset([8,4])\"><mat-icon>view_column</mat-icon><span>2/3 \u2014\n 1/3</span></button>\n <button mat-menu-item (click)=\"applyPreset([4,4,4])\"><mat-icon>view_column</mat-icon><span>1/3 \u2014 1/3 \u2014\n 1/3</span></button>\n <button mat-menu-item (click)=\"applyPreset([3,3,3,3])\"><mat-icon>view_column</mat-icon><span>1/4 \u2014 1/4 \u2014 1/4 \u2014\n 1/4</span></button>\n <button mat-menu-item (click)=\"addColumn()\"><mat-icon>add</mat-icon><span>Adicionar coluna</span></button>\n <button mat-menu-item (click)=\"removeRow()\"><mat-icon>delete</mat-icon><span>Remover linha</span></button>\n </ng-template>\n </mat-menu>\n </div>\n </div>\n <div class=\"span-warning\" *ngIf=\"getSpanTotal(previewBreakpoint) !== 12\">\n <mat-icon color=\"warn\">warning</mat-icon>\n Soma de spans = {{ getSpanTotal(previewBreakpoint) }} (ideal: 12)\n </div>\n</div>\n\n<div class=\"row-container\" [style.marginBottom.px]=\"!isLastRow ? (row.rowGap || null) : null\">\n <ng-container *ngIf=\"row.columns.length > 0; else emptyRow\">\n <div class=\"row grid-12\" cdkDropListGroup (click)=\"selectRow()\" [class.selected]=\"isRowSelected()\" tabindex=\"0\"\n role=\"button\" [attr.aria-label]=\"'Linha ' + (rowIndex + 1)\" [attr.aria-selected]=\"isRowSelected()\"\n [style.--pfx-grid-gap.px]=\"row.gap || null\" [style.--px-row-field-gap.px]=\"row.rowGap ?? null\">\n <div class=\"row-label\" aria-hidden=\"true\">Linha {{ rowIndex + 1 }}</div>\n <div *ngFor=\"let column of row.columns; let i = index\" class=\"column\" [id]=\"getColumnId(i)\" cdkDropList\n [cdkDropListData]=\"column.fields\" [cdkDropListConnectedTo]=\"connectedColumns(i)\"\n (cdkDropListDropped)=\"drop($event)\" (cdkDropListEntered)=\"onDropEnter(i)\" (cdkDropListExited)=\"onDropExit(i)\"\n (click)=\"selectColumn(i, $event)\" [class.drop-active]=\"activeDropIndex === i\"\n [class.selected]=\"isColumnSelected(i)\" [ngClass]=\"getColumnClassList(column)\"\n [style.grid-column]=\"'span ' + getSpanFor(column)\" tabindex=\"0\" role=\"button\"\n [attr.aria-label]=\"'Coluna ' + (i + 1) + ' de Linha ' + (rowIndex + 1) + '; Largura ' + getSpanFor(column)\"\n [attr.aria-selected]=\"isColumnSelected(i)\">\n <div class=\"column-header\">\n <div class=\"column-status-pill\" [matMenuTriggerFor]=\"columnSettingsMenu\"\n matTooltip=\"Clique para ajustar largura e offset\" [class.active]=\"isColumnSelected(i)\">\n <span class=\"status-bp\">{{ previewBreakpoint }}</span>\n <span class=\"status-divider\">\u00B7</span>\n <span class=\"status-span\">\n <mat-icon>view_column</mat-icon>\n {{ getSpanFor(column) }}/12\n </span>\n <span class=\"status-divider\">\u00B7</span>\n <span class=\"status-offset\">\n off {{ getOffsetFor(column) }}\n </span>\n <span class=\"status-hidden\" *ngIf=\"getHiddenFor(column)\">\n <mat-icon>visibility_off</mat-icon>\n </span>\n </div>\n\n <div class=\"column-actions\">\n <button mat-icon-button class=\"action-btn\" [matMenuTriggerFor]=\"columnOverflowMenu\"\n (click)=\"$event.stopPropagation()\" matTooltip=\"Op\u00E7\u00F5es da coluna\">\n <mat-icon>more_vert</mat-icon>\n </button>\n </div>\n </div>\n\n <mat-menu #columnSettingsMenu=\"matMenu\" class=\"column-settings-popover\">\n <div class=\"popover-content\" (click)=\"$event.stopPropagation()\">\n <div class=\"control-group\" *ngIf=\"getSuggestedSpan(i) as suggested\">\n <button mat-flat-button color=\"primary\" (click)=\"setSpan(i, suggested)\"\n matTooltip=\"Ajustar largura para completar 12 colunas\">\n <mat-icon>auto_fix_high</mat-icon>\n Ajustar para {{ suggested }} (Total 12)\n </button>\n </div>\n <div class=\"control-group\">\n <label>Largura ({{ previewBreakpoint }})</label>\n <div class=\"control-row\">\n <button mat-icon-button (click)=\"adjustSpan(i, -1)\"><mat-icon>remove</mat-icon></button>\n <span class=\"value-display\">{{ getSpanFor(column) }} / 12</span>\n <button mat-icon-button (click)=\"adjustSpan(i, 1)\"><mat-icon>add</mat-icon></button>\n </div>\n </div>\n <div class=\"control-group\">\n <label>Offset ({{ previewBreakpoint }})</label>\n <div class=\"control-row\">\n <button mat-icon-button (click)=\"adjustOffset(i, -1)\"><mat-icon>chevron_left</mat-icon></button>\n <span class=\"value-display\">{{ getOffsetFor(column) }}</span>\n <button mat-icon-button (click)=\"adjustOffset(i, 1)\"><mat-icon>chevron_right</mat-icon></button>\n </div>\n </div>\n <div class=\"control-group\">\n <button mat-stroked-button (click)=\"toggleHidden(i)\" [color]=\"getHiddenFor(column) ? 'warn' : ''\">\n <mat-icon>{{ getHiddenFor(column) ? 'visibility' : 'visibility_off' }}</mat-icon>\n {{ getHiddenFor(column) ? 'Mostrar' : 'Ocultar' }}\n </button>\n </div>\n </div>\n </mat-menu>\n\n <mat-menu #columnOverflowMenu=\"matMenu\">\n <button mat-menu-item (click)=\"openColumnConfig(i)\" matTooltip=\"Abrir painel de configura\u00E7\u00E3o completa\">\n <mat-icon>tune</mat-icon>\n <span>Configurar coluna</span>\n </button>\n <button mat-menu-item [matMenuTriggerFor]=\"apiFieldMenu\" [matTooltip]=\"t('apiFields.addTooltip')\">\n <mat-icon>input</mat-icon>\n <span>{{ t('apiFields.addAction') }}</span>\n </button>\n <mat-menu #apiFieldMenu=\"matMenu\">\n <button\n mat-menu-item\n *ngFor=\"let field of availableFields\"\n (click)=\"addApiFieldToColumn(i, field.name)\"\n >\n <mat-icon>short_text</mat-icon>\n <span>{{ getFieldLabel(field) }}</span>\n </button>\n <button mat-menu-item disabled *ngIf=\"!availableFields.length\">\n <span>{{ t('apiFields.empty') }}</span>\n </button>\n </mat-menu>\n <button mat-menu-item [matMenuTriggerFor]=\"visualBlockPresetMenu\" [matTooltip]=\"t('visualBlock.addTooltip')\">\n <mat-icon>notes</mat-icon>\n <span>{{ t('visualBlock.addAction') }}</span>\n </button>\n <mat-menu #visualBlockPresetMenu=\"matMenu\">\n <button\n mat-menu-item\n *ngFor=\"let preset of visualBlockPresets\"\n (click)=\"addVisualBlockToColumn(i, preset.id)\"\n >\n <mat-icon>{{ preset.icon }}</mat-icon>\n <span>{{ t(preset.labelKey) }}</span>\n </button>\n </mat-menu>\n <mat-divider></mat-divider>\n <button mat-menu-item (click)=\"moveColumn(i, -1)\" [disabled]=\"i === 0\"\n matTooltip=\"Mover coluna para a esquerda\">\n <mat-icon>arrow_back</mat-icon>\n <span>Mover para esquerda</span>\n </button>\n <button mat-menu-item (click)=\"moveColumn(i, 1)\" [disabled]=\"i === row.columns.length - 1\"\n matTooltip=\"Mover coluna para a direita\">\n <mat-icon>arrow_forward</mat-icon>\n <span>Mover para direita</span>\n </button>\n\n <button mat-menu-item (click)=\"clearColumn(i)\" [disabled]=\"!hasColumnContent(column)\"\n matTooltip=\"Remover todo o conte\u00C3\u00BAdo desta coluna\">\n <mat-icon>backspace</mat-icon>\n <span>Limpar conte\u00FAdo</span>\n </button>\n <mat-divider></mat-divider>\n <button mat-menu-item (click)=\"removeColumn(i)\" matTooltip=\"Excluir esta coluna\">\n <mat-icon color=\"warn\">delete</mat-icon>\n <span>Remover coluna</span>\n </button>\n </mat-menu>\n <div class=\"column-content\">\n <div class=\"hidden-overlay\" *ngIf=\"getHiddenFor(column)\">\n <mat-icon aria-hidden=\"true\">visibility_off</mat-icon>\n <span>Oculta em {{ previewBreakpoint }}</span>\n </div>\n <ng-container *ngIf=\"hasColumnContent(column); else emptyColumn\">\n <ng-container *ngFor=\"let item of getColumnLayoutItems(column); let itemIndex = index\">\n <div *ngIf=\"item.kind === 'field'; else visualBlockItem\" (click)=\"selectField(item.fieldName, $event)\"\n [class.selected]=\"isFieldSelected(item.fieldName)\">\n <praxis-field-configurator [field]=\"getFieldByName(item.fieldName)\"></praxis-field-configurator>\n </div>\n <ng-template #visualBlockItem>\n <div\n class=\"visual-block-preview\"\n *ngIf=\"item.kind === 'richContent'\"\n role=\"button\"\n tabindex=\"0\"\n [class.selected]=\"selected?.type === 'visualBlock' && selected?.itemId === item.id\"\n (click)=\"selectVisualBlock(i, item, $event)\"\n (dblclick)=\"openVisualBlockEditor(i, item, $event)\"\n >\n <mat-icon aria-hidden=\"true\">notes</mat-icon>\n <span>{{ getVisualBlockLabel(item) }}</span>\n <span class=\"visual-block-preview__actions\">\n <button\n mat-icon-button\n class=\"visual-block-preview__action\"\n type=\"button\"\n [matTooltip]=\"t('visualBlock.moveUp')\"\n [attr.aria-label]=\"t('visualBlock.moveUp')\"\n [disabled]=\"itemIndex === 0\"\n (click)=\"moveVisualBlockItem(i, item, -1, $event)\"\n >\n <mat-icon>arrow_upward</mat-icon>\n </button>\n <button\n mat-icon-button\n class=\"visual-block-preview__action\"\n type=\"button\"\n [matTooltip]=\"t('visualBlock.moveDown')\"\n [attr.aria-label]=\"t('visualBlock.moveDown')\"\n [disabled]=\"itemIndex === getColumnLayoutItems(column).length - 1\"\n (click)=\"moveVisualBlockItem(i, item, 1, $event)\"\n >\n <mat-icon>arrow_downward</mat-icon>\n </button>\n <button\n mat-icon-button\n class=\"visual-block-preview__action\"\n type=\"button\"\n [matTooltip]=\"t('visualBlock.movePreviousColumn')\"\n [attr.aria-label]=\"t('visualBlock.movePreviousColumn')\"\n [disabled]=\"!canMoveVisualBlockToColumn(i, -1)\"\n (click)=\"moveVisualBlockToAdjacentColumn(i, item, -1, $event)\"\n >\n <mat-icon>arrow_back</mat-icon>\n </button>\n <button\n mat-icon-button\n class=\"visual-block-preview__action\"\n type=\"button\"\n [matTooltip]=\"t('visualBlock.moveNextColumn')\"\n [attr.aria-label]=\"t('visualBlock.moveNextColumn')\"\n [disabled]=\"!canMoveVisualBlockToColumn(i, 1)\"\n (click)=\"moveVisualBlockToAdjacentColumn(i, item, 1, $event)\"\n >\n <mat-icon>arrow_forward</mat-icon>\n </button>\n <button\n mat-icon-button\n class=\"visual-block-preview__action\"\n type=\"button\"\n [matTooltip]=\"t('visualBlock.editAction')\"\n [attr.aria-label]=\"t('visualBlock.editAction')\"\n (click)=\"openVisualBlockEditor(i, item, $event)\"\n >\n <mat-icon>edit</mat-icon>\n </button>\n <button\n mat-icon-button\n class=\"visual-block-preview__action\"\n type=\"button\"\n color=\"warn\"\n [matTooltip]=\"t('visualBlock.removeAction')\"\n [attr.aria-label]=\"t('visualBlock.removeAction')\"\n (click)=\"removeVisualBlockItem(i, item, $event)\"\n >\n <mat-icon>delete</mat-icon>\n </button>\n </span>\n </div>\n </ng-template>\n </ng-container>\n </ng-container>\n <ng-template #emptyColumn>\n <div class=\"column-placeholder\">\n <span>Coluna vazia \u2014 solte um campo ou remova.</span>\n </div>\n </ng-template>\n </div>\n </div>\n </div>\n </ng-container>\n <ng-template #emptyRow>\n <div class=\"row-empty-placeholder\">\n <span>Linha vazia \u2014 crie colunas ou remova.</span>\n <div class=\"row-placeholder-actions\">\n <button mat-stroked-button (click)=\"addColumn()\" matTooltip=\"Adicionar coluna\">\n <mat-icon>add</mat-icon> Adicionar coluna\n </button>\n <button mat-stroked-button color=\"warn\" (click)=\"removeRow()\" matTooltip=\"Remover linha\">\n <mat-icon>delete</mat-icon> Remover linha\n </button>\n </div>\n </div>\n </ng-template>\n</div>\n", styles: [".row-meta{display:flex;align-items:center;gap:8px;margin-bottom:8px;flex-wrap:wrap}.bp-toggle{display:inline-flex;gap:4px;align-items:center}.bp-toggle__btn{min-width:34px;height:30px;line-height:30px;padding:0 8px;text-transform:uppercase}.bp-toggle__btn.active{background:var(--md-sys-color-primary-container);color:var(--md-sys-color-on-primary-container)}.gap-controls{display:flex;gap:8px;flex-wrap:wrap;align-items:center}.gap-chip{display:inline-flex;align-items:center;gap:2px;padding:0 4px;height:32px;border-radius:8px;border:1px solid var(--md-sys-color-outline-variant);background:var(--md-sys-color-surface-variant)}.gap-chip__btn{width:24px;height:24px;line-height:24px;min-width:0;padding:0;--mdc-icon-button-size: 24px;--mdc-icon-button-state-layer-size: 24px}.gap-chip .mat-mdc-button-touch-target{width:24px;height:24px}.gap-chip mat-icon{font-size:16px;width:16px;height:16px;line-height:16px}.gap-chip__input{width:42px;border:none;background:transparent;color:var(--md-sys-color-on-surface);font:var(--mdc-typography-body-medium, 600 13px/18px system-ui);text-align:center;outline:none;-moz-appearance:textfield}.gap-chip__input::-webkit-outer-spin-button,.gap-chip__input::-webkit-inner-spin-button{-webkit-appearance:none;margin:0}.gap-chip__suffix{color:var(--md-sys-color-on-surface-variant);font:var(--mdc-typography-label-medium, 500 12px/16px system-ui)}.gap-pill{display:inline-flex;align-items:center;gap:6px;padding:4px 8px;border-radius:12px;background:var(--md-sys-color-surface-variant);color:var(--md-sys-color-on-surface-variant);font:var(--mdc-typography-label-medium, 500 12px/16px system-ui)}.chip-title{font:var(--mdc-typography-label-medium, 600 12px/16px system-ui);color:var(--md-sys-color-on-surface-variant);text-transform:uppercase;letter-spacing:.03em}.span-warning{display:inline-flex;align-items:center;gap:6px;color:var(--md-sys-color-on-error);background:var(--md-sys-color-error-container);border:1px solid var(--md-sys-color-error);border-radius:6px;padding:4px 8px}.row-container{position:relative;display:flex;align-items:stretch}.row{display:flex;flex-grow:1;position:relative;padding-right:0;border-radius:6px;transition:box-shadow .2s ease;gap:var(--pfx-grid-gap, 12px)}.row:focus{outline:none;box-shadow:0 0 0 2px var(--md-sys-color-primary)}.row:focus-visible{box-shadow:0 0 0 2px var(--md-sys-color-primary)}.row.grid-12{display:grid;grid-template-columns:repeat(12,minmax(0,1fr));gap:var(--pfx-grid-gap, 16px)}.row.selected{box-shadow:0 0 0 2px var(--md-sys-color-primary)}.row-label{position:absolute;left:-4px;top:-10px;transform:translateY(-100%);background:var(--md-sys-color-surface-variant);color:var(--md-sys-color-on-surface-variant);border:1px solid var(--md-sys-color-outline-variant);border-radius:10px;padding:2px 6px;font-size:11px;opacity:0;transition:opacity .15s ease;pointer-events:none}.row:hover .row-label,.row.selected .row-label{opacity:1}.row-actions-meta{margin-left:auto}.column{position:relative;flex:1;display:flex;flex-direction:column;border:1px dashed var(--md-sys-color-outline-variant);margin:0;background:var(--md-sys-color-surface-container);transition:background-color .2s ease,border-color .2s ease;border-radius:8px;overflow:hidden}.column-header{display:flex;align-items:center;justify-content:space-between;padding:4px 8px;background:var(--md-sys-color-surface-variant);border-bottom:1px solid var(--md-sys-color-outline-variant);min-height:36px}.column-content{flex:1;display:grid;align-content:start;gap:var(--px-row-field-gap, 6px);padding:8px}.column-status-pill{display:inline-flex;align-items:center;gap:6px;padding:2px 8px;border-radius:12px;background:var(--md-sys-color-surface);border:1px solid var(--md-sys-color-outline-variant);cursor:pointer;transition:all .2s ease;-webkit-user-select:none;user-select:none}.column-status-pill:hover,.column-status-pill.active{background:var(--md-sys-color-surface-variant);border-color:var(--md-sys-color-outline)}.status-bp{font-weight:700;text-transform:uppercase;font-size:11px;color:var(--md-sys-color-primary)}.status-divider{color:var(--md-sys-color-outline-variant)}.status-span,.status-offset{display:inline-flex;align-items:center;gap:4px;font-size:12px;color:var(--md-sys-color-on-surface)}.status-span mat-icon{font-size:14px;width:14px;height:14px}.status-hidden{color:var(--md-sys-color-error);display:flex;align-items:center}.status-hidden mat-icon{font-size:14px;width:14px;height:14px}.column-actions{display:flex;align-items:center;opacity:0;transition:opacity .2s ease}.column:hover .column-actions,.column.selected .column-actions,.column-actions:focus-within{opacity:1}.action-btn{width:24px;height:24px;line-height:24px;padding:0}.action-btn mat-icon{font-size:18px;width:18px;height:18px;line-height:18px}.popover-content{padding:12px;display:flex;flex-direction:column;gap:12px;min-width:200px}.control-group{display:flex;flex-direction:column;gap:4px}.control-group label{font-size:11px;color:var(--md-sys-color-on-surface-variant);text-transform:uppercase;font-weight:600}.control-row{display:flex;align-items:center;justify-content:space-between;background:var(--md-sys-color-surface-container-high);border-radius:8px;padding:2px}.value-display{font-weight:600;font-size:13px}.row.grid-12 .column{flex:unset}.column>div{margin:0}.column:focus{outline:none;box-shadow:0 0 0 2px var(--md-sys-color-primary)}.column:focus-visible{box-shadow:0 0 0 2px var(--md-sys-color-primary)}.column.drop-active{border-color:var(--md-sys-color-primary);background:var(--md-sys-color-surface-variant)}.column.selected{border-color:var(--md-sys-color-primary);box-shadow:0 0 0 2px var(--md-sys-color-primary)}.column.cdk-drop-list-receiving{animation:columnHighlight .3s ease-in-out}@keyframes columnHighlight{0%{box-shadow:0 0 0 2px var(--md-sys-color-primary)}to{box-shadow:none}}.field-selected-highlight.selected .field-item,.selected>.field-item{border-color:var(--md-sys-color-primary)!important;box-shadow:0 0 0 2px var(--md-sys-color-primary)}.visual-block-preview{display:flex;align-items:center;gap:8px;min-height:36px;padding:8px;border:1px dashed var(--md-sys-color-outline-variant);border-radius:6px;background:var(--md-sys-color-surface);color:var(--md-sys-color-on-surface-variant);font-size:13px;cursor:pointer}.visual-block-preview.selected{border-color:var(--md-sys-color-primary);box-shadow:0 0 0 2px var(--md-sys-color-primary)}.visual-block-preview mat-icon{font-size:18px;width:18px;height:18px}.visual-block-preview__actions{margin-left:auto;display:inline-flex;align-items:center;gap:2px}.visual-block-preview__action{width:28px;height:28px;--mdc-icon-button-size: 28px;--mdc-icon-button-state-layer-size: 28px}.row-empty-placeholder{flex:1;border:1px dashed var(--md-sys-color-outline-variant);margin:0;padding:16px;text-align:center;color:var(--md-sys-color-on-surface-variant);background:var(--md-sys-color-surface-container)}.row-placeholder-actions{margin-top:8px;display:flex;gap:8px;justify-content:center}.hidden-overlay{position:absolute;inset:0;background:var(--md-sys-color-surface-container-low);border:1px dashed var(--md-sys-color-outline);display:flex;align-items:center;justify-content:center;gap:6px;color:var(--md-sys-color-on-surface-variant);z-index:2;pointer-events:none}\n"] }]
13520
14133
  }], propDecorators: { row: [{
13521
14134
  type: Input
13522
14135
  }], fieldMetadata: [{
13523
14136
  type: Input
14137
+ }], availableFields: [{
14138
+ type: Input
13524
14139
  }], sectionIndex: [{
13525
14140
  type: Input
13526
14141
  }], rowIndex: [{
@@ -13543,6 +14158,18 @@ i0.ɵɵngDeclareClassMetadata({ minVersion: "12.0.0", version: "20.3.17", ngImpo
13543
14158
  type: Output
13544
14159
  }], fieldDrop: [{
13545
14160
  type: Output
14161
+ }], addVisualBlock: [{
14162
+ type: Output
14163
+ }], addApiField: [{
14164
+ type: Output
14165
+ }], editVisualBlock: [{
14166
+ type: Output
14167
+ }], moveVisualBlock: [{
14168
+ type: Output
14169
+ }], moveVisualBlockToColumn: [{
14170
+ type: Output
14171
+ }], removeVisualBlock: [{
14172
+ type: Output
13546
14173
  }], select: [{
13547
14174
  type: Output
13548
14175
  }] } });
@@ -13812,6 +14439,7 @@ class SectionConfiguratorComponent {
13812
14439
  sectionIndex;
13813
14440
  allSections = [];
13814
14441
  fieldMetadata = [];
14442
+ availableFields = [];
13815
14443
  selected = null;
13816
14444
  availableFieldsListId = 'available-fields-list';
13817
14445
  columnDropListIds = [];
@@ -13821,6 +14449,12 @@ class SectionConfiguratorComponent {
13821
14449
  remove = new EventEmitter();
13822
14450
  select = new EventEmitter();
13823
14451
  fieldDrop = new EventEmitter();
14452
+ addVisualBlock = new EventEmitter();
14453
+ addApiField = new EventEmitter();
14454
+ editVisualBlock = new EventEmitter();
14455
+ moveVisualBlock = new EventEmitter();
14456
+ moveVisualBlockToColumn = new EventEmitter();
14457
+ removeVisualBlock = new EventEmitter();
13824
14458
  isHovered = false;
13825
14459
  isCollapsed = false;
13826
14460
  constructor(dialog, presetRegistry, settingsPanel) {
@@ -13895,6 +14529,56 @@ class SectionConfiguratorComponent {
13895
14529
  onFieldDrop(event, rowIndex) {
13896
14530
  this.fieldDrop.emit({ event, sectionIndex: this.sectionIndex, rowIndex });
13897
14531
  }
14532
+ onAddVisualBlock(event) {
14533
+ this.addVisualBlock.emit({
14534
+ sectionIndex: this.sectionIndex,
14535
+ rowIndex: event.rowIndex,
14536
+ columnIndex: event.columnIndex,
14537
+ presetId: event.presetId,
14538
+ });
14539
+ }
14540
+ onAddApiField(event) {
14541
+ this.addApiField.emit({
14542
+ sectionIndex: this.sectionIndex,
14543
+ rowIndex: event.rowIndex,
14544
+ columnIndex: event.columnIndex,
14545
+ fieldName: event.fieldName,
14546
+ });
14547
+ }
14548
+ onEditVisualBlock(event) {
14549
+ this.editVisualBlock.emit({
14550
+ sectionIndex: this.sectionIndex,
14551
+ rowIndex: event.rowIndex,
14552
+ columnIndex: event.columnIndex,
14553
+ itemId: event.itemId,
14554
+ });
14555
+ }
14556
+ onMoveVisualBlock(event) {
14557
+ this.moveVisualBlock.emit({
14558
+ sectionIndex: this.sectionIndex,
14559
+ rowIndex: event.rowIndex,
14560
+ columnIndex: event.columnIndex,
14561
+ itemId: event.itemId,
14562
+ direction: event.direction,
14563
+ });
14564
+ }
14565
+ onMoveVisualBlockToColumn(event) {
14566
+ this.moveVisualBlockToColumn.emit({
14567
+ sectionIndex: this.sectionIndex,
14568
+ rowIndex: event.rowIndex,
14569
+ columnIndex: event.columnIndex,
14570
+ targetColumnIndex: event.targetColumnIndex,
14571
+ itemId: event.itemId,
14572
+ });
14573
+ }
14574
+ onRemoveVisualBlock(event) {
14575
+ this.removeVisualBlock.emit({
14576
+ sectionIndex: this.sectionIndex,
14577
+ rowIndex: event.rowIndex,
14578
+ columnIndex: event.columnIndex,
14579
+ itemId: event.itemId,
14580
+ });
14581
+ }
13898
14582
  onRemoveSection() {
13899
14583
  this.remove.emit();
13900
14584
  }
@@ -14050,7 +14734,7 @@ class SectionConfiguratorComponent {
14050
14734
  this.applyStyleToAll.emit(patch);
14051
14735
  }
14052
14736
  static ɵfac = i0.ɵɵngDeclareFactory({ minVersion: "12.0.0", version: "20.3.17", ngImport: i0, type: SectionConfiguratorComponent, deps: [{ token: i2$1.MatDialog }, { token: SectionPresetRegistry }, { token: i7.SettingsPanelService }], target: i0.ɵɵFactoryTarget.Component });
14053
- static ɵcmp = i0.ɵɵngDeclareComponent({ minVersion: "17.0.0", version: "20.3.17", type: SectionConfiguratorComponent, isStandalone: true, selector: "praxis-section-configurator", inputs: { section: "section", sectionIndex: "sectionIndex", allSections: "allSections", fieldMetadata: "fieldMetadata", selected: "selected", availableFieldsListId: "availableFieldsListId", columnDropListIds: "columnDropListIds", gapGlobal: "gapGlobal" }, outputs: { sectionChange: "sectionChange", applyStyleToAll: "applyStyleToAll", remove: "remove", select: "select", fieldDrop: "fieldDrop" }, ngImport: i0, template: "<mat-card\n class=\"section-card\"\n cdkDrag\n (mouseenter)=\"onMouseEnter()\"\n (mouseleave)=\"onMouseLeave()\"\n [class.hovered]=\"isHovered\"\n [class.selected]=\"isThisSectionSelected()\"\n [class.collapsed]=\"isCollapsed\"\n (click)=\"onSelectSection()\"\n tabindex=\"0\"\n role=\"button\"\n [attr.aria-label]=\"'Se\u00E7\u00E3o ' + (sectionIndex + 1)\"\n [attr.aria-selected]=\"isThisSectionSelected()\"\n>\n <mat-card-header class=\"section-header\">\n <mat-card-title class=\"title-wrapper\">\n <div class=\"section-heading\">\n @let headerPreview = getSectionHeaderPreview();\n @let headerAvatarSize = getSectionHeaderAvatarSize();\n @if (headerPreview.kind === 'icon') {\n <mat-icon class=\"section-heading__icon\" aria-hidden=\"true\" [praxisIcon]=\"headerPreview.icon\"></mat-icon>\n }\n @if (headerPreview.kind === 'initials') {\n <span class=\"section-heading__avatar section-heading__avatar--text\" [class.size-sm]=\"headerAvatarSize === 'sm'\"\n [class.size-md]=\"headerAvatarSize === 'md'\" [class.size-lg]=\"headerAvatarSize === 'lg'\"\n [matTooltip]=\"headerPreview.tooltip || ''\" [matTooltipDisabled]=\"!headerPreview.tooltip\">\n {{ headerPreview.text }}\n </span>\n }\n @if (headerPreview.kind === 'placeholder') {\n <span class=\"section-heading__avatar section-heading__avatar--placeholder\" [class.size-sm]=\"headerAvatarSize === 'sm'\"\n [class.size-md]=\"headerAvatarSize === 'md'\" [class.size-lg]=\"headerAvatarSize === 'lg'\"\n [matTooltip]=\"headerPreview.tooltip || ''\" [matTooltipDisabled]=\"!headerPreview.tooltip\">\n @if (headerPreview.icon) {\n <mat-icon aria-hidden=\"true\" [praxisIcon]=\"headerPreview.icon\"></mat-icon>\n }\n </span>\n }\n <div class=\"section-heading__text\">\n <span class=\"section-name\">{{ section.title || 'Sem t\u00EDtulo' }}</span>\n <span class=\"section-desc\" *ngIf=\"section.description\">{{ section.description }}</span>\n </div>\n </div>\n <button\n mat-icon-button\n type=\"button\"\n color=\"primary\"\n class=\"section-editor-trigger\"\n (click)=\"openAdvancedEditor($event)\"\n matTooltip=\"Para editar o t\u00EDtulo, use o editor completo da se\u00E7\u00E3o\"\n aria-label=\"Abrir editor da se\u00E7\u00E3o\"\n >\n <mat-icon>open_in_new</mat-icon>\n </button>\n </mat-card-title>\n <div class=\"section-header-actions\">\n <button\n mat-icon-button\n class=\"section-collapse-btn\"\n type=\"button\"\n (click)=\"toggleCollapsed($event)\"\n [attr.aria-expanded]=\"!isCollapsed\"\n [attr.aria-label]=\"isCollapsed ? 'Expandir se\u00E7\u00E3o' : 'Colapsar se\u00E7\u00E3o'\"\n [matTooltip]=\"isCollapsed ? 'Expandir se\u00E7\u00E3o' : 'Colapsar se\u00E7\u00E3o'\"\n >\n <mat-icon>{{ isCollapsed ? 'unfold_more' : 'unfold_less' }}</mat-icon>\n </button>\n <button\n mat-icon-button\n class=\"section-menu-btn\"\n [matMenuTriggerFor]=\"sectionMenu\"\n aria-label=\"Mais a\u00E7\u00F5es da se\u00E7\u00E3o\"\n matTooltip=\"Mais a\u00E7\u00F5es\"\n >\n <mat-icon [praxisIcon]=\"'more_vert'\"></mat-icon>\n </button>\n </div>\n <mat-menu #sectionMenu=\"matMenu\">\n <button mat-menu-item (click)=\"openSectionPresets()\">\n <mat-icon [praxisIcon]=\"'view_quilt'\"></mat-icon>\n <span>Presets de se\u00E7\u00E3o\u2026</span>\n </button>\n <button mat-menu-item (click)=\"applyCurrentStyleToAll()\">\n <mat-icon [praxisIcon]=\"'format_paint'\"></mat-icon>\n <span>Aplicar estilo desta se\u00E7\u00E3o a todas</span>\n </button>\n <mat-divider></mat-divider>\n <button mat-menu-item *ngIf=\"section.description == null\" (click)=\"section.description = ''; onSectionUpdated()\">\n <mat-icon [praxisIcon]=\"'note_add'\"></mat-icon>\n <span>Adicionar descri\u00E7\u00E3o</span>\n </button>\n <button mat-menu-item *ngIf=\"section.description != null\" (click)=\"section.description = undefined; onSectionUpdated()\">\n <mat-icon [praxisIcon]=\"'backspace'\"></mat-icon>\n <span>Remover descri\u00E7\u00E3o</span>\n </button>\n <mat-divider></mat-divider>\n <button mat-menu-item (click)=\"onRemoveSection()\">\n <mat-icon [praxisIcon]=\"'delete'\"></mat-icon>\n <span>Remover se\u00E7\u00E3o</span>\n </button>\n </mat-menu>\n </mat-card-header>\n <mat-card-content [attr.aria-hidden]=\"isCollapsed\">\n <ng-container *ngIf=\"isThisSectionSelected(); else linhasTitle\">\n <div class=\"section-breadcrumbs\" (click)=\"$event.stopPropagation()\">\n <button\n type=\"button\"\n class=\"crumb as-button\"\n data-crumb=\"layout\"\n [attr.aria-label]=\"'Voltar ao Layout'\"\n disabled\n >\n Layout\n </button>\n <span class=\"sep\">\u203A</span>\n <button\n type=\"button\"\n class=\"crumb as-button crumb-section\"\n data-crumb=\"section\"\n (click)=\"onSelectSectionFromBreadcrumb($event)\"\n [attr.aria-label]=\"'Selecionar Se\u00E7\u00E3o ' + (sectionIndex + 1)\"\n >\n Se\u00E7\u00E3o {{ sectionIndex + 1 }}\n </button>\n <ng-container *ngIf=\"selected?.rowIndex != null\">\n <span class=\"sep\">\u203A</span>\n <button\n type=\"button\"\n class=\"crumb as-button crumb-row\"\n data-crumb=\"row\"\n (click)=\"onSelectRowFromBreadcrumb($event)\"\n [attr.aria-label]=\"'Selecionar Linha ' + (selected!.rowIndex! + 1)\"\n >\n Linha {{ selected!.rowIndex! + 1 }}\n </button>\n </ng-container>\n <ng-container *ngIf=\"selected?.columnIndex != null\">\n <span class=\"sep\">\u203A</span>\n <button\n type=\"button\"\n class=\"crumb as-button crumb-column\"\n data-crumb=\"column\"\n (click)=\"onSelectColumnFromBreadcrumb($event)\"\n [attr.aria-label]=\"'Selecionar Coluna ' + (selected!.columnIndex! + 1)\"\n >\n Coluna {{ selected!.columnIndex! + 1 }}\n </button>\n </ng-container>\n <ng-container *ngIf=\"selected?.fieldName\">\n <span class=\"sep\">\u203A</span>\n <span class=\"crumb active\">{{ selected!.fieldName }}</span>\n </ng-container>\n <button\n *ngIf=\"selected\"\n type=\"button\"\n class=\"crumb as-button crumb-clear\"\n data-crumb=\"clear\"\n (click)=\"onClearSelectionFromBreadcrumb($event)\"\n [attr.aria-label]=\"'Limpar sele\u00E7\u00E3o'\"\n >\n Limpar\n </button>\n </div>\n </ng-container>\n <ng-template #linhasTitle>\n <h5>Linhas</h5>\n </ng-template>\n <div\n class=\"row-list\"\n cdkDropList\n [cdkDropListData]=\"section.rows\"\n (cdkDropListDropped)=\"dropRow($event)\"\n >\n <praxis-row-configurator\n *ngFor=\"let row of section.rows; let i = index\"\n class=\"row-item\"\n [row]=\"row\"\n [fieldMetadata]=\"fieldMetadata\"\n [sectionIndex]=\"sectionIndex\"\n [rowIndex]=\"i\"\n [isLastRow]=\"i === section.rows.length - 1\"\n [selected]=\"selected\"\n [availableFieldsListId]=\"availableFieldsListId\"\n [connectedDropListIds]=\"columnDropListIds\"\n [gapGlobal]=\"gapGlobal\"\n (rowChange)=\"onRowUpdated(i, $event)\"\n (applyRowGapAll)=\"onApplyRowGapAll($event)\"\n (remove)=\"removeRow(i)\"\n (select)=\"select.emit($event)\"\n (fieldDrop)=\"onFieldDrop($event, i)\"\n cdkDrag\n ></praxis-row-configurator>\n </div>\n <div class=\"section-actions\" aria-label=\"A\u00E7\u00F5es da se\u00E7\u00E3o\">\n <button\n class=\"fab-add-row\"\n mat-fab\n color=\"primary\"\n (click)=\"addRow()\"\n matTooltip=\"Adicionar linha\"\n aria-label=\"Adicionar linha\"\n >\n <mat-icon>add</mat-icon>\n </button>\n </div>\n </mat-card-content>\n</mat-card>\n", styles: ["@charset \"UTF-8\";.section-card{background:var(--md-sys-color-surface, var(--sicoob-bg-elev-1));margin-bottom:16px;transition:border-color .2s ease;border:1px solid transparent}.section-card.hovered{border-color:var(--md-sys-color-primary, var(--md-sys-color-primary, var(--sicoob-primary-default)))}.section-card.selected{border-color:var(--md-sys-color-primary, var(--md-sys-color-primary, var(--sicoob-primary-default)));box-shadow:0 0 0 2px var(--md-sys-color-primary)}.section-card:focus-visible{outline:2px solid var(--md-sys-color-primary, var(--md-sys-color-primary, var(--sicoob-primary-default)));outline-offset:2px}.section-card .mat-mdc-card-content{padding-bottom:var(--px-editor-section-gap, 16px)}.section-breadcrumbs{font-size:12px;color:var(--md-sys-color-on-surface-variant);margin:4px 0 8px;display:flex;align-items:center;gap:6px}.section-breadcrumbs .as-button{background:transparent;border:none;padding:0 2px;color:inherit;font:inherit;cursor:pointer;border-radius:4px}.section-breadcrumbs .as-button:hover{color:var(--md-sys-color-primary, var(--md-sys-color-primary, var(--sicoob-primary-default)))}.section-breadcrumbs .as-button:focus-visible{outline:2px solid var(--md-sys-color-primary, var(--md-sys-color-primary, var(--sicoob-primary-default)));outline-offset:2px}.section-breadcrumbs .crumb-clear{margin-left:6px;opacity:.85}.section-breadcrumbs .crumb.active{color:var(--md-sys-color-on-surface);font-weight:600}.section-breadcrumbs .sep{opacity:.6}.section-header{display:flex;justify-content:space-between;align-items:center;gap:12px;min-height:56px}.title-wrapper{display:flex;align-items:center;gap:8px;width:100%;min-width:0;flex:1 1 auto}.section-heading{display:flex;align-items:center;gap:10px;min-width:0}.section-heading__icon{color:var(--md-sys-color-primary, var(--md-sys-color-primary, var(--sicoob-primary-default)))}.section-heading__avatar{--_pfx-layout-section-avatar-size: var(--pfx-form-section-avatar-size-md, var(--pfx-form-section-avatar-size, 32px));display:inline-flex;align-items:center;justify-content:center;width:var(--_pfx-layout-section-avatar-size);height:var(--_pfx-layout-section-avatar-size);border-radius:999px;flex:0 0 var(--_pfx-layout-section-avatar-size);overflow:hidden}.section-heading__avatar.size-sm{--_pfx-layout-section-avatar-size: var(--pfx-form-section-avatar-size-sm, 24px)}.section-heading__avatar.size-md{--_pfx-layout-section-avatar-size: var(--pfx-form-section-avatar-size-md, var(--pfx-form-section-avatar-size, 32px))}.section-heading__avatar.size-lg{--_pfx-layout-section-avatar-size: var(--pfx-form-section-avatar-size-lg, 40px)}.section-heading__avatar--text,.section-heading__avatar--placeholder{background:color-mix(in srgb,var(--pfx-editorial-form-accent, var(--md-sys-color-primary, var(--sicoob-primary-default))) 14%,var(--pfx-form-section-surface-flat, var(--md-sys-color-surface, var(--sicoob-bg-elev-1))));color:color-mix(in srgb,var(--pfx-editorial-form-accent, var(--md-sys-color-primary, var(--sicoob-primary-default))) 82%,var(--pfx-form-label-strong, var(--md-sys-color-on-surface, var(--sicoob-text-default))) 18%);font-size:calc(var(--_pfx-layout-section-avatar-size) * .41);font-weight:800;letter-spacing:.04em;text-transform:uppercase}.section-heading__avatar--placeholder mat-icon{font-size:calc(var(--_pfx-layout-section-avatar-size) * .5625);width:calc(var(--_pfx-layout-section-avatar-size) * .5625);height:calc(var(--_pfx-layout-section-avatar-size) * .5625);line-height:calc(var(--_pfx-layout-section-avatar-size) * .5625)}.section-heading__text{display:flex;flex-direction:column;align-items:flex-start;min-width:0}.section-heading .section-name{font-weight:600;color:var(--md-sys-color-on-surface);overflow:hidden;text-overflow:ellipsis;white-space:nowrap}.section-heading .section-desc{font-size:12px;color:var(--md-sys-color-on-surface-variant);margin-top:2px;overflow:hidden;text-overflow:ellipsis;white-space:nowrap}.section-editor-trigger{margin-left:auto}.section-header-actions{display:inline-flex;align-items:center;gap:4px;flex-shrink:0}.section-header-actions .mat-mdc-icon-button{width:36px;height:36px;padding:6px}.add-row-button{margin-top:8px}.row-item{animation:fadeIn .3s ease}@keyframes fadeIn{0%{opacity:0;transform:translateY(-4px)}to{opacity:1;transform:none}}.section-card:hover{border-color:var(--md-sys-color-primary, var(--md-sys-color-primary, var(--sicoob-primary-default)))}.section-card.collapsed .mat-mdc-card-content{display:none}:host ::ng-deep .section-card .mat-mdc-card-header{padding:8px 12px}:host ::ng-deep .section-card .mat-mdc-card-title{margin:0}:host ::ng-deep .section-card .mat-mdc-card-content{padding:0 12px 12px}.section-actions{position:relative;margin-top:12px;padding-top:16px;border-top:1px solid var(--md-sys-color-outline-variant, var(--md-sys-color-outline-variant, var(--sicoob-stroke-medium)));min-height:28px}.row-list{border-top:1px solid var(--px-editor-separator-color, var(--md-sys-color-outline-variant));padding-top:12px;margin-top:8px}.fab-add-row{position:absolute;top:-15px;left:50%;transform:translate(-50%,calc(-50% - var(--pfx-divider-w, 1px)));z-index:2;--pfx-fab-size: var(--pfx-fab-size-row, 32px);--pfx-fab-icon: var(--pfx-fab-icon-row, 18px);width:var(--pfx-fab-size);height:var(--pfx-fab-size);border-radius:50%}.fab-add-row.mat-mdc-fab{width:var(--pfx-fab-size);height:var(--pfx-fab-size);padding:0}.fab-add-row .mat-mdc-button-touch-target,.fab-add-row .mat-mdc-button-persistent-ripple,.fab-add-row .mat-mdc-button-ripple{width:var(--pfx-fab-size);height:var(--pfx-fab-size)}.fab-add-row mat-icon{font-size:var(--pfx-fab-icon);width:var(--pfx-fab-icon);height:var(--pfx-fab-icon)}\n"], dependencies: [{ kind: "ngmodule", type: CommonModule }, { kind: "directive", type: i1$1.NgForOf, selector: "[ngFor][ngForOf]", inputs: ["ngForOf", "ngForTrackBy", "ngForTemplate"] }, { kind: "directive", type: i1$1.NgIf, selector: "[ngIf]", inputs: ["ngIf", "ngIfThen", "ngIfElse"] }, { kind: "ngmodule", type: DragDropModule }, { kind: "directive", type: i2$2.CdkDropList, selector: "[cdkDropList], cdk-drop-list", inputs: ["cdkDropListConnectedTo", "cdkDropListData", "cdkDropListOrientation", "id", "cdkDropListLockAxis", "cdkDropListDisabled", "cdkDropListSortingDisabled", "cdkDropListEnterPredicate", "cdkDropListSortPredicate", "cdkDropListAutoScrollDisabled", "cdkDropListAutoScrollStep", "cdkDropListElementContainer", "cdkDropListHasAnchor"], outputs: ["cdkDropListDropped", "cdkDropListEntered", "cdkDropListExited", "cdkDropListSorted"], exportAs: ["cdkDropList"] }, { kind: "directive", type: i2$2.CdkDrag, selector: "[cdkDrag]", inputs: ["cdkDragData", "cdkDragLockAxis", "cdkDragRootElement", "cdkDragBoundary", "cdkDragStartDelay", "cdkDragFreeDragPosition", "cdkDragDisabled", "cdkDragConstrainPosition", "cdkDragPreviewClass", "cdkDragPreviewContainer", "cdkDragScale"], outputs: ["cdkDragStarted", "cdkDragReleased", "cdkDragEnded", "cdkDragEntered", "cdkDragExited", "cdkDragDropped", "cdkDragMoved"], exportAs: ["cdkDrag"] }, { kind: "component", type: RowConfiguratorComponent, selector: "praxis-row-configurator", inputs: ["row", "fieldMetadata", "sectionIndex", "rowIndex", "isLastRow", "selected", "availableFieldsListId", "connectedDropListIds", "gapGlobal"], outputs: ["rowChange", "remove", "applyRowGapAll", "fieldDrop", "select"] }, { kind: "ngmodule", type: MatButtonModule }, { kind: "component", type: i4.MatIconButton, selector: "button[mat-icon-button], a[mat-icon-button], button[matIconButton], a[matIconButton]", exportAs: ["matButton", "matAnchor"] }, { kind: "component", type: i4.MatFabButton, selector: "button[mat-fab], a[mat-fab], button[matFab], a[matFab]", inputs: ["extended"], exportAs: ["matButton", "matAnchor"] }, { kind: "ngmodule", type: MatIconModule }, { kind: "component", type: i5.MatIcon, selector: "mat-icon", inputs: ["color", "inline", "svgIcon", "fontSet", "fontIcon"], exportAs: ["matIcon"] }, { kind: "directive", type: PraxisIconDirective, selector: "mat-icon[praxisIcon]", inputs: ["praxisIcon"] }, { kind: "ngmodule", type: MatCardModule }, { kind: "component", type: i8.MatCard, selector: "mat-card", inputs: ["appearance"], exportAs: ["matCard"] }, { kind: "directive", type: i8.MatCardContent, selector: "mat-card-content" }, { kind: "component", type: i8.MatCardHeader, selector: "mat-card-header" }, { kind: "directive", type: i8.MatCardTitle, selector: "mat-card-title, [mat-card-title], [matCardTitle]" }, { kind: "ngmodule", type: MatTooltipModule }, { kind: "directive", type: i9.MatTooltip, selector: "[matTooltip]", inputs: ["matTooltipPosition", "matTooltipPositionAtOrigin", "matTooltipDisabled", "matTooltipShowDelay", "matTooltipHideDelay", "matTooltipTouchGestures", "matTooltip", "matTooltipClass"], exportAs: ["matTooltip"] }, { kind: "ngmodule", type: MatDialogModule }, { kind: "ngmodule", type: MatMenuModule }, { kind: "component", type: i6.MatMenu, selector: "mat-menu", inputs: ["backdropClass", "aria-label", "aria-labelledby", "aria-describedby", "xPosition", "yPosition", "overlapTrigger", "hasBackdrop", "class", "classList"], outputs: ["closed", "close"], exportAs: ["matMenu"] }, { kind: "component", type: i6.MatMenuItem, selector: "[mat-menu-item]", inputs: ["role", "disabled", "disableRipple"], exportAs: ["matMenuItem"] }, { kind: "directive", type: i6.MatMenuTrigger, selector: "[mat-menu-trigger-for], [matMenuTriggerFor]", inputs: ["mat-menu-trigger-for", "matMenuTriggerFor", "matMenuTriggerData", "matMenuTriggerRestoreFocus"], outputs: ["menuOpened", "onMenuOpen", "menuClosed", "onMenuClose"], exportAs: ["matMenuTrigger"] }, { kind: "ngmodule", type: MatDividerModule }, { kind: "component", type: i11.MatDivider, selector: "mat-divider", inputs: ["vertical", "inset"] }] });
14737
+ static ɵcmp = i0.ɵɵngDeclareComponent({ minVersion: "17.0.0", version: "20.3.17", type: SectionConfiguratorComponent, isStandalone: true, selector: "praxis-section-configurator", inputs: { section: "section", sectionIndex: "sectionIndex", allSections: "allSections", fieldMetadata: "fieldMetadata", availableFields: "availableFields", selected: "selected", availableFieldsListId: "availableFieldsListId", columnDropListIds: "columnDropListIds", gapGlobal: "gapGlobal" }, outputs: { sectionChange: "sectionChange", applyStyleToAll: "applyStyleToAll", remove: "remove", select: "select", fieldDrop: "fieldDrop", addVisualBlock: "addVisualBlock", addApiField: "addApiField", editVisualBlock: "editVisualBlock", moveVisualBlock: "moveVisualBlock", moveVisualBlockToColumn: "moveVisualBlockToColumn", removeVisualBlock: "removeVisualBlock" }, ngImport: i0, template: "<mat-card\n class=\"section-card\"\n cdkDrag\n (mouseenter)=\"onMouseEnter()\"\n (mouseleave)=\"onMouseLeave()\"\n [class.hovered]=\"isHovered\"\n [class.selected]=\"isThisSectionSelected()\"\n [class.collapsed]=\"isCollapsed\"\n (click)=\"onSelectSection()\"\n tabindex=\"0\"\n role=\"button\"\n [attr.aria-label]=\"'Se\u00E7\u00E3o ' + (sectionIndex + 1)\"\n [attr.aria-selected]=\"isThisSectionSelected()\"\n>\n <mat-card-header class=\"section-header\">\n <mat-card-title class=\"title-wrapper\">\n <div class=\"section-heading\">\n @let headerPreview = getSectionHeaderPreview();\n @let headerAvatarSize = getSectionHeaderAvatarSize();\n @if (headerPreview.kind === 'icon') {\n <mat-icon class=\"section-heading__icon\" aria-hidden=\"true\" [praxisIcon]=\"headerPreview.icon\"></mat-icon>\n }\n @if (headerPreview.kind === 'initials') {\n <span class=\"section-heading__avatar section-heading__avatar--text\" [class.size-sm]=\"headerAvatarSize === 'sm'\"\n [class.size-md]=\"headerAvatarSize === 'md'\" [class.size-lg]=\"headerAvatarSize === 'lg'\"\n [matTooltip]=\"headerPreview.tooltip || ''\" [matTooltipDisabled]=\"!headerPreview.tooltip\">\n {{ headerPreview.text }}\n </span>\n }\n @if (headerPreview.kind === 'placeholder') {\n <span class=\"section-heading__avatar section-heading__avatar--placeholder\" [class.size-sm]=\"headerAvatarSize === 'sm'\"\n [class.size-md]=\"headerAvatarSize === 'md'\" [class.size-lg]=\"headerAvatarSize === 'lg'\"\n [matTooltip]=\"headerPreview.tooltip || ''\" [matTooltipDisabled]=\"!headerPreview.tooltip\">\n @if (headerPreview.icon) {\n <mat-icon aria-hidden=\"true\" [praxisIcon]=\"headerPreview.icon\"></mat-icon>\n }\n </span>\n }\n <div class=\"section-heading__text\">\n <span class=\"section-name\">{{ section.title || 'Sem t\u00EDtulo' }}</span>\n <span class=\"section-desc\" *ngIf=\"section.description\">{{ section.description }}</span>\n </div>\n </div>\n <button\n mat-icon-button\n type=\"button\"\n color=\"primary\"\n class=\"section-editor-trigger\"\n (click)=\"openAdvancedEditor($event)\"\n matTooltip=\"Para editar o t\u00EDtulo, use o editor completo da se\u00E7\u00E3o\"\n aria-label=\"Abrir editor da se\u00E7\u00E3o\"\n >\n <mat-icon>open_in_new</mat-icon>\n </button>\n </mat-card-title>\n <div class=\"section-header-actions\">\n <button\n mat-icon-button\n class=\"section-collapse-btn\"\n type=\"button\"\n (click)=\"toggleCollapsed($event)\"\n [attr.aria-expanded]=\"!isCollapsed\"\n [attr.aria-label]=\"isCollapsed ? 'Expandir se\u00E7\u00E3o' : 'Colapsar se\u00E7\u00E3o'\"\n [matTooltip]=\"isCollapsed ? 'Expandir se\u00E7\u00E3o' : 'Colapsar se\u00E7\u00E3o'\"\n >\n <mat-icon>{{ isCollapsed ? 'unfold_more' : 'unfold_less' }}</mat-icon>\n </button>\n <button\n mat-icon-button\n class=\"section-menu-btn\"\n [matMenuTriggerFor]=\"sectionMenu\"\n aria-label=\"Mais a\u00E7\u00F5es da se\u00E7\u00E3o\"\n matTooltip=\"Mais a\u00E7\u00F5es\"\n >\n <mat-icon [praxisIcon]=\"'more_vert'\"></mat-icon>\n </button>\n </div>\n <mat-menu #sectionMenu=\"matMenu\">\n <button mat-menu-item (click)=\"openSectionPresets()\">\n <mat-icon [praxisIcon]=\"'view_quilt'\"></mat-icon>\n <span>Presets de se\u00E7\u00E3o\u2026</span>\n </button>\n <button mat-menu-item (click)=\"applyCurrentStyleToAll()\">\n <mat-icon [praxisIcon]=\"'format_paint'\"></mat-icon>\n <span>Aplicar estilo desta se\u00E7\u00E3o a todas</span>\n </button>\n <mat-divider></mat-divider>\n <button mat-menu-item *ngIf=\"section.description == null\" (click)=\"section.description = ''; onSectionUpdated()\">\n <mat-icon [praxisIcon]=\"'note_add'\"></mat-icon>\n <span>Adicionar descri\u00E7\u00E3o</span>\n </button>\n <button mat-menu-item *ngIf=\"section.description != null\" (click)=\"section.description = undefined; onSectionUpdated()\">\n <mat-icon [praxisIcon]=\"'backspace'\"></mat-icon>\n <span>Remover descri\u00E7\u00E3o</span>\n </button>\n <mat-divider></mat-divider>\n <button mat-menu-item (click)=\"onRemoveSection()\">\n <mat-icon [praxisIcon]=\"'delete'\"></mat-icon>\n <span>Remover se\u00E7\u00E3o</span>\n </button>\n </mat-menu>\n </mat-card-header>\n <mat-card-content [attr.aria-hidden]=\"isCollapsed\">\n <ng-container *ngIf=\"isThisSectionSelected(); else linhasTitle\">\n <div class=\"section-breadcrumbs\" (click)=\"$event.stopPropagation()\">\n <button\n type=\"button\"\n class=\"crumb as-button\"\n data-crumb=\"layout\"\n [attr.aria-label]=\"'Voltar ao Layout'\"\n disabled\n >\n Layout\n </button>\n <span class=\"sep\">\u203A</span>\n <button\n type=\"button\"\n class=\"crumb as-button crumb-section\"\n data-crumb=\"section\"\n (click)=\"onSelectSectionFromBreadcrumb($event)\"\n [attr.aria-label]=\"'Selecionar Se\u00E7\u00E3o ' + (sectionIndex + 1)\"\n >\n Se\u00E7\u00E3o {{ sectionIndex + 1 }}\n </button>\n <ng-container *ngIf=\"selected?.rowIndex != null\">\n <span class=\"sep\">\u203A</span>\n <button\n type=\"button\"\n class=\"crumb as-button crumb-row\"\n data-crumb=\"row\"\n (click)=\"onSelectRowFromBreadcrumb($event)\"\n [attr.aria-label]=\"'Selecionar Linha ' + (selected!.rowIndex! + 1)\"\n >\n Linha {{ selected!.rowIndex! + 1 }}\n </button>\n </ng-container>\n <ng-container *ngIf=\"selected?.columnIndex != null\">\n <span class=\"sep\">\u203A</span>\n <button\n type=\"button\"\n class=\"crumb as-button crumb-column\"\n data-crumb=\"column\"\n (click)=\"onSelectColumnFromBreadcrumb($event)\"\n [attr.aria-label]=\"'Selecionar Coluna ' + (selected!.columnIndex! + 1)\"\n >\n Coluna {{ selected!.columnIndex! + 1 }}\n </button>\n </ng-container>\n <ng-container *ngIf=\"selected?.fieldName\">\n <span class=\"sep\">\u203A</span>\n <span class=\"crumb active\">{{ selected!.fieldName }}</span>\n </ng-container>\n <button\n *ngIf=\"selected\"\n type=\"button\"\n class=\"crumb as-button crumb-clear\"\n data-crumb=\"clear\"\n (click)=\"onClearSelectionFromBreadcrumb($event)\"\n [attr.aria-label]=\"'Limpar sele\u00E7\u00E3o'\"\n >\n Limpar\n </button>\n </div>\n </ng-container>\n <ng-template #linhasTitle>\n <h5>Linhas</h5>\n </ng-template>\n <div\n class=\"row-list\"\n cdkDropList\n [cdkDropListData]=\"section.rows\"\n (cdkDropListDropped)=\"dropRow($event)\"\n >\n <praxis-row-configurator\n *ngFor=\"let row of section.rows; let i = index\"\n class=\"row-item\"\n [row]=\"row\"\n [fieldMetadata]=\"fieldMetadata\"\n [availableFields]=\"availableFields\"\n [sectionIndex]=\"sectionIndex\"\n [rowIndex]=\"i\"\n [isLastRow]=\"i === section.rows.length - 1\"\n [selected]=\"selected\"\n [availableFieldsListId]=\"availableFieldsListId\"\n [connectedDropListIds]=\"columnDropListIds\"\n [gapGlobal]=\"gapGlobal\"\n (rowChange)=\"onRowUpdated(i, $event)\"\n (applyRowGapAll)=\"onApplyRowGapAll($event)\"\n (remove)=\"removeRow(i)\"\n (select)=\"select.emit($event)\"\n (fieldDrop)=\"onFieldDrop($event, i)\"\n (addVisualBlock)=\"onAddVisualBlock($event)\"\n (addApiField)=\"onAddApiField($event)\"\n (editVisualBlock)=\"onEditVisualBlock($event)\"\n (moveVisualBlock)=\"onMoveVisualBlock($event)\"\n (moveVisualBlockToColumn)=\"onMoveVisualBlockToColumn($event)\"\n (removeVisualBlock)=\"onRemoveVisualBlock($event)\"\n cdkDrag\n ></praxis-row-configurator>\n </div>\n <div class=\"section-actions\" aria-label=\"A\u00E7\u00F5es da se\u00E7\u00E3o\">\n <button\n class=\"fab-add-row\"\n mat-fab\n color=\"primary\"\n (click)=\"addRow()\"\n matTooltip=\"Adicionar linha\"\n aria-label=\"Adicionar linha\"\n >\n <mat-icon>add</mat-icon>\n </button>\n </div>\n </mat-card-content>\n</mat-card>\n", styles: ["@charset \"UTF-8\";.section-card{background:var(--md-sys-color-surface, var(--sicoob-bg-elev-1));margin-bottom:16px;transition:border-color .2s ease;border:1px solid transparent}.section-card.hovered{border-color:var(--md-sys-color-primary, var(--md-sys-color-primary, var(--sicoob-primary-default)))}.section-card.selected{border-color:var(--md-sys-color-primary, var(--md-sys-color-primary, var(--sicoob-primary-default)));box-shadow:0 0 0 2px var(--md-sys-color-primary)}.section-card:focus-visible{outline:2px solid var(--md-sys-color-primary, var(--md-sys-color-primary, var(--sicoob-primary-default)));outline-offset:2px}.section-card .mat-mdc-card-content{padding-bottom:var(--px-editor-section-gap, 16px)}.section-breadcrumbs{font-size:12px;color:var(--md-sys-color-on-surface-variant);margin:4px 0 8px;display:flex;align-items:center;gap:6px}.section-breadcrumbs .as-button{background:transparent;border:none;padding:0 2px;color:inherit;font:inherit;cursor:pointer;border-radius:4px}.section-breadcrumbs .as-button:hover{color:var(--md-sys-color-primary, var(--md-sys-color-primary, var(--sicoob-primary-default)))}.section-breadcrumbs .as-button:focus-visible{outline:2px solid var(--md-sys-color-primary, var(--md-sys-color-primary, var(--sicoob-primary-default)));outline-offset:2px}.section-breadcrumbs .crumb-clear{margin-left:6px;opacity:.85}.section-breadcrumbs .crumb.active{color:var(--md-sys-color-on-surface);font-weight:600}.section-breadcrumbs .sep{opacity:.6}.section-header{display:flex;justify-content:space-between;align-items:center;gap:12px;min-height:56px}.title-wrapper{display:flex;align-items:center;gap:8px;width:100%;min-width:0;flex:1 1 auto}.section-heading{display:flex;align-items:center;gap:10px;min-width:0}.section-heading__icon{color:var(--md-sys-color-primary, var(--md-sys-color-primary, var(--sicoob-primary-default)))}.section-heading__avatar{--_pfx-layout-section-avatar-size: var(--pfx-form-section-avatar-size-md, var(--pfx-form-section-avatar-size, 32px));display:inline-flex;align-items:center;justify-content:center;width:var(--_pfx-layout-section-avatar-size);height:var(--_pfx-layout-section-avatar-size);border-radius:999px;flex:0 0 var(--_pfx-layout-section-avatar-size);overflow:hidden}.section-heading__avatar.size-sm{--_pfx-layout-section-avatar-size: var(--pfx-form-section-avatar-size-sm, 24px)}.section-heading__avatar.size-md{--_pfx-layout-section-avatar-size: var(--pfx-form-section-avatar-size-md, var(--pfx-form-section-avatar-size, 32px))}.section-heading__avatar.size-lg{--_pfx-layout-section-avatar-size: var(--pfx-form-section-avatar-size-lg, 40px)}.section-heading__avatar--text,.section-heading__avatar--placeholder{background:color-mix(in srgb,var(--pfx-editorial-form-accent, var(--md-sys-color-primary, var(--sicoob-primary-default))) 14%,var(--pfx-form-section-surface-flat, var(--md-sys-color-surface, var(--sicoob-bg-elev-1))));color:color-mix(in srgb,var(--pfx-editorial-form-accent, var(--md-sys-color-primary, var(--sicoob-primary-default))) 82%,var(--pfx-form-label-strong, var(--md-sys-color-on-surface, var(--sicoob-text-default))) 18%);font-size:calc(var(--_pfx-layout-section-avatar-size) * .41);font-weight:800;letter-spacing:.04em;text-transform:uppercase}.section-heading__avatar--placeholder mat-icon{font-size:calc(var(--_pfx-layout-section-avatar-size) * .5625);width:calc(var(--_pfx-layout-section-avatar-size) * .5625);height:calc(var(--_pfx-layout-section-avatar-size) * .5625);line-height:calc(var(--_pfx-layout-section-avatar-size) * .5625)}.section-heading__text{display:flex;flex-direction:column;align-items:flex-start;min-width:0}.section-heading .section-name{font-weight:600;color:var(--md-sys-color-on-surface);overflow:hidden;text-overflow:ellipsis;white-space:nowrap}.section-heading .section-desc{font-size:12px;color:var(--md-sys-color-on-surface-variant);margin-top:2px;overflow:hidden;text-overflow:ellipsis;white-space:nowrap}.section-editor-trigger{margin-left:auto}.section-header-actions{display:inline-flex;align-items:center;gap:4px;flex-shrink:0}.section-header-actions .mat-mdc-icon-button{width:36px;height:36px;padding:6px}.add-row-button{margin-top:8px}.row-item{animation:fadeIn .3s ease}@keyframes fadeIn{0%{opacity:0;transform:translateY(-4px)}to{opacity:1;transform:none}}.section-card:hover{border-color:var(--md-sys-color-primary, var(--md-sys-color-primary, var(--sicoob-primary-default)))}.section-card.collapsed .mat-mdc-card-content{display:none}:host ::ng-deep .section-card .mat-mdc-card-header{padding:8px 12px}:host ::ng-deep .section-card .mat-mdc-card-title{margin:0}:host ::ng-deep .section-card .mat-mdc-card-content{padding:0 12px 12px}.section-actions{position:relative;margin-top:12px;padding-top:16px;border-top:1px solid var(--md-sys-color-outline-variant, var(--md-sys-color-outline-variant, var(--sicoob-stroke-medium)));min-height:28px}.row-list{border-top:1px solid var(--px-editor-separator-color, var(--md-sys-color-outline-variant));padding-top:12px;margin-top:8px}.fab-add-row{position:absolute;top:-15px;left:50%;transform:translate(-50%,calc(-50% - var(--pfx-divider-w, 1px)));z-index:2;--pfx-fab-size: var(--pfx-fab-size-row, 32px);--pfx-fab-icon: var(--pfx-fab-icon-row, 18px);width:var(--pfx-fab-size);height:var(--pfx-fab-size);border-radius:50%}.fab-add-row.mat-mdc-fab{width:var(--pfx-fab-size);height:var(--pfx-fab-size);padding:0}.fab-add-row .mat-mdc-button-touch-target,.fab-add-row .mat-mdc-button-persistent-ripple,.fab-add-row .mat-mdc-button-ripple{width:var(--pfx-fab-size);height:var(--pfx-fab-size)}.fab-add-row mat-icon{font-size:var(--pfx-fab-icon);width:var(--pfx-fab-icon);height:var(--pfx-fab-icon)}\n"], dependencies: [{ kind: "ngmodule", type: CommonModule }, { kind: "directive", type: i1$1.NgForOf, selector: "[ngFor][ngForOf]", inputs: ["ngForOf", "ngForTrackBy", "ngForTemplate"] }, { kind: "directive", type: i1$1.NgIf, selector: "[ngIf]", inputs: ["ngIf", "ngIfThen", "ngIfElse"] }, { kind: "ngmodule", type: DragDropModule }, { kind: "directive", type: i2$2.CdkDropList, selector: "[cdkDropList], cdk-drop-list", inputs: ["cdkDropListConnectedTo", "cdkDropListData", "cdkDropListOrientation", "id", "cdkDropListLockAxis", "cdkDropListDisabled", "cdkDropListSortingDisabled", "cdkDropListEnterPredicate", "cdkDropListSortPredicate", "cdkDropListAutoScrollDisabled", "cdkDropListAutoScrollStep", "cdkDropListElementContainer", "cdkDropListHasAnchor"], outputs: ["cdkDropListDropped", "cdkDropListEntered", "cdkDropListExited", "cdkDropListSorted"], exportAs: ["cdkDropList"] }, { kind: "directive", type: i2$2.CdkDrag, selector: "[cdkDrag]", inputs: ["cdkDragData", "cdkDragLockAxis", "cdkDragRootElement", "cdkDragBoundary", "cdkDragStartDelay", "cdkDragFreeDragPosition", "cdkDragDisabled", "cdkDragConstrainPosition", "cdkDragPreviewClass", "cdkDragPreviewContainer", "cdkDragScale"], outputs: ["cdkDragStarted", "cdkDragReleased", "cdkDragEnded", "cdkDragEntered", "cdkDragExited", "cdkDragDropped", "cdkDragMoved"], exportAs: ["cdkDrag"] }, { kind: "component", type: RowConfiguratorComponent, selector: "praxis-row-configurator", inputs: ["row", "fieldMetadata", "availableFields", "sectionIndex", "rowIndex", "isLastRow", "selected", "availableFieldsListId", "connectedDropListIds", "gapGlobal"], outputs: ["rowChange", "remove", "applyRowGapAll", "fieldDrop", "addVisualBlock", "addApiField", "editVisualBlock", "moveVisualBlock", "moveVisualBlockToColumn", "removeVisualBlock", "select"] }, { kind: "ngmodule", type: MatButtonModule }, { kind: "component", type: i4.MatIconButton, selector: "button[mat-icon-button], a[mat-icon-button], button[matIconButton], a[matIconButton]", exportAs: ["matButton", "matAnchor"] }, { kind: "component", type: i4.MatFabButton, selector: "button[mat-fab], a[mat-fab], button[matFab], a[matFab]", inputs: ["extended"], exportAs: ["matButton", "matAnchor"] }, { kind: "ngmodule", type: MatIconModule }, { kind: "component", type: i5.MatIcon, selector: "mat-icon", inputs: ["color", "inline", "svgIcon", "fontSet", "fontIcon"], exportAs: ["matIcon"] }, { kind: "directive", type: PraxisIconDirective, selector: "mat-icon[praxisIcon]", inputs: ["praxisIcon"] }, { kind: "ngmodule", type: MatCardModule }, { kind: "component", type: i8.MatCard, selector: "mat-card", inputs: ["appearance"], exportAs: ["matCard"] }, { kind: "directive", type: i8.MatCardContent, selector: "mat-card-content" }, { kind: "component", type: i8.MatCardHeader, selector: "mat-card-header" }, { kind: "directive", type: i8.MatCardTitle, selector: "mat-card-title, [mat-card-title], [matCardTitle]" }, { kind: "ngmodule", type: MatTooltipModule }, { kind: "directive", type: i9.MatTooltip, selector: "[matTooltip]", inputs: ["matTooltipPosition", "matTooltipPositionAtOrigin", "matTooltipDisabled", "matTooltipShowDelay", "matTooltipHideDelay", "matTooltipTouchGestures", "matTooltip", "matTooltipClass"], exportAs: ["matTooltip"] }, { kind: "ngmodule", type: MatDialogModule }, { kind: "ngmodule", type: MatMenuModule }, { kind: "component", type: i6.MatMenu, selector: "mat-menu", inputs: ["backdropClass", "aria-label", "aria-labelledby", "aria-describedby", "xPosition", "yPosition", "overlapTrigger", "hasBackdrop", "class", "classList"], outputs: ["closed", "close"], exportAs: ["matMenu"] }, { kind: "component", type: i6.MatMenuItem, selector: "[mat-menu-item]", inputs: ["role", "disabled", "disableRipple"], exportAs: ["matMenuItem"] }, { kind: "directive", type: i6.MatMenuTrigger, selector: "[mat-menu-trigger-for], [matMenuTriggerFor]", inputs: ["mat-menu-trigger-for", "matMenuTriggerFor", "matMenuTriggerData", "matMenuTriggerRestoreFocus"], outputs: ["menuOpened", "onMenuOpen", "menuClosed", "onMenuClose"], exportAs: ["matMenuTrigger"] }, { kind: "ngmodule", type: MatDividerModule }, { kind: "component", type: i11.MatDivider, selector: "mat-divider", inputs: ["vertical", "inset"] }] });
14054
14738
  }
14055
14739
  i0.ɵɵngDeclareClassMetadata({ minVersion: "12.0.0", version: "20.3.17", ngImport: i0, type: SectionConfiguratorComponent, decorators: [{
14056
14740
  type: Component,
@@ -14066,7 +14750,7 @@ i0.ɵɵngDeclareClassMetadata({ minVersion: "12.0.0", version: "20.3.17", ngImpo
14066
14750
  MatDialogModule,
14067
14751
  MatMenuModule,
14068
14752
  MatDividerModule,
14069
- ], template: "<mat-card\n class=\"section-card\"\n cdkDrag\n (mouseenter)=\"onMouseEnter()\"\n (mouseleave)=\"onMouseLeave()\"\n [class.hovered]=\"isHovered\"\n [class.selected]=\"isThisSectionSelected()\"\n [class.collapsed]=\"isCollapsed\"\n (click)=\"onSelectSection()\"\n tabindex=\"0\"\n role=\"button\"\n [attr.aria-label]=\"'Se\u00E7\u00E3o ' + (sectionIndex + 1)\"\n [attr.aria-selected]=\"isThisSectionSelected()\"\n>\n <mat-card-header class=\"section-header\">\n <mat-card-title class=\"title-wrapper\">\n <div class=\"section-heading\">\n @let headerPreview = getSectionHeaderPreview();\n @let headerAvatarSize = getSectionHeaderAvatarSize();\n @if (headerPreview.kind === 'icon') {\n <mat-icon class=\"section-heading__icon\" aria-hidden=\"true\" [praxisIcon]=\"headerPreview.icon\"></mat-icon>\n }\n @if (headerPreview.kind === 'initials') {\n <span class=\"section-heading__avatar section-heading__avatar--text\" [class.size-sm]=\"headerAvatarSize === 'sm'\"\n [class.size-md]=\"headerAvatarSize === 'md'\" [class.size-lg]=\"headerAvatarSize === 'lg'\"\n [matTooltip]=\"headerPreview.tooltip || ''\" [matTooltipDisabled]=\"!headerPreview.tooltip\">\n {{ headerPreview.text }}\n </span>\n }\n @if (headerPreview.kind === 'placeholder') {\n <span class=\"section-heading__avatar section-heading__avatar--placeholder\" [class.size-sm]=\"headerAvatarSize === 'sm'\"\n [class.size-md]=\"headerAvatarSize === 'md'\" [class.size-lg]=\"headerAvatarSize === 'lg'\"\n [matTooltip]=\"headerPreview.tooltip || ''\" [matTooltipDisabled]=\"!headerPreview.tooltip\">\n @if (headerPreview.icon) {\n <mat-icon aria-hidden=\"true\" [praxisIcon]=\"headerPreview.icon\"></mat-icon>\n }\n </span>\n }\n <div class=\"section-heading__text\">\n <span class=\"section-name\">{{ section.title || 'Sem t\u00EDtulo' }}</span>\n <span class=\"section-desc\" *ngIf=\"section.description\">{{ section.description }}</span>\n </div>\n </div>\n <button\n mat-icon-button\n type=\"button\"\n color=\"primary\"\n class=\"section-editor-trigger\"\n (click)=\"openAdvancedEditor($event)\"\n matTooltip=\"Para editar o t\u00EDtulo, use o editor completo da se\u00E7\u00E3o\"\n aria-label=\"Abrir editor da se\u00E7\u00E3o\"\n >\n <mat-icon>open_in_new</mat-icon>\n </button>\n </mat-card-title>\n <div class=\"section-header-actions\">\n <button\n mat-icon-button\n class=\"section-collapse-btn\"\n type=\"button\"\n (click)=\"toggleCollapsed($event)\"\n [attr.aria-expanded]=\"!isCollapsed\"\n [attr.aria-label]=\"isCollapsed ? 'Expandir se\u00E7\u00E3o' : 'Colapsar se\u00E7\u00E3o'\"\n [matTooltip]=\"isCollapsed ? 'Expandir se\u00E7\u00E3o' : 'Colapsar se\u00E7\u00E3o'\"\n >\n <mat-icon>{{ isCollapsed ? 'unfold_more' : 'unfold_less' }}</mat-icon>\n </button>\n <button\n mat-icon-button\n class=\"section-menu-btn\"\n [matMenuTriggerFor]=\"sectionMenu\"\n aria-label=\"Mais a\u00E7\u00F5es da se\u00E7\u00E3o\"\n matTooltip=\"Mais a\u00E7\u00F5es\"\n >\n <mat-icon [praxisIcon]=\"'more_vert'\"></mat-icon>\n </button>\n </div>\n <mat-menu #sectionMenu=\"matMenu\">\n <button mat-menu-item (click)=\"openSectionPresets()\">\n <mat-icon [praxisIcon]=\"'view_quilt'\"></mat-icon>\n <span>Presets de se\u00E7\u00E3o\u2026</span>\n </button>\n <button mat-menu-item (click)=\"applyCurrentStyleToAll()\">\n <mat-icon [praxisIcon]=\"'format_paint'\"></mat-icon>\n <span>Aplicar estilo desta se\u00E7\u00E3o a todas</span>\n </button>\n <mat-divider></mat-divider>\n <button mat-menu-item *ngIf=\"section.description == null\" (click)=\"section.description = ''; onSectionUpdated()\">\n <mat-icon [praxisIcon]=\"'note_add'\"></mat-icon>\n <span>Adicionar descri\u00E7\u00E3o</span>\n </button>\n <button mat-menu-item *ngIf=\"section.description != null\" (click)=\"section.description = undefined; onSectionUpdated()\">\n <mat-icon [praxisIcon]=\"'backspace'\"></mat-icon>\n <span>Remover descri\u00E7\u00E3o</span>\n </button>\n <mat-divider></mat-divider>\n <button mat-menu-item (click)=\"onRemoveSection()\">\n <mat-icon [praxisIcon]=\"'delete'\"></mat-icon>\n <span>Remover se\u00E7\u00E3o</span>\n </button>\n </mat-menu>\n </mat-card-header>\n <mat-card-content [attr.aria-hidden]=\"isCollapsed\">\n <ng-container *ngIf=\"isThisSectionSelected(); else linhasTitle\">\n <div class=\"section-breadcrumbs\" (click)=\"$event.stopPropagation()\">\n <button\n type=\"button\"\n class=\"crumb as-button\"\n data-crumb=\"layout\"\n [attr.aria-label]=\"'Voltar ao Layout'\"\n disabled\n >\n Layout\n </button>\n <span class=\"sep\">\u203A</span>\n <button\n type=\"button\"\n class=\"crumb as-button crumb-section\"\n data-crumb=\"section\"\n (click)=\"onSelectSectionFromBreadcrumb($event)\"\n [attr.aria-label]=\"'Selecionar Se\u00E7\u00E3o ' + (sectionIndex + 1)\"\n >\n Se\u00E7\u00E3o {{ sectionIndex + 1 }}\n </button>\n <ng-container *ngIf=\"selected?.rowIndex != null\">\n <span class=\"sep\">\u203A</span>\n <button\n type=\"button\"\n class=\"crumb as-button crumb-row\"\n data-crumb=\"row\"\n (click)=\"onSelectRowFromBreadcrumb($event)\"\n [attr.aria-label]=\"'Selecionar Linha ' + (selected!.rowIndex! + 1)\"\n >\n Linha {{ selected!.rowIndex! + 1 }}\n </button>\n </ng-container>\n <ng-container *ngIf=\"selected?.columnIndex != null\">\n <span class=\"sep\">\u203A</span>\n <button\n type=\"button\"\n class=\"crumb as-button crumb-column\"\n data-crumb=\"column\"\n (click)=\"onSelectColumnFromBreadcrumb($event)\"\n [attr.aria-label]=\"'Selecionar Coluna ' + (selected!.columnIndex! + 1)\"\n >\n Coluna {{ selected!.columnIndex! + 1 }}\n </button>\n </ng-container>\n <ng-container *ngIf=\"selected?.fieldName\">\n <span class=\"sep\">\u203A</span>\n <span class=\"crumb active\">{{ selected!.fieldName }}</span>\n </ng-container>\n <button\n *ngIf=\"selected\"\n type=\"button\"\n class=\"crumb as-button crumb-clear\"\n data-crumb=\"clear\"\n (click)=\"onClearSelectionFromBreadcrumb($event)\"\n [attr.aria-label]=\"'Limpar sele\u00E7\u00E3o'\"\n >\n Limpar\n </button>\n </div>\n </ng-container>\n <ng-template #linhasTitle>\n <h5>Linhas</h5>\n </ng-template>\n <div\n class=\"row-list\"\n cdkDropList\n [cdkDropListData]=\"section.rows\"\n (cdkDropListDropped)=\"dropRow($event)\"\n >\n <praxis-row-configurator\n *ngFor=\"let row of section.rows; let i = index\"\n class=\"row-item\"\n [row]=\"row\"\n [fieldMetadata]=\"fieldMetadata\"\n [sectionIndex]=\"sectionIndex\"\n [rowIndex]=\"i\"\n [isLastRow]=\"i === section.rows.length - 1\"\n [selected]=\"selected\"\n [availableFieldsListId]=\"availableFieldsListId\"\n [connectedDropListIds]=\"columnDropListIds\"\n [gapGlobal]=\"gapGlobal\"\n (rowChange)=\"onRowUpdated(i, $event)\"\n (applyRowGapAll)=\"onApplyRowGapAll($event)\"\n (remove)=\"removeRow(i)\"\n (select)=\"select.emit($event)\"\n (fieldDrop)=\"onFieldDrop($event, i)\"\n cdkDrag\n ></praxis-row-configurator>\n </div>\n <div class=\"section-actions\" aria-label=\"A\u00E7\u00F5es da se\u00E7\u00E3o\">\n <button\n class=\"fab-add-row\"\n mat-fab\n color=\"primary\"\n (click)=\"addRow()\"\n matTooltip=\"Adicionar linha\"\n aria-label=\"Adicionar linha\"\n >\n <mat-icon>add</mat-icon>\n </button>\n </div>\n </mat-card-content>\n</mat-card>\n", styles: ["@charset \"UTF-8\";.section-card{background:var(--md-sys-color-surface, var(--sicoob-bg-elev-1));margin-bottom:16px;transition:border-color .2s ease;border:1px solid transparent}.section-card.hovered{border-color:var(--md-sys-color-primary, var(--md-sys-color-primary, var(--sicoob-primary-default)))}.section-card.selected{border-color:var(--md-sys-color-primary, var(--md-sys-color-primary, var(--sicoob-primary-default)));box-shadow:0 0 0 2px var(--md-sys-color-primary)}.section-card:focus-visible{outline:2px solid var(--md-sys-color-primary, var(--md-sys-color-primary, var(--sicoob-primary-default)));outline-offset:2px}.section-card .mat-mdc-card-content{padding-bottom:var(--px-editor-section-gap, 16px)}.section-breadcrumbs{font-size:12px;color:var(--md-sys-color-on-surface-variant);margin:4px 0 8px;display:flex;align-items:center;gap:6px}.section-breadcrumbs .as-button{background:transparent;border:none;padding:0 2px;color:inherit;font:inherit;cursor:pointer;border-radius:4px}.section-breadcrumbs .as-button:hover{color:var(--md-sys-color-primary, var(--md-sys-color-primary, var(--sicoob-primary-default)))}.section-breadcrumbs .as-button:focus-visible{outline:2px solid var(--md-sys-color-primary, var(--md-sys-color-primary, var(--sicoob-primary-default)));outline-offset:2px}.section-breadcrumbs .crumb-clear{margin-left:6px;opacity:.85}.section-breadcrumbs .crumb.active{color:var(--md-sys-color-on-surface);font-weight:600}.section-breadcrumbs .sep{opacity:.6}.section-header{display:flex;justify-content:space-between;align-items:center;gap:12px;min-height:56px}.title-wrapper{display:flex;align-items:center;gap:8px;width:100%;min-width:0;flex:1 1 auto}.section-heading{display:flex;align-items:center;gap:10px;min-width:0}.section-heading__icon{color:var(--md-sys-color-primary, var(--md-sys-color-primary, var(--sicoob-primary-default)))}.section-heading__avatar{--_pfx-layout-section-avatar-size: var(--pfx-form-section-avatar-size-md, var(--pfx-form-section-avatar-size, 32px));display:inline-flex;align-items:center;justify-content:center;width:var(--_pfx-layout-section-avatar-size);height:var(--_pfx-layout-section-avatar-size);border-radius:999px;flex:0 0 var(--_pfx-layout-section-avatar-size);overflow:hidden}.section-heading__avatar.size-sm{--_pfx-layout-section-avatar-size: var(--pfx-form-section-avatar-size-sm, 24px)}.section-heading__avatar.size-md{--_pfx-layout-section-avatar-size: var(--pfx-form-section-avatar-size-md, var(--pfx-form-section-avatar-size, 32px))}.section-heading__avatar.size-lg{--_pfx-layout-section-avatar-size: var(--pfx-form-section-avatar-size-lg, 40px)}.section-heading__avatar--text,.section-heading__avatar--placeholder{background:color-mix(in srgb,var(--pfx-editorial-form-accent, var(--md-sys-color-primary, var(--sicoob-primary-default))) 14%,var(--pfx-form-section-surface-flat, var(--md-sys-color-surface, var(--sicoob-bg-elev-1))));color:color-mix(in srgb,var(--pfx-editorial-form-accent, var(--md-sys-color-primary, var(--sicoob-primary-default))) 82%,var(--pfx-form-label-strong, var(--md-sys-color-on-surface, var(--sicoob-text-default))) 18%);font-size:calc(var(--_pfx-layout-section-avatar-size) * .41);font-weight:800;letter-spacing:.04em;text-transform:uppercase}.section-heading__avatar--placeholder mat-icon{font-size:calc(var(--_pfx-layout-section-avatar-size) * .5625);width:calc(var(--_pfx-layout-section-avatar-size) * .5625);height:calc(var(--_pfx-layout-section-avatar-size) * .5625);line-height:calc(var(--_pfx-layout-section-avatar-size) * .5625)}.section-heading__text{display:flex;flex-direction:column;align-items:flex-start;min-width:0}.section-heading .section-name{font-weight:600;color:var(--md-sys-color-on-surface);overflow:hidden;text-overflow:ellipsis;white-space:nowrap}.section-heading .section-desc{font-size:12px;color:var(--md-sys-color-on-surface-variant);margin-top:2px;overflow:hidden;text-overflow:ellipsis;white-space:nowrap}.section-editor-trigger{margin-left:auto}.section-header-actions{display:inline-flex;align-items:center;gap:4px;flex-shrink:0}.section-header-actions .mat-mdc-icon-button{width:36px;height:36px;padding:6px}.add-row-button{margin-top:8px}.row-item{animation:fadeIn .3s ease}@keyframes fadeIn{0%{opacity:0;transform:translateY(-4px)}to{opacity:1;transform:none}}.section-card:hover{border-color:var(--md-sys-color-primary, var(--md-sys-color-primary, var(--sicoob-primary-default)))}.section-card.collapsed .mat-mdc-card-content{display:none}:host ::ng-deep .section-card .mat-mdc-card-header{padding:8px 12px}:host ::ng-deep .section-card .mat-mdc-card-title{margin:0}:host ::ng-deep .section-card .mat-mdc-card-content{padding:0 12px 12px}.section-actions{position:relative;margin-top:12px;padding-top:16px;border-top:1px solid var(--md-sys-color-outline-variant, var(--md-sys-color-outline-variant, var(--sicoob-stroke-medium)));min-height:28px}.row-list{border-top:1px solid var(--px-editor-separator-color, var(--md-sys-color-outline-variant));padding-top:12px;margin-top:8px}.fab-add-row{position:absolute;top:-15px;left:50%;transform:translate(-50%,calc(-50% - var(--pfx-divider-w, 1px)));z-index:2;--pfx-fab-size: var(--pfx-fab-size-row, 32px);--pfx-fab-icon: var(--pfx-fab-icon-row, 18px);width:var(--pfx-fab-size);height:var(--pfx-fab-size);border-radius:50%}.fab-add-row.mat-mdc-fab{width:var(--pfx-fab-size);height:var(--pfx-fab-size);padding:0}.fab-add-row .mat-mdc-button-touch-target,.fab-add-row .mat-mdc-button-persistent-ripple,.fab-add-row .mat-mdc-button-ripple{width:var(--pfx-fab-size);height:var(--pfx-fab-size)}.fab-add-row mat-icon{font-size:var(--pfx-fab-icon);width:var(--pfx-fab-icon);height:var(--pfx-fab-icon)}\n"] }]
14753
+ ], template: "<mat-card\n class=\"section-card\"\n cdkDrag\n (mouseenter)=\"onMouseEnter()\"\n (mouseleave)=\"onMouseLeave()\"\n [class.hovered]=\"isHovered\"\n [class.selected]=\"isThisSectionSelected()\"\n [class.collapsed]=\"isCollapsed\"\n (click)=\"onSelectSection()\"\n tabindex=\"0\"\n role=\"button\"\n [attr.aria-label]=\"'Se\u00E7\u00E3o ' + (sectionIndex + 1)\"\n [attr.aria-selected]=\"isThisSectionSelected()\"\n>\n <mat-card-header class=\"section-header\">\n <mat-card-title class=\"title-wrapper\">\n <div class=\"section-heading\">\n @let headerPreview = getSectionHeaderPreview();\n @let headerAvatarSize = getSectionHeaderAvatarSize();\n @if (headerPreview.kind === 'icon') {\n <mat-icon class=\"section-heading__icon\" aria-hidden=\"true\" [praxisIcon]=\"headerPreview.icon\"></mat-icon>\n }\n @if (headerPreview.kind === 'initials') {\n <span class=\"section-heading__avatar section-heading__avatar--text\" [class.size-sm]=\"headerAvatarSize === 'sm'\"\n [class.size-md]=\"headerAvatarSize === 'md'\" [class.size-lg]=\"headerAvatarSize === 'lg'\"\n [matTooltip]=\"headerPreview.tooltip || ''\" [matTooltipDisabled]=\"!headerPreview.tooltip\">\n {{ headerPreview.text }}\n </span>\n }\n @if (headerPreview.kind === 'placeholder') {\n <span class=\"section-heading__avatar section-heading__avatar--placeholder\" [class.size-sm]=\"headerAvatarSize === 'sm'\"\n [class.size-md]=\"headerAvatarSize === 'md'\" [class.size-lg]=\"headerAvatarSize === 'lg'\"\n [matTooltip]=\"headerPreview.tooltip || ''\" [matTooltipDisabled]=\"!headerPreview.tooltip\">\n @if (headerPreview.icon) {\n <mat-icon aria-hidden=\"true\" [praxisIcon]=\"headerPreview.icon\"></mat-icon>\n }\n </span>\n }\n <div class=\"section-heading__text\">\n <span class=\"section-name\">{{ section.title || 'Sem t\u00EDtulo' }}</span>\n <span class=\"section-desc\" *ngIf=\"section.description\">{{ section.description }}</span>\n </div>\n </div>\n <button\n mat-icon-button\n type=\"button\"\n color=\"primary\"\n class=\"section-editor-trigger\"\n (click)=\"openAdvancedEditor($event)\"\n matTooltip=\"Para editar o t\u00EDtulo, use o editor completo da se\u00E7\u00E3o\"\n aria-label=\"Abrir editor da se\u00E7\u00E3o\"\n >\n <mat-icon>open_in_new</mat-icon>\n </button>\n </mat-card-title>\n <div class=\"section-header-actions\">\n <button\n mat-icon-button\n class=\"section-collapse-btn\"\n type=\"button\"\n (click)=\"toggleCollapsed($event)\"\n [attr.aria-expanded]=\"!isCollapsed\"\n [attr.aria-label]=\"isCollapsed ? 'Expandir se\u00E7\u00E3o' : 'Colapsar se\u00E7\u00E3o'\"\n [matTooltip]=\"isCollapsed ? 'Expandir se\u00E7\u00E3o' : 'Colapsar se\u00E7\u00E3o'\"\n >\n <mat-icon>{{ isCollapsed ? 'unfold_more' : 'unfold_less' }}</mat-icon>\n </button>\n <button\n mat-icon-button\n class=\"section-menu-btn\"\n [matMenuTriggerFor]=\"sectionMenu\"\n aria-label=\"Mais a\u00E7\u00F5es da se\u00E7\u00E3o\"\n matTooltip=\"Mais a\u00E7\u00F5es\"\n >\n <mat-icon [praxisIcon]=\"'more_vert'\"></mat-icon>\n </button>\n </div>\n <mat-menu #sectionMenu=\"matMenu\">\n <button mat-menu-item (click)=\"openSectionPresets()\">\n <mat-icon [praxisIcon]=\"'view_quilt'\"></mat-icon>\n <span>Presets de se\u00E7\u00E3o\u2026</span>\n </button>\n <button mat-menu-item (click)=\"applyCurrentStyleToAll()\">\n <mat-icon [praxisIcon]=\"'format_paint'\"></mat-icon>\n <span>Aplicar estilo desta se\u00E7\u00E3o a todas</span>\n </button>\n <mat-divider></mat-divider>\n <button mat-menu-item *ngIf=\"section.description == null\" (click)=\"section.description = ''; onSectionUpdated()\">\n <mat-icon [praxisIcon]=\"'note_add'\"></mat-icon>\n <span>Adicionar descri\u00E7\u00E3o</span>\n </button>\n <button mat-menu-item *ngIf=\"section.description != null\" (click)=\"section.description = undefined; onSectionUpdated()\">\n <mat-icon [praxisIcon]=\"'backspace'\"></mat-icon>\n <span>Remover descri\u00E7\u00E3o</span>\n </button>\n <mat-divider></mat-divider>\n <button mat-menu-item (click)=\"onRemoveSection()\">\n <mat-icon [praxisIcon]=\"'delete'\"></mat-icon>\n <span>Remover se\u00E7\u00E3o</span>\n </button>\n </mat-menu>\n </mat-card-header>\n <mat-card-content [attr.aria-hidden]=\"isCollapsed\">\n <ng-container *ngIf=\"isThisSectionSelected(); else linhasTitle\">\n <div class=\"section-breadcrumbs\" (click)=\"$event.stopPropagation()\">\n <button\n type=\"button\"\n class=\"crumb as-button\"\n data-crumb=\"layout\"\n [attr.aria-label]=\"'Voltar ao Layout'\"\n disabled\n >\n Layout\n </button>\n <span class=\"sep\">\u203A</span>\n <button\n type=\"button\"\n class=\"crumb as-button crumb-section\"\n data-crumb=\"section\"\n (click)=\"onSelectSectionFromBreadcrumb($event)\"\n [attr.aria-label]=\"'Selecionar Se\u00E7\u00E3o ' + (sectionIndex + 1)\"\n >\n Se\u00E7\u00E3o {{ sectionIndex + 1 }}\n </button>\n <ng-container *ngIf=\"selected?.rowIndex != null\">\n <span class=\"sep\">\u203A</span>\n <button\n type=\"button\"\n class=\"crumb as-button crumb-row\"\n data-crumb=\"row\"\n (click)=\"onSelectRowFromBreadcrumb($event)\"\n [attr.aria-label]=\"'Selecionar Linha ' + (selected!.rowIndex! + 1)\"\n >\n Linha {{ selected!.rowIndex! + 1 }}\n </button>\n </ng-container>\n <ng-container *ngIf=\"selected?.columnIndex != null\">\n <span class=\"sep\">\u203A</span>\n <button\n type=\"button\"\n class=\"crumb as-button crumb-column\"\n data-crumb=\"column\"\n (click)=\"onSelectColumnFromBreadcrumb($event)\"\n [attr.aria-label]=\"'Selecionar Coluna ' + (selected!.columnIndex! + 1)\"\n >\n Coluna {{ selected!.columnIndex! + 1 }}\n </button>\n </ng-container>\n <ng-container *ngIf=\"selected?.fieldName\">\n <span class=\"sep\">\u203A</span>\n <span class=\"crumb active\">{{ selected!.fieldName }}</span>\n </ng-container>\n <button\n *ngIf=\"selected\"\n type=\"button\"\n class=\"crumb as-button crumb-clear\"\n data-crumb=\"clear\"\n (click)=\"onClearSelectionFromBreadcrumb($event)\"\n [attr.aria-label]=\"'Limpar sele\u00E7\u00E3o'\"\n >\n Limpar\n </button>\n </div>\n </ng-container>\n <ng-template #linhasTitle>\n <h5>Linhas</h5>\n </ng-template>\n <div\n class=\"row-list\"\n cdkDropList\n [cdkDropListData]=\"section.rows\"\n (cdkDropListDropped)=\"dropRow($event)\"\n >\n <praxis-row-configurator\n *ngFor=\"let row of section.rows; let i = index\"\n class=\"row-item\"\n [row]=\"row\"\n [fieldMetadata]=\"fieldMetadata\"\n [availableFields]=\"availableFields\"\n [sectionIndex]=\"sectionIndex\"\n [rowIndex]=\"i\"\n [isLastRow]=\"i === section.rows.length - 1\"\n [selected]=\"selected\"\n [availableFieldsListId]=\"availableFieldsListId\"\n [connectedDropListIds]=\"columnDropListIds\"\n [gapGlobal]=\"gapGlobal\"\n (rowChange)=\"onRowUpdated(i, $event)\"\n (applyRowGapAll)=\"onApplyRowGapAll($event)\"\n (remove)=\"removeRow(i)\"\n (select)=\"select.emit($event)\"\n (fieldDrop)=\"onFieldDrop($event, i)\"\n (addVisualBlock)=\"onAddVisualBlock($event)\"\n (addApiField)=\"onAddApiField($event)\"\n (editVisualBlock)=\"onEditVisualBlock($event)\"\n (moveVisualBlock)=\"onMoveVisualBlock($event)\"\n (moveVisualBlockToColumn)=\"onMoveVisualBlockToColumn($event)\"\n (removeVisualBlock)=\"onRemoveVisualBlock($event)\"\n cdkDrag\n ></praxis-row-configurator>\n </div>\n <div class=\"section-actions\" aria-label=\"A\u00E7\u00F5es da se\u00E7\u00E3o\">\n <button\n class=\"fab-add-row\"\n mat-fab\n color=\"primary\"\n (click)=\"addRow()\"\n matTooltip=\"Adicionar linha\"\n aria-label=\"Adicionar linha\"\n >\n <mat-icon>add</mat-icon>\n </button>\n </div>\n </mat-card-content>\n</mat-card>\n", styles: ["@charset \"UTF-8\";.section-card{background:var(--md-sys-color-surface, var(--sicoob-bg-elev-1));margin-bottom:16px;transition:border-color .2s ease;border:1px solid transparent}.section-card.hovered{border-color:var(--md-sys-color-primary, var(--md-sys-color-primary, var(--sicoob-primary-default)))}.section-card.selected{border-color:var(--md-sys-color-primary, var(--md-sys-color-primary, var(--sicoob-primary-default)));box-shadow:0 0 0 2px var(--md-sys-color-primary)}.section-card:focus-visible{outline:2px solid var(--md-sys-color-primary, var(--md-sys-color-primary, var(--sicoob-primary-default)));outline-offset:2px}.section-card .mat-mdc-card-content{padding-bottom:var(--px-editor-section-gap, 16px)}.section-breadcrumbs{font-size:12px;color:var(--md-sys-color-on-surface-variant);margin:4px 0 8px;display:flex;align-items:center;gap:6px}.section-breadcrumbs .as-button{background:transparent;border:none;padding:0 2px;color:inherit;font:inherit;cursor:pointer;border-radius:4px}.section-breadcrumbs .as-button:hover{color:var(--md-sys-color-primary, var(--md-sys-color-primary, var(--sicoob-primary-default)))}.section-breadcrumbs .as-button:focus-visible{outline:2px solid var(--md-sys-color-primary, var(--md-sys-color-primary, var(--sicoob-primary-default)));outline-offset:2px}.section-breadcrumbs .crumb-clear{margin-left:6px;opacity:.85}.section-breadcrumbs .crumb.active{color:var(--md-sys-color-on-surface);font-weight:600}.section-breadcrumbs .sep{opacity:.6}.section-header{display:flex;justify-content:space-between;align-items:center;gap:12px;min-height:56px}.title-wrapper{display:flex;align-items:center;gap:8px;width:100%;min-width:0;flex:1 1 auto}.section-heading{display:flex;align-items:center;gap:10px;min-width:0}.section-heading__icon{color:var(--md-sys-color-primary, var(--md-sys-color-primary, var(--sicoob-primary-default)))}.section-heading__avatar{--_pfx-layout-section-avatar-size: var(--pfx-form-section-avatar-size-md, var(--pfx-form-section-avatar-size, 32px));display:inline-flex;align-items:center;justify-content:center;width:var(--_pfx-layout-section-avatar-size);height:var(--_pfx-layout-section-avatar-size);border-radius:999px;flex:0 0 var(--_pfx-layout-section-avatar-size);overflow:hidden}.section-heading__avatar.size-sm{--_pfx-layout-section-avatar-size: var(--pfx-form-section-avatar-size-sm, 24px)}.section-heading__avatar.size-md{--_pfx-layout-section-avatar-size: var(--pfx-form-section-avatar-size-md, var(--pfx-form-section-avatar-size, 32px))}.section-heading__avatar.size-lg{--_pfx-layout-section-avatar-size: var(--pfx-form-section-avatar-size-lg, 40px)}.section-heading__avatar--text,.section-heading__avatar--placeholder{background:color-mix(in srgb,var(--pfx-editorial-form-accent, var(--md-sys-color-primary, var(--sicoob-primary-default))) 14%,var(--pfx-form-section-surface-flat, var(--md-sys-color-surface, var(--sicoob-bg-elev-1))));color:color-mix(in srgb,var(--pfx-editorial-form-accent, var(--md-sys-color-primary, var(--sicoob-primary-default))) 82%,var(--pfx-form-label-strong, var(--md-sys-color-on-surface, var(--sicoob-text-default))) 18%);font-size:calc(var(--_pfx-layout-section-avatar-size) * .41);font-weight:800;letter-spacing:.04em;text-transform:uppercase}.section-heading__avatar--placeholder mat-icon{font-size:calc(var(--_pfx-layout-section-avatar-size) * .5625);width:calc(var(--_pfx-layout-section-avatar-size) * .5625);height:calc(var(--_pfx-layout-section-avatar-size) * .5625);line-height:calc(var(--_pfx-layout-section-avatar-size) * .5625)}.section-heading__text{display:flex;flex-direction:column;align-items:flex-start;min-width:0}.section-heading .section-name{font-weight:600;color:var(--md-sys-color-on-surface);overflow:hidden;text-overflow:ellipsis;white-space:nowrap}.section-heading .section-desc{font-size:12px;color:var(--md-sys-color-on-surface-variant);margin-top:2px;overflow:hidden;text-overflow:ellipsis;white-space:nowrap}.section-editor-trigger{margin-left:auto}.section-header-actions{display:inline-flex;align-items:center;gap:4px;flex-shrink:0}.section-header-actions .mat-mdc-icon-button{width:36px;height:36px;padding:6px}.add-row-button{margin-top:8px}.row-item{animation:fadeIn .3s ease}@keyframes fadeIn{0%{opacity:0;transform:translateY(-4px)}to{opacity:1;transform:none}}.section-card:hover{border-color:var(--md-sys-color-primary, var(--md-sys-color-primary, var(--sicoob-primary-default)))}.section-card.collapsed .mat-mdc-card-content{display:none}:host ::ng-deep .section-card .mat-mdc-card-header{padding:8px 12px}:host ::ng-deep .section-card .mat-mdc-card-title{margin:0}:host ::ng-deep .section-card .mat-mdc-card-content{padding:0 12px 12px}.section-actions{position:relative;margin-top:12px;padding-top:16px;border-top:1px solid var(--md-sys-color-outline-variant, var(--md-sys-color-outline-variant, var(--sicoob-stroke-medium)));min-height:28px}.row-list{border-top:1px solid var(--px-editor-separator-color, var(--md-sys-color-outline-variant));padding-top:12px;margin-top:8px}.fab-add-row{position:absolute;top:-15px;left:50%;transform:translate(-50%,calc(-50% - var(--pfx-divider-w, 1px)));z-index:2;--pfx-fab-size: var(--pfx-fab-size-row, 32px);--pfx-fab-icon: var(--pfx-fab-icon-row, 18px);width:var(--pfx-fab-size);height:var(--pfx-fab-size);border-radius:50%}.fab-add-row.mat-mdc-fab{width:var(--pfx-fab-size);height:var(--pfx-fab-size);padding:0}.fab-add-row .mat-mdc-button-touch-target,.fab-add-row .mat-mdc-button-persistent-ripple,.fab-add-row .mat-mdc-button-ripple{width:var(--pfx-fab-size);height:var(--pfx-fab-size)}.fab-add-row mat-icon{font-size:var(--pfx-fab-icon);width:var(--pfx-fab-icon);height:var(--pfx-fab-icon)}\n"] }]
14070
14754
  }], ctorParameters: () => [{ type: i2$1.MatDialog }, { type: SectionPresetRegistry }, { type: i7.SettingsPanelService }], propDecorators: { section: [{
14071
14755
  type: Input
14072
14756
  }], sectionIndex: [{
@@ -14075,6 +14759,8 @@ i0.ɵɵngDeclareClassMetadata({ minVersion: "12.0.0", version: "20.3.17", ngImpo
14075
14759
  type: Input
14076
14760
  }], fieldMetadata: [{
14077
14761
  type: Input
14762
+ }], availableFields: [{
14763
+ type: Input
14078
14764
  }], selected: [{
14079
14765
  type: Input
14080
14766
  }], availableFieldsListId: [{
@@ -14093,6 +14779,18 @@ i0.ɵɵngDeclareClassMetadata({ minVersion: "12.0.0", version: "20.3.17", ngImpo
14093
14779
  type: Output
14094
14780
  }], fieldDrop: [{
14095
14781
  type: Output
14782
+ }], addVisualBlock: [{
14783
+ type: Output
14784
+ }], addApiField: [{
14785
+ type: Output
14786
+ }], editVisualBlock: [{
14787
+ type: Output
14788
+ }], moveVisualBlock: [{
14789
+ type: Output
14790
+ }], moveVisualBlockToColumn: [{
14791
+ type: Output
14792
+ }], removeVisualBlock: [{
14793
+ type: Output
14096
14794
  }] } });
14097
14795
 
14098
14796
  /** Tokens for theme colors used across the layout editor. */
@@ -14141,6 +14839,10 @@ class LayoutEditorComponent {
14141
14839
  configChange = new EventEmitter();
14142
14840
  paletteCollapsed = false;
14143
14841
  prefs = inject(LayoutPrefsService);
14842
+ layoutService = inject(DynamicFormLayoutService);
14843
+ settingsPanel = inject(SettingsPanelService);
14844
+ i18n = inject(PraxisI18nService);
14845
+ visualBlockIdSequence = 0;
14144
14846
  colorTokens = LayoutColorToken;
14145
14847
  selected = null;
14146
14848
  // Global default for section gap (inherited when not customized)
@@ -14214,12 +14916,15 @@ class LayoutEditorComponent {
14214
14916
  this.config.sections.forEach((s) => {
14215
14917
  s.rows.forEach((r) => {
14216
14918
  r.columns.forEach((c) => {
14217
- c.fields.forEach((f) => placedFieldNames.add(f));
14919
+ getFormColumnFieldNames(c).forEach((fieldName) => placedFieldNames.add(fieldName));
14218
14920
  });
14219
14921
  });
14220
14922
  });
14221
14923
  return visibleFields.filter((f) => !placedFieldNames.has(f.name));
14222
14924
  }
14925
+ t(key, params) {
14926
+ return this.i18n.t(key, params, LAYOUT_EDITOR_DEFAULT_COPY[key] ?? key, LAYOUT_EDITOR_I18N_NAMESPACE);
14927
+ }
14223
14928
  get columnDropListIds() {
14224
14929
  const ids = [];
14225
14930
  this.config.sections.forEach((section, sIdx) => {
@@ -14264,42 +14969,72 @@ class LayoutEditorComponent {
14264
14969
  dropField({ event }) {
14265
14970
  const prevPos = this.parseColumnId(event.previousContainer.id);
14266
14971
  const currentPos = this.parseColumnId(event.container.id);
14267
- const newConfig = produce(this.config, (draft) => {
14268
- if (event.previousContainer.id === 'available-fields-list') {
14269
- if (!currentPos) {
14270
- return;
14271
- }
14272
- const field = event.item.data;
14273
- if (!field) {
14274
- return;
14275
- }
14276
- draft.sections[currentPos.sectionIndex].rows[currentPos.rowIndex].columns[currentPos.columnIndex].fields.splice(event.currentIndex, 0, field.name);
14277
- }
14278
- else if (event.container.id === 'available-fields-list') {
14279
- if (!prevPos) {
14280
- return;
14281
- }
14282
- draft.sections[prevPos.sectionIndex].rows[prevPos.rowIndex].columns[prevPos.columnIndex].fields.splice(event.previousIndex, 1);
14283
- }
14284
- else if (prevPos &&
14285
- currentPos &&
14286
- prevPos.sectionIndex === currentPos.sectionIndex &&
14287
- prevPos.rowIndex === currentPos.rowIndex &&
14288
- prevPos.columnIndex === currentPos.columnIndex) {
14289
- const fields = draft.sections[currentPos.sectionIndex].rows[currentPos.rowIndex]
14290
- .columns[currentPos.columnIndex].fields;
14291
- moveItemInArray(fields, event.previousIndex, event.currentIndex);
14292
- }
14293
- else if (prevPos && currentPos) {
14294
- const prevFields = draft.sections[prevPos.sectionIndex].rows[prevPos.rowIndex].columns[prevPos.columnIndex].fields;
14295
- const currFields = draft.sections[currentPos.sectionIndex].rows[currentPos.rowIndex]
14296
- .columns[currentPos.columnIndex].fields;
14297
- transferArrayItem(prevFields, currFields, event.previousIndex, event.currentIndex);
14298
- }
14299
- });
14300
- this.config = newConfig;
14972
+ let nextConfig = this.layoutService.normalizeConfig(this.config);
14973
+ if (event.previousContainer.id === 'available-fields-list') {
14974
+ if (!currentPos)
14975
+ return;
14976
+ const field = (event.item?.data ??
14977
+ event.previousContainer.data?.[event.previousIndex]);
14978
+ if (!field?.name)
14979
+ return;
14980
+ const target = this.getColumnTargetByIndex(nextConfig, currentPos);
14981
+ if (!target)
14982
+ return;
14983
+ nextConfig = this.layoutService.insertFieldById(nextConfig, target, field.name, event.currentIndex).config;
14984
+ }
14985
+ else if (event.container.id === 'available-fields-list') {
14986
+ if (!prevPos)
14987
+ return;
14988
+ const source = this.getColumnTargetByIndex(nextConfig, prevPos);
14989
+ const fieldName = nextConfig.sections[prevPos.sectionIndex].rows[prevPos.rowIndex]
14990
+ .columns[prevPos.columnIndex].fields?.[event.previousIndex];
14991
+ if (!source || !fieldName)
14992
+ return;
14993
+ nextConfig = this.layoutService.removeFieldById(nextConfig, source.sectionId, source.rowId, source.columnId, fieldName).config;
14994
+ }
14995
+ else if (prevPos && currentPos) {
14996
+ const source = this.getColumnTargetByIndex(nextConfig, prevPos);
14997
+ const target = this.getColumnTargetByIndex(nextConfig, currentPos);
14998
+ const fieldName = nextConfig.sections[prevPos.sectionIndex].rows[prevPos.rowIndex]
14999
+ .columns[prevPos.columnIndex].fields?.[event.previousIndex];
15000
+ if (!source || !target || !fieldName)
15001
+ return;
15002
+ nextConfig = this.layoutService.moveFieldById(nextConfig, { ...source, fieldName }, { ...target, toIndex: event.currentIndex }).config;
15003
+ }
15004
+ this.config = nextConfig;
14301
15005
  this.configChange.emit(this.config);
14302
15006
  }
15007
+ getColumnTargetByIndex(config, pos) {
15008
+ const section = config.sections[pos.sectionIndex];
15009
+ const row = section?.rows?.[pos.rowIndex];
15010
+ const column = row?.columns?.[pos.columnIndex];
15011
+ if (!section?.id || !row?.id || !column?.id)
15012
+ return null;
15013
+ return {
15014
+ sectionId: section.id,
15015
+ rowId: row.id,
15016
+ columnId: column.id,
15017
+ };
15018
+ }
15019
+ getLayoutItemTargetByIndex(config, event) {
15020
+ const section = config.sections[event.sectionIndex];
15021
+ const row = section?.rows?.[event.rowIndex];
15022
+ const column = row?.columns?.[event.columnIndex];
15023
+ if (!section?.id || !row?.id || !column?.id) {
15024
+ return null;
15025
+ }
15026
+ const itemIndex = column.items?.findIndex((item) => item.id === event.itemId) ?? -1;
15027
+ if (itemIndex < 0 || column.items?.[itemIndex]?.kind !== 'richContent') {
15028
+ return null;
15029
+ }
15030
+ return {
15031
+ ...event,
15032
+ sectionId: section.id,
15033
+ rowId: row.id,
15034
+ columnId: column.id,
15035
+ itemIndex,
15036
+ };
15037
+ }
14303
15038
  dropSection(event) {
14304
15039
  const sections = [...this.config.sections];
14305
15040
  if (event.previousContainer === event.container) {
@@ -14341,6 +15076,178 @@ class LayoutEditorComponent {
14341
15076
  catch { }
14342
15077
  this.emitNewConfig({ sections });
14343
15078
  }
15079
+ addVisualBlockToColumn(event) {
15080
+ const normalized = this.layoutService.normalizeConfig(this.config);
15081
+ const section = normalized.sections[event.sectionIndex];
15082
+ const row = section?.rows?.[event.rowIndex];
15083
+ const column = row?.columns?.[event.columnIndex];
15084
+ if (!section?.id || !row?.id || !column?.id) {
15085
+ return;
15086
+ }
15087
+ const item = createVisualBlockItemFromPreset(event.presetId, this.createVisualBlockItemId(), {
15088
+ text: this.t('visualBlock.preset.text.default'),
15089
+ notice: this.t('visualBlock.preset.notice.default'),
15090
+ divider: this.t('visualBlock.preset.divider.default'),
15091
+ infoCardTitle: this.t('visualBlock.preset.infoCard.title'),
15092
+ infoCardBody: this.t('visualBlock.preset.infoCard.body'),
15093
+ });
15094
+ const result = this.layoutService.insertLayoutItemById(normalized, {
15095
+ sectionId: section.id,
15096
+ rowId: row.id,
15097
+ columnId: column.id,
15098
+ }, item);
15099
+ this.config = result.config;
15100
+ this.selected = {
15101
+ type: 'visualBlock',
15102
+ sectionIndex: event.sectionIndex,
15103
+ rowIndex: event.rowIndex,
15104
+ columnIndex: event.columnIndex,
15105
+ itemId: item.id,
15106
+ };
15107
+ this.configChange.emit(this.config);
15108
+ }
15109
+ createVisualBlockItemId() {
15110
+ this.visualBlockIdSequence += 1;
15111
+ const entropy = Math.random().toString(36).slice(2, 9);
15112
+ return `rich-content-${Date.now()}-${this.visualBlockIdSequence}-${entropy}`;
15113
+ }
15114
+ addApiFieldToColumn(event) {
15115
+ if (!event.fieldName)
15116
+ return;
15117
+ if (!this.availableFields.some((field) => field.name === event.fieldName)) {
15118
+ return;
15119
+ }
15120
+ const normalized = this.layoutService.normalizeConfig(this.config);
15121
+ const target = this.getColumnTargetByIndex(normalized, event);
15122
+ if (!target) {
15123
+ return;
15124
+ }
15125
+ const result = this.layoutService.insertFieldById(normalized, target, event.fieldName);
15126
+ this.config = result.config;
15127
+ this.selected = {
15128
+ type: 'field',
15129
+ sectionIndex: event.sectionIndex,
15130
+ rowIndex: event.rowIndex,
15131
+ columnIndex: event.columnIndex,
15132
+ fieldName: event.fieldName,
15133
+ };
15134
+ this.configChange.emit(this.config);
15135
+ }
15136
+ openVisualBlockEditor(event) {
15137
+ const normalized = this.layoutService.normalizeConfig(this.config);
15138
+ const section = normalized.sections[event.sectionIndex];
15139
+ const row = section?.rows?.[event.rowIndex];
15140
+ const column = row?.columns?.[event.columnIndex];
15141
+ const item = column?.items?.find((candidate) => candidate.id === event.itemId);
15142
+ if (!section?.id || !row?.id || !column?.id || item?.kind !== 'richContent') {
15143
+ return;
15144
+ }
15145
+ const ref = this.settingsPanel.open({
15146
+ id: `layout.richContent.${section.id}.${row.id}.${column.id}.${item.id}`,
15147
+ title: this.t('visualBlock.editTitle'),
15148
+ titleIcon: 'notes',
15149
+ content: {
15150
+ component: PraxisRichContentConfigEditor,
15151
+ inputs: {
15152
+ inputs: {
15153
+ document: item.document,
15154
+ layout: item.layout ?? 'block',
15155
+ rootClassName: item.rootClassName ?? null,
15156
+ },
15157
+ },
15158
+ },
15159
+ });
15160
+ const applyValue = (value) => {
15161
+ if (!value?.inputs?.document)
15162
+ return;
15163
+ const currentConfig = this.layoutService.normalizeConfig(this.config);
15164
+ const currentColumn = currentConfig.sections
15165
+ .find((candidate) => candidate.id === section.id)
15166
+ ?.rows?.find((candidate) => candidate.id === row.id)
15167
+ ?.columns?.find((candidate) => candidate.id === column.id);
15168
+ const currentItem = currentColumn?.items?.find((candidate) => candidate.id === item.id);
15169
+ if (currentItem?.kind !== 'richContent')
15170
+ return;
15171
+ const result = this.layoutService.updateLayoutItemById(currentConfig, {
15172
+ sectionId: section.id,
15173
+ rowId: row.id,
15174
+ columnId: column.id,
15175
+ itemId: item.id,
15176
+ }, {
15177
+ ...currentItem,
15178
+ document: value.inputs.document,
15179
+ layout: value.inputs.layout ?? 'block',
15180
+ rootClassName: value.inputs.rootClassName ?? null,
15181
+ });
15182
+ this.config = result.config;
15183
+ this.configChange.emit(this.config);
15184
+ };
15185
+ ref.applied$?.subscribe(applyValue);
15186
+ ref.saved$?.subscribe(applyValue);
15187
+ }
15188
+ moveVisualBlock(event) {
15189
+ const normalized = this.layoutService.normalizeConfig(this.config);
15190
+ const target = this.getLayoutItemTargetByIndex(normalized, event);
15191
+ if (!target) {
15192
+ return;
15193
+ }
15194
+ const toIndex = target.itemIndex + event.direction;
15195
+ const itemCount = normalized.sections[event.sectionIndex].rows[event.rowIndex]
15196
+ .columns[event.columnIndex].items?.length ?? 0;
15197
+ if (toIndex < 0 || toIndex >= itemCount) {
15198
+ return;
15199
+ }
15200
+ const result = this.layoutService.moveLayoutItemById(normalized, {
15201
+ sectionId: target.sectionId,
15202
+ rowId: target.rowId,
15203
+ columnId: target.columnId,
15204
+ itemId: event.itemId,
15205
+ }, {
15206
+ sectionId: target.sectionId,
15207
+ rowId: target.rowId,
15208
+ columnId: target.columnId,
15209
+ toIndex,
15210
+ }, { policy: 'keepEmptyContainers' });
15211
+ this.config = result.config;
15212
+ this.configChange.emit(this.config);
15213
+ }
15214
+ moveVisualBlockToColumn(event) {
15215
+ const normalized = this.layoutService.normalizeConfig(this.config);
15216
+ const source = this.getLayoutItemTargetByIndex(normalized, event);
15217
+ const target = this.getColumnTargetByIndex(normalized, {
15218
+ sectionIndex: event.sectionIndex,
15219
+ rowIndex: event.rowIndex,
15220
+ columnIndex: event.targetColumnIndex,
15221
+ });
15222
+ const targetColumn = normalized.sections[event.sectionIndex]?.rows?.[event.rowIndex]
15223
+ ?.columns?.[event.targetColumnIndex];
15224
+ if (!source || !target || !targetColumn) {
15225
+ return;
15226
+ }
15227
+ const result = this.layoutService.moveLayoutItemById(normalized, {
15228
+ sectionId: source.sectionId,
15229
+ rowId: source.rowId,
15230
+ columnId: source.columnId,
15231
+ itemId: event.itemId,
15232
+ }, {
15233
+ sectionId: target.sectionId,
15234
+ rowId: target.rowId,
15235
+ columnId: target.columnId,
15236
+ toIndex: targetColumn.items?.length ?? 0,
15237
+ }, { policy: 'keepEmptyContainers' });
15238
+ this.config = result.config;
15239
+ this.configChange.emit(this.config);
15240
+ }
15241
+ removeVisualBlock(event) {
15242
+ const normalized = this.layoutService.normalizeConfig(this.config);
15243
+ const target = this.getLayoutItemTargetByIndex(normalized, event);
15244
+ if (!target) {
15245
+ return;
15246
+ }
15247
+ const result = this.layoutService.removeLayoutItemById(normalized, target.sectionId, target.rowId, target.columnId, event.itemId, { policy: 'keepEmptyContainers' });
15248
+ this.config = result.config;
15249
+ this.configChange.emit(this.config);
15250
+ }
14344
15251
  emitNewConfig(configChanges) {
14345
15252
  const newConfig = {
14346
15253
  ...this.config,
@@ -14357,7 +15264,7 @@ class LayoutEditorComponent {
14357
15264
  return s.id ?? index;
14358
15265
  }
14359
15266
  static ɵfac = i0.ɵɵngDeclareFactory({ minVersion: "12.0.0", version: "20.3.17", ngImport: i0, type: LayoutEditorComponent, deps: [], target: i0.ɵɵFactoryTarget.Component });
14360
- static ɵcmp = i0.ɵɵngDeclareComponent({ minVersion: "14.0.0", version: "20.3.17", type: LayoutEditorComponent, isStandalone: true, selector: "praxis-layout-editor", inputs: { config: "config" }, outputs: { configChange: "configChange", select: "select" }, host: { listeners: { "document:keydown": "handleKeydown($event)" } }, ngImport: i0, template: `
15267
+ static ɵcmp = i0.ɵɵngDeclareComponent({ minVersion: "14.0.0", version: "20.3.17", type: LayoutEditorComponent, isStandalone: true, selector: "praxis-layout-editor", inputs: { config: "config" }, outputs: { configChange: "configChange", select: "select" }, host: { listeners: { "document:keydown": "handleKeydown($event)" } }, providers: [providePraxisI18nConfig(LAYOUT_EDITOR_I18N_CONFIG)], ngImport: i0, template: `
14361
15268
  <div class="layout-editor-wrapper"
14362
15269
  cdkDropListGroup
14363
15270
  [class.no-available-fields]="!availableFields.length"
@@ -14446,8 +15353,8 @@ class LayoutEditorComponent {
14446
15353
  >
14447
15354
  <mat-icon>chevron_right</mat-icon>
14448
15355
  </button>
14449
- <h4>Campos disponíveis</h4>
14450
- <small class="available-fields__hint">Arraste para montar seções.</small>
15356
+ <h4>{{ t('apiFields.heading') }}</h4>
15357
+ <small class="available-fields__hint">{{ t('apiFields.hint') }}</small>
14451
15358
  <div
14452
15359
  cdkDropList
14453
15360
  id="available-fields-list"
@@ -14472,8 +15379,12 @@ class LayoutEditorComponent {
14472
15379
  <mat-icon>chevron_left</mat-icon>
14473
15380
  </button>
14474
15381
  <div class="layout-canvas">
14475
- <div class="no-fields-chip" *ngIf="!availableFields.length">
14476
- Nenhum campo disponível
15382
+ <div
15383
+ class="no-fields-chip"
15384
+ data-testid="layout-editor-api-fields-empty"
15385
+ *ngIf="!availableFields.length"
15386
+ >
15387
+ {{ t('apiFields.empty') }}
14477
15388
  </div>
14478
15389
  <div
14479
15390
  cdkDropList
@@ -14487,6 +15398,7 @@ class LayoutEditorComponent {
14487
15398
  [sectionIndex]="i"
14488
15399
  [allSections]="config.sections"
14489
15400
  [fieldMetadata]="config.fieldMetadata || []"
15401
+ [availableFields]="availableFields"
14490
15402
  [selected]="selected"
14491
15403
  [gapGlobal]="gapGlobal || 16"
14492
15404
  [availableFieldsListId]="
@@ -14498,6 +15410,12 @@ class LayoutEditorComponent {
14498
15410
  (sectionChange)="onSectionUpdated(i, $event)"
14499
15411
  (applyStyleToAll)="onApplyStyleToAll($event)"
14500
15412
  (fieldDrop)="dropField($event)"
15413
+ (addVisualBlock)="addVisualBlockToColumn($event)"
15414
+ (addApiField)="addApiFieldToColumn($event)"
15415
+ (editVisualBlock)="openVisualBlockEditor($event)"
15416
+ (moveVisualBlock)="moveVisualBlock($event)"
15417
+ (moveVisualBlockToColumn)="moveVisualBlockToColumn($event)"
15418
+ (removeVisualBlock)="removeVisualBlock($event)"
14501
15419
  cdkDrag
14502
15420
  ></praxis-section-configurator>
14503
15421
  </div>
@@ -14515,7 +15433,7 @@ class LayoutEditorComponent {
14515
15433
  </div>
14516
15434
  </div>
14517
15435
  </div>
14518
- `, isInline: true, styles: [".layout-editor-wrapper{display:flex;flex-wrap:wrap;gap:16px}.layout-editor-wrapper.no-available-fields{gap:0}.editor-toolbar{position:sticky;top:0;z-index:3;display:flex;gap:16px;align-items:center;min-height:56px;background:var(--md-sys-color-surface-container);border-bottom:1px solid var(--md-sys-color-outline-variant);box-shadow:var(--md-sys-elevation-level1, var(--md-sys-elevation-level1));padding:0 12px;margin:0 0 var(--px-editor-section-gap, 16px) 0}.editor-toolbar .title-block{display:flex;flex-direction:column;justify-content:center;gap:2px}.editor-toolbar .toolbar-title{font:var(--mdc-typography-title-small, 600 15px/20px system-ui);color:var(--md-sys-color-on-surface)}.editor-toolbar .toolbar-subtitle{font:var(--mdc-typography-body-small, 400 12px/16px system-ui);color:var(--md-sys-color-on-surface-variant)}.editor-toolbar .spacer{flex:1 1 auto}.editor-toolbar .toolbar-group{display:inline-flex;align-items:center;gap:8px;flex-wrap:wrap}.editor-toolbar .gap-group{align-items:center}.editor-toolbar .group-label{font:var(--mdc-typography-label-medium, 500 12px/16px system-ui);color:var(--md-sys-color-on-surface-variant)}.editor-toolbar .gap-group{align-items:center;gap:10px}.editor-toolbar .density-control{display:flex;align-items:center;gap:8px}.editor-toolbar .density-label{font:var(--mdc-typography-label-medium, 500 12px/16px system-ui);opacity:.9}.editor-toolbar .density-toggle,.editor-toolbar .toggle-icons-group{border:1px solid var(--md-sys-color-outline-variant);border-radius:999px;overflow:hidden;background:var(--md-sys-color-surface-container-low)}.editor-toolbar .density-toggle .mat-button-toggle,.editor-toolbar .toggle-icons-group .mat-button-toggle{background:var(--md-sys-color-surface-container-low);color:var(--md-sys-color-on-surface-variant)}.editor-toolbar .density-toggle .mat-button-toggle+.mat-button-toggle,.editor-toolbar .toggle-icons-group .mat-button-toggle+.mat-button-toggle{border-left:1px solid var(--md-sys-color-outline-variant)}.editor-toolbar .density-toggle .mat-button-toggle-button,.toggle-icons-group .mat-button-toggle-button{height:32px}.editor-toolbar .density-toggle .mat-icon,.toggle-icons-group .mat-icon{font-size:20px;width:20px;height:20px;line-height:20px}.editor-toolbar .density-toggle .mat-icon,.editor-toolbar .toggle-icons-group .mat-icon{color:inherit}.gap-chip{display:inline-flex;align-items:center;gap:2px;padding:0 4px;height:32px;border-radius:8px;border:1px solid var(--md-sys-color-outline-variant);background:var(--md-sys-color-surface-variant)}.gap-chip__btn{width:24px;height:24px;line-height:24px;min-width:0;padding:0;--mdc-icon-button-size: 24px;--mdc-icon-button-state-layer-size: 24px}.gap-chip .mat-mdc-button-touch-target{width:24px;height:24px}.gap-chip mat-icon{font-size:16px;width:16px;height:16px;line-height:16px}.gap-chip__input{width:42px;border:none;background:transparent;color:var(--md-sys-color-on-surface);font:var(--mdc-typography-body-medium, 600 13px/18px system-ui);text-align:center;outline:none;-moz-appearance:textfield}.gap-chip__input::-webkit-outer-spin-button,.gap-chip__input::-webkit-inner-spin-button{-webkit-appearance:none;margin:0}.gap-chip__suffix{color:var(--md-sys-color-on-surface-variant);font:var(--mdc-typography-label-medium, 500 12px/16px system-ui)}.pill{display:inline-flex;align-items:center;gap:6px;padding:4px 8px;border-radius:12px;background:var(--md-sys-color-surface-variant);color:var(--md-sys-color-on-surface-variant);font-size:12px}.pill.subtle{background:transparent;color:var(--md-sys-color-on-surface-variant);padding-left:0}.available-fields{width:250px;border:1px solid var(--md-sys-color-outline-variant);border-radius:12px;padding:10px;background:var(--md-sys-color-surface)}.collapse-toggle{float:right}.available-fields__hint{display:block;margin-bottom:8px;color:var(--md-sys-color-on-surface-variant);font-size:12px}.no-fields-chip{position:absolute;top:8px;right:8px;padding:4px 8px;border:1px dashed var(--md-sys-color-outline);border-radius:16px;color:var(--md-sys-color-outline);font-size:12px;background:var(--md-sys-color-surface);pointer-events:none}.layout-canvas{flex-grow:1;overflow:visible;max-height:none;position:relative}.field-list{min-height:100px}.section-list{display:flex;flex-direction:column;gap:var(--pfx-section-gap, 20px)}.add-section-container{position:relative;padding-top:16px;margin-top:12px;border-top:1px solid var(--md-sys-color-outline-variant);min-height:28px}.fab-add-section{position:absolute;top:-30px;left:50%;transform:translate(-50%,calc(-50% - var(--pfx-divider-w, 1px)));z-index:2;--pfx-fab-size: var(--pfx-fab-size-section, 32px);--pfx-fab-icon: var(--pfx-fab-icon-section, 18px);width:var(--pfx-fab-size);height:var(--pfx-fab-size);border-radius:50%}.fab-add-section mat-icon{font-size:var(--pfx-fab-icon);width:var(--pfx-fab-icon);height:var(--pfx-fab-icon)}.fab-add-section.mat-mdc-fab{width:var(--pfx-fab-size);height:var(--pfx-fab-size);padding:0}.fab-add-section .mat-mdc-button-touch-target,.fab-add-section .mat-mdc-button-persistent-ripple,.fab-add-section .mat-mdc-button-ripple{width:var(--pfx-fab-size);height:var(--pfx-fab-size)}.cdk-drag-placeholder{opacity:.3;transition:opacity .2s ease}:host ::ng-deep .mdc-text-field--filled{--mdc-filled-text-field-container-color: var(--md-sys-color-surface-container)}:host ::ng-deep .mdc-text-field__input::placeholder{color:var(--md-sys-color-on-surface-variant)!important;opacity:.95}:host ::ng-deep .mat-mdc-form-field-subscript-wrapper,:host ::ng-deep .mat-mdc-hint{color:var(--md-sys-color-on-surface-variant)!important}:host ::ng-deep .mdc-text-field--disabled .mdc-text-field__input,:host ::ng-deep .mat-mdc-select-disabled .mat-mdc-select-value{color:var(--md-sys-color-on-surface-variant)!important}:host ::ng-deep .mat-button-toggle-checked{background:var(--md-sys-color-primary-container)!important;color:var(--md-sys-color-on-primary-container)!important}:host ::ng-deep .editor-toolbar .mat-button-toggle-appearance-standard{color:var(--md-sys-color-on-surface-variant)}:host ::ng-deep .editor-toolbar .mat-button-toggle-appearance-standard:hover{background:var(--md-sys-color-surface-container-high);color:var(--md-sys-color-on-surface)}:host ::ng-deep .editor-toolbar .mat-button-toggle-checked:hover{background:var(--md-sys-color-primary-container)!important;color:var(--md-sys-color-on-primary-container)!important}:host{--px-editor-section-gap: 16px;--pfx-grid-gap: 12px;--pfx-section-gap: var(--px-editor-section-gap)}@media(min-width:960px){:host{--px-editor-section-gap: 20px;--pfx-grid-gap: 16px}}@media(min-width:1280px){:host{--px-editor-section-gap: 24px;--pfx-grid-gap: 20px}}\n"], dependencies: [{ kind: "ngmodule", type: CommonModule }, { kind: "directive", type: i1$1.NgForOf, selector: "[ngFor][ngForOf]", inputs: ["ngForOf", "ngForTrackBy", "ngForTemplate"] }, { kind: "directive", type: i1$1.NgIf, selector: "[ngIf]", inputs: ["ngIf", "ngIfThen", "ngIfElse"] }, { kind: "directive", type: i1$1.NgStyle, selector: "[ngStyle]", inputs: ["ngStyle"] }, { kind: "ngmodule", type: DragDropModule }, { kind: "directive", type: i2$2.CdkDropList, selector: "[cdkDropList], cdk-drop-list", inputs: ["cdkDropListConnectedTo", "cdkDropListData", "cdkDropListOrientation", "id", "cdkDropListLockAxis", "cdkDropListDisabled", "cdkDropListSortingDisabled", "cdkDropListEnterPredicate", "cdkDropListSortPredicate", "cdkDropListAutoScrollDisabled", "cdkDropListAutoScrollStep", "cdkDropListElementContainer", "cdkDropListHasAnchor"], outputs: ["cdkDropListDropped", "cdkDropListEntered", "cdkDropListExited", "cdkDropListSorted"], exportAs: ["cdkDropList"] }, { kind: "directive", type: i2$2.CdkDropListGroup, selector: "[cdkDropListGroup]", inputs: ["cdkDropListGroupDisabled"], exportAs: ["cdkDropListGroup"] }, { kind: "directive", type: i2$2.CdkDrag, selector: "[cdkDrag]", inputs: ["cdkDragData", "cdkDragLockAxis", "cdkDragRootElement", "cdkDragBoundary", "cdkDragStartDelay", "cdkDragFreeDragPosition", "cdkDragDisabled", "cdkDragConstrainPosition", "cdkDragPreviewClass", "cdkDragPreviewContainer", "cdkDragScale"], outputs: ["cdkDragStarted", "cdkDragReleased", "cdkDragEnded", "cdkDragEntered", "cdkDragExited", "cdkDragDropped", "cdkDragMoved"], exportAs: ["cdkDrag"] }, { kind: "ngmodule", type: ScrollingModule }, { kind: "component", type: SectionConfiguratorComponent, selector: "praxis-section-configurator", inputs: ["section", "sectionIndex", "allSections", "fieldMetadata", "selected", "availableFieldsListId", "columnDropListIds", "gapGlobal"], outputs: ["sectionChange", "applyStyleToAll", "remove", "select", "fieldDrop"] }, { kind: "component", type: FieldConfiguratorComponent, selector: "praxis-field-configurator", inputs: ["field"] }, { kind: "ngmodule", type: MatButtonModule }, { kind: "component", type: i4.MatIconButton, selector: "button[mat-icon-button], a[mat-icon-button], button[matIconButton], a[matIconButton]", exportAs: ["matButton", "matAnchor"] }, { kind: "component", type: i4.MatFabButton, selector: "button[mat-fab], a[mat-fab], button[matFab], a[matFab]", inputs: ["extended"], exportAs: ["matButton", "matAnchor"] }, { kind: "ngmodule", type: MatIconModule }, { kind: "component", type: i5.MatIcon, selector: "mat-icon", inputs: ["color", "inline", "svgIcon", "fontSet", "fontIcon"], exportAs: ["matIcon"] }, { kind: "ngmodule", type: MatTooltipModule }, { kind: "directive", type: i9.MatTooltip, selector: "[matTooltip]", inputs: ["matTooltipPosition", "matTooltipPositionAtOrigin", "matTooltipDisabled", "matTooltipShowDelay", "matTooltipHideDelay", "matTooltipTouchGestures", "matTooltip", "matTooltipClass"], exportAs: ["matTooltip"] }, { kind: "ngmodule", type: MatToolbarModule }, { kind: "component", type: i6$1.MatToolbar, selector: "mat-toolbar", inputs: ["color"], exportAs: ["matToolbar"] }, { kind: "ngmodule", type: MatButtonToggleModule }, { kind: "directive", type: i7$2.MatButtonToggleGroup, selector: "mat-button-toggle-group", inputs: ["appearance", "name", "vertical", "value", "multiple", "disabled", "disabledInteractive", "hideSingleSelectionIndicator", "hideMultipleSelectionIndicator"], outputs: ["valueChange", "change"], exportAs: ["matButtonToggleGroup"] }, { kind: "component", type: i7$2.MatButtonToggle, selector: "mat-button-toggle", inputs: ["aria-label", "aria-labelledby", "id", "name", "value", "tabIndex", "disableRipple", "appearance", "checked", "disabled", "disabledInteractive"], outputs: ["change"], exportAs: ["matButtonToggle"] }, { kind: "ngmodule", type: FormsModule }, { kind: "directive", type: i1$3.DefaultValueAccessor, selector: "input:not([type=checkbox])[formControlName],textarea[formControlName],input:not([type=checkbox])[formControl],textarea[formControl],input:not([type=checkbox])[ngModel],textarea[ngModel],[ngDefaultControl]" }, { kind: "directive", type: i1$3.NumberValueAccessor, selector: "input[type=number][formControlName],input[type=number][formControl],input[type=number][ngModel]" }, { kind: "directive", type: i1$3.NgControlStatus, selector: "[formControlName],[ngModel],[formControl]" }, { kind: "directive", type: i1$3.MinValidator, selector: "input[type=number][min][formControlName],input[type=number][min][formControl],input[type=number][min][ngModel]", inputs: ["min"] }, { kind: "directive", type: i1$3.NgModel, selector: "[ngModel]:not([formControlName]):not([formControl])", inputs: ["name", "disabled", "ngModel", "ngModelOptions"], outputs: ["ngModelChange"], exportAs: ["ngModel"] }] });
15436
+ `, isInline: true, styles: [".layout-editor-wrapper{display:flex;flex-wrap:wrap;gap:16px}.layout-editor-wrapper.no-available-fields{gap:0}.editor-toolbar{position:sticky;top:0;z-index:3;display:flex;gap:16px;align-items:center;min-height:56px;background:var(--md-sys-color-surface-container);border-bottom:1px solid var(--md-sys-color-outline-variant);box-shadow:var(--md-sys-elevation-level1, var(--md-sys-elevation-level1));padding:0 12px;margin:0 0 var(--px-editor-section-gap, 16px) 0}.editor-toolbar .title-block{display:flex;flex-direction:column;justify-content:center;gap:2px}.editor-toolbar .toolbar-title{font:var(--mdc-typography-title-small, 600 15px/20px system-ui);color:var(--md-sys-color-on-surface)}.editor-toolbar .toolbar-subtitle{font:var(--mdc-typography-body-small, 400 12px/16px system-ui);color:var(--md-sys-color-on-surface-variant)}.editor-toolbar .spacer{flex:1 1 auto}.editor-toolbar .toolbar-group{display:inline-flex;align-items:center;gap:8px;flex-wrap:wrap}.editor-toolbar .gap-group{align-items:center}.editor-toolbar .group-label{font:var(--mdc-typography-label-medium, 500 12px/16px system-ui);color:var(--md-sys-color-on-surface-variant)}.editor-toolbar .gap-group{align-items:center;gap:10px}.editor-toolbar .density-control{display:flex;align-items:center;gap:8px}.editor-toolbar .density-label{font:var(--mdc-typography-label-medium, 500 12px/16px system-ui);opacity:.9}.editor-toolbar .density-toggle,.editor-toolbar .toggle-icons-group{border:1px solid var(--md-sys-color-outline-variant);border-radius:999px;overflow:hidden;background:var(--md-sys-color-surface-container-low)}.editor-toolbar .density-toggle .mat-button-toggle,.editor-toolbar .toggle-icons-group .mat-button-toggle{background:var(--md-sys-color-surface-container-low);color:var(--md-sys-color-on-surface-variant)}.editor-toolbar .density-toggle .mat-button-toggle+.mat-button-toggle,.editor-toolbar .toggle-icons-group .mat-button-toggle+.mat-button-toggle{border-left:1px solid var(--md-sys-color-outline-variant)}.editor-toolbar .density-toggle .mat-button-toggle-button,.toggle-icons-group .mat-button-toggle-button{height:32px}.editor-toolbar .density-toggle .mat-icon,.toggle-icons-group .mat-icon{font-size:20px;width:20px;height:20px;line-height:20px}.editor-toolbar .density-toggle .mat-icon,.editor-toolbar .toggle-icons-group .mat-icon{color:inherit}.gap-chip{display:inline-flex;align-items:center;gap:2px;padding:0 4px;height:32px;border-radius:8px;border:1px solid var(--md-sys-color-outline-variant);background:var(--md-sys-color-surface-variant)}.gap-chip__btn{width:24px;height:24px;line-height:24px;min-width:0;padding:0;--mdc-icon-button-size: 24px;--mdc-icon-button-state-layer-size: 24px}.gap-chip .mat-mdc-button-touch-target{width:24px;height:24px}.gap-chip mat-icon{font-size:16px;width:16px;height:16px;line-height:16px}.gap-chip__input{width:42px;border:none;background:transparent;color:var(--md-sys-color-on-surface);font:var(--mdc-typography-body-medium, 600 13px/18px system-ui);text-align:center;outline:none;-moz-appearance:textfield}.gap-chip__input::-webkit-outer-spin-button,.gap-chip__input::-webkit-inner-spin-button{-webkit-appearance:none;margin:0}.gap-chip__suffix{color:var(--md-sys-color-on-surface-variant);font:var(--mdc-typography-label-medium, 500 12px/16px system-ui)}.pill{display:inline-flex;align-items:center;gap:6px;padding:4px 8px;border-radius:12px;background:var(--md-sys-color-surface-variant);color:var(--md-sys-color-on-surface-variant);font-size:12px}.pill.subtle{background:transparent;color:var(--md-sys-color-on-surface-variant);padding-left:0}.available-fields{width:250px;border:1px solid var(--md-sys-color-outline-variant);border-radius:12px;padding:10px;background:var(--md-sys-color-surface)}.collapse-toggle{float:right}.available-fields__hint{display:block;margin-bottom:8px;color:var(--md-sys-color-on-surface-variant);font-size:12px}.no-fields-chip{position:absolute;top:8px;right:8px;padding:4px 8px;border:1px dashed var(--md-sys-color-outline);border-radius:16px;color:var(--md-sys-color-outline);font-size:12px;background:var(--md-sys-color-surface);pointer-events:none}.layout-canvas{flex-grow:1;overflow:visible;max-height:none;position:relative}.field-list{min-height:100px}.section-list{display:flex;flex-direction:column;gap:var(--pfx-section-gap, 20px)}.add-section-container{position:relative;padding-top:16px;margin-top:12px;border-top:1px solid var(--md-sys-color-outline-variant);min-height:28px}.fab-add-section{position:absolute;top:-30px;left:50%;transform:translate(-50%,calc(-50% - var(--pfx-divider-w, 1px)));z-index:2;--pfx-fab-size: var(--pfx-fab-size-section, 32px);--pfx-fab-icon: var(--pfx-fab-icon-section, 18px);width:var(--pfx-fab-size);height:var(--pfx-fab-size);border-radius:50%}.fab-add-section mat-icon{font-size:var(--pfx-fab-icon);width:var(--pfx-fab-icon);height:var(--pfx-fab-icon)}.fab-add-section.mat-mdc-fab{width:var(--pfx-fab-size);height:var(--pfx-fab-size);padding:0}.fab-add-section .mat-mdc-button-touch-target,.fab-add-section .mat-mdc-button-persistent-ripple,.fab-add-section .mat-mdc-button-ripple{width:var(--pfx-fab-size);height:var(--pfx-fab-size)}.cdk-drag-placeholder{opacity:.3;transition:opacity .2s ease}:host ::ng-deep .mdc-text-field--filled{--mdc-filled-text-field-container-color: var(--md-sys-color-surface-container)}:host ::ng-deep .mdc-text-field__input::placeholder{color:var(--md-sys-color-on-surface-variant)!important;opacity:.95}:host ::ng-deep .mat-mdc-form-field-subscript-wrapper,:host ::ng-deep .mat-mdc-hint{color:var(--md-sys-color-on-surface-variant)!important}:host ::ng-deep .mdc-text-field--disabled .mdc-text-field__input,:host ::ng-deep .mat-mdc-select-disabled .mat-mdc-select-value{color:var(--md-sys-color-on-surface-variant)!important}:host ::ng-deep .mat-button-toggle-checked{background:var(--md-sys-color-primary-container)!important;color:var(--md-sys-color-on-primary-container)!important}:host ::ng-deep .editor-toolbar .mat-button-toggle-appearance-standard{color:var(--md-sys-color-on-surface-variant)}:host ::ng-deep .editor-toolbar .mat-button-toggle-appearance-standard:hover{background:var(--md-sys-color-surface-container-high);color:var(--md-sys-color-on-surface)}:host ::ng-deep .editor-toolbar .mat-button-toggle-checked:hover{background:var(--md-sys-color-primary-container)!important;color:var(--md-sys-color-on-primary-container)!important}:host{--px-editor-section-gap: 16px;--pfx-grid-gap: 12px;--pfx-section-gap: var(--px-editor-section-gap)}@media(min-width:960px){:host{--px-editor-section-gap: 20px;--pfx-grid-gap: 16px}}@media(min-width:1280px){:host{--px-editor-section-gap: 24px;--pfx-grid-gap: 20px}}\n"], dependencies: [{ kind: "ngmodule", type: CommonModule }, { kind: "directive", type: i1$1.NgForOf, selector: "[ngFor][ngForOf]", inputs: ["ngForOf", "ngForTrackBy", "ngForTemplate"] }, { kind: "directive", type: i1$1.NgIf, selector: "[ngIf]", inputs: ["ngIf", "ngIfThen", "ngIfElse"] }, { kind: "directive", type: i1$1.NgStyle, selector: "[ngStyle]", inputs: ["ngStyle"] }, { kind: "ngmodule", type: DragDropModule }, { kind: "directive", type: i2$2.CdkDropList, selector: "[cdkDropList], cdk-drop-list", inputs: ["cdkDropListConnectedTo", "cdkDropListData", "cdkDropListOrientation", "id", "cdkDropListLockAxis", "cdkDropListDisabled", "cdkDropListSortingDisabled", "cdkDropListEnterPredicate", "cdkDropListSortPredicate", "cdkDropListAutoScrollDisabled", "cdkDropListAutoScrollStep", "cdkDropListElementContainer", "cdkDropListHasAnchor"], outputs: ["cdkDropListDropped", "cdkDropListEntered", "cdkDropListExited", "cdkDropListSorted"], exportAs: ["cdkDropList"] }, { kind: "directive", type: i2$2.CdkDropListGroup, selector: "[cdkDropListGroup]", inputs: ["cdkDropListGroupDisabled"], exportAs: ["cdkDropListGroup"] }, { kind: "directive", type: i2$2.CdkDrag, selector: "[cdkDrag]", inputs: ["cdkDragData", "cdkDragLockAxis", "cdkDragRootElement", "cdkDragBoundary", "cdkDragStartDelay", "cdkDragFreeDragPosition", "cdkDragDisabled", "cdkDragConstrainPosition", "cdkDragPreviewClass", "cdkDragPreviewContainer", "cdkDragScale"], outputs: ["cdkDragStarted", "cdkDragReleased", "cdkDragEnded", "cdkDragEntered", "cdkDragExited", "cdkDragDropped", "cdkDragMoved"], exportAs: ["cdkDrag"] }, { kind: "ngmodule", type: ScrollingModule }, { kind: "component", type: SectionConfiguratorComponent, selector: "praxis-section-configurator", inputs: ["section", "sectionIndex", "allSections", "fieldMetadata", "availableFields", "selected", "availableFieldsListId", "columnDropListIds", "gapGlobal"], outputs: ["sectionChange", "applyStyleToAll", "remove", "select", "fieldDrop", "addVisualBlock", "addApiField", "editVisualBlock", "moveVisualBlock", "moveVisualBlockToColumn", "removeVisualBlock"] }, { kind: "component", type: FieldConfiguratorComponent, selector: "praxis-field-configurator", inputs: ["field"] }, { kind: "ngmodule", type: MatButtonModule }, { kind: "component", type: i4.MatIconButton, selector: "button[mat-icon-button], a[mat-icon-button], button[matIconButton], a[matIconButton]", exportAs: ["matButton", "matAnchor"] }, { kind: "component", type: i4.MatFabButton, selector: "button[mat-fab], a[mat-fab], button[matFab], a[matFab]", inputs: ["extended"], exportAs: ["matButton", "matAnchor"] }, { kind: "ngmodule", type: MatIconModule }, { kind: "component", type: i5.MatIcon, selector: "mat-icon", inputs: ["color", "inline", "svgIcon", "fontSet", "fontIcon"], exportAs: ["matIcon"] }, { kind: "ngmodule", type: MatTooltipModule }, { kind: "directive", type: i9.MatTooltip, selector: "[matTooltip]", inputs: ["matTooltipPosition", "matTooltipPositionAtOrigin", "matTooltipDisabled", "matTooltipShowDelay", "matTooltipHideDelay", "matTooltipTouchGestures", "matTooltip", "matTooltipClass"], exportAs: ["matTooltip"] }, { kind: "ngmodule", type: MatToolbarModule }, { kind: "component", type: i6$1.MatToolbar, selector: "mat-toolbar", inputs: ["color"], exportAs: ["matToolbar"] }, { kind: "ngmodule", type: MatButtonToggleModule }, { kind: "directive", type: i7$2.MatButtonToggleGroup, selector: "mat-button-toggle-group", inputs: ["appearance", "name", "vertical", "value", "multiple", "disabled", "disabledInteractive", "hideSingleSelectionIndicator", "hideMultipleSelectionIndicator"], outputs: ["valueChange", "change"], exportAs: ["matButtonToggleGroup"] }, { kind: "component", type: i7$2.MatButtonToggle, selector: "mat-button-toggle", inputs: ["aria-label", "aria-labelledby", "id", "name", "value", "tabIndex", "disableRipple", "appearance", "checked", "disabled", "disabledInteractive"], outputs: ["change"], exportAs: ["matButtonToggle"] }, { kind: "ngmodule", type: FormsModule }, { kind: "directive", type: i1$3.DefaultValueAccessor, selector: "input:not([type=checkbox])[formControlName],textarea[formControlName],input:not([type=checkbox])[formControl],textarea[formControl],input:not([type=checkbox])[ngModel],textarea[ngModel],[ngDefaultControl]" }, { kind: "directive", type: i1$3.NumberValueAccessor, selector: "input[type=number][formControlName],input[type=number][formControl],input[type=number][ngModel]" }, { kind: "directive", type: i1$3.NgControlStatus, selector: "[formControlName],[ngModel],[formControl]" }, { kind: "directive", type: i1$3.MinValidator, selector: "input[type=number][min][formControlName],input[type=number][min][formControl],input[type=number][min][ngModel]", inputs: ["min"] }, { kind: "directive", type: i1$3.NgModel, selector: "[ngModel]:not([formControlName]):not([formControl])", inputs: ["name", "disabled", "ngModel", "ngModelOptions"], outputs: ["ngModelChange"], exportAs: ["ngModel"] }] });
14519
15437
  }
14520
15438
  i0.ɵɵngDeclareClassMetadata({ minVersion: "12.0.0", version: "20.3.17", ngImport: i0, type: LayoutEditorComponent, decorators: [{
14521
15439
  type: Component,
@@ -14620,8 +15538,8 @@ i0.ɵɵngDeclareClassMetadata({ minVersion: "12.0.0", version: "20.3.17", ngImpo
14620
15538
  >
14621
15539
  <mat-icon>chevron_right</mat-icon>
14622
15540
  </button>
14623
- <h4>Campos disponíveis</h4>
14624
- <small class="available-fields__hint">Arraste para montar seções.</small>
15541
+ <h4>{{ t('apiFields.heading') }}</h4>
15542
+ <small class="available-fields__hint">{{ t('apiFields.hint') }}</small>
14625
15543
  <div
14626
15544
  cdkDropList
14627
15545
  id="available-fields-list"
@@ -14646,8 +15564,12 @@ i0.ɵɵngDeclareClassMetadata({ minVersion: "12.0.0", version: "20.3.17", ngImpo
14646
15564
  <mat-icon>chevron_left</mat-icon>
14647
15565
  </button>
14648
15566
  <div class="layout-canvas">
14649
- <div class="no-fields-chip" *ngIf="!availableFields.length">
14650
- Nenhum campo disponível
15567
+ <div
15568
+ class="no-fields-chip"
15569
+ data-testid="layout-editor-api-fields-empty"
15570
+ *ngIf="!availableFields.length"
15571
+ >
15572
+ {{ t('apiFields.empty') }}
14651
15573
  </div>
14652
15574
  <div
14653
15575
  cdkDropList
@@ -14661,6 +15583,7 @@ i0.ɵɵngDeclareClassMetadata({ minVersion: "12.0.0", version: "20.3.17", ngImpo
14661
15583
  [sectionIndex]="i"
14662
15584
  [allSections]="config.sections"
14663
15585
  [fieldMetadata]="config.fieldMetadata || []"
15586
+ [availableFields]="availableFields"
14664
15587
  [selected]="selected"
14665
15588
  [gapGlobal]="gapGlobal || 16"
14666
15589
  [availableFieldsListId]="
@@ -14672,6 +15595,12 @@ i0.ɵɵngDeclareClassMetadata({ minVersion: "12.0.0", version: "20.3.17", ngImpo
14672
15595
  (sectionChange)="onSectionUpdated(i, $event)"
14673
15596
  (applyStyleToAll)="onApplyStyleToAll($event)"
14674
15597
  (fieldDrop)="dropField($event)"
15598
+ (addVisualBlock)="addVisualBlockToColumn($event)"
15599
+ (addApiField)="addApiFieldToColumn($event)"
15600
+ (editVisualBlock)="openVisualBlockEditor($event)"
15601
+ (moveVisualBlock)="moveVisualBlock($event)"
15602
+ (moveVisualBlockToColumn)="moveVisualBlockToColumn($event)"
15603
+ (removeVisualBlock)="removeVisualBlock($event)"
14675
15604
  cdkDrag
14676
15605
  ></praxis-section-configurator>
14677
15606
  </div>
@@ -14689,7 +15618,7 @@ i0.ɵɵngDeclareClassMetadata({ minVersion: "12.0.0", version: "20.3.17", ngImpo
14689
15618
  </div>
14690
15619
  </div>
14691
15620
  </div>
14692
- `, styles: [".layout-editor-wrapper{display:flex;flex-wrap:wrap;gap:16px}.layout-editor-wrapper.no-available-fields{gap:0}.editor-toolbar{position:sticky;top:0;z-index:3;display:flex;gap:16px;align-items:center;min-height:56px;background:var(--md-sys-color-surface-container);border-bottom:1px solid var(--md-sys-color-outline-variant);box-shadow:var(--md-sys-elevation-level1, var(--md-sys-elevation-level1));padding:0 12px;margin:0 0 var(--px-editor-section-gap, 16px) 0}.editor-toolbar .title-block{display:flex;flex-direction:column;justify-content:center;gap:2px}.editor-toolbar .toolbar-title{font:var(--mdc-typography-title-small, 600 15px/20px system-ui);color:var(--md-sys-color-on-surface)}.editor-toolbar .toolbar-subtitle{font:var(--mdc-typography-body-small, 400 12px/16px system-ui);color:var(--md-sys-color-on-surface-variant)}.editor-toolbar .spacer{flex:1 1 auto}.editor-toolbar .toolbar-group{display:inline-flex;align-items:center;gap:8px;flex-wrap:wrap}.editor-toolbar .gap-group{align-items:center}.editor-toolbar .group-label{font:var(--mdc-typography-label-medium, 500 12px/16px system-ui);color:var(--md-sys-color-on-surface-variant)}.editor-toolbar .gap-group{align-items:center;gap:10px}.editor-toolbar .density-control{display:flex;align-items:center;gap:8px}.editor-toolbar .density-label{font:var(--mdc-typography-label-medium, 500 12px/16px system-ui);opacity:.9}.editor-toolbar .density-toggle,.editor-toolbar .toggle-icons-group{border:1px solid var(--md-sys-color-outline-variant);border-radius:999px;overflow:hidden;background:var(--md-sys-color-surface-container-low)}.editor-toolbar .density-toggle .mat-button-toggle,.editor-toolbar .toggle-icons-group .mat-button-toggle{background:var(--md-sys-color-surface-container-low);color:var(--md-sys-color-on-surface-variant)}.editor-toolbar .density-toggle .mat-button-toggle+.mat-button-toggle,.editor-toolbar .toggle-icons-group .mat-button-toggle+.mat-button-toggle{border-left:1px solid var(--md-sys-color-outline-variant)}.editor-toolbar .density-toggle .mat-button-toggle-button,.toggle-icons-group .mat-button-toggle-button{height:32px}.editor-toolbar .density-toggle .mat-icon,.toggle-icons-group .mat-icon{font-size:20px;width:20px;height:20px;line-height:20px}.editor-toolbar .density-toggle .mat-icon,.editor-toolbar .toggle-icons-group .mat-icon{color:inherit}.gap-chip{display:inline-flex;align-items:center;gap:2px;padding:0 4px;height:32px;border-radius:8px;border:1px solid var(--md-sys-color-outline-variant);background:var(--md-sys-color-surface-variant)}.gap-chip__btn{width:24px;height:24px;line-height:24px;min-width:0;padding:0;--mdc-icon-button-size: 24px;--mdc-icon-button-state-layer-size: 24px}.gap-chip .mat-mdc-button-touch-target{width:24px;height:24px}.gap-chip mat-icon{font-size:16px;width:16px;height:16px;line-height:16px}.gap-chip__input{width:42px;border:none;background:transparent;color:var(--md-sys-color-on-surface);font:var(--mdc-typography-body-medium, 600 13px/18px system-ui);text-align:center;outline:none;-moz-appearance:textfield}.gap-chip__input::-webkit-outer-spin-button,.gap-chip__input::-webkit-inner-spin-button{-webkit-appearance:none;margin:0}.gap-chip__suffix{color:var(--md-sys-color-on-surface-variant);font:var(--mdc-typography-label-medium, 500 12px/16px system-ui)}.pill{display:inline-flex;align-items:center;gap:6px;padding:4px 8px;border-radius:12px;background:var(--md-sys-color-surface-variant);color:var(--md-sys-color-on-surface-variant);font-size:12px}.pill.subtle{background:transparent;color:var(--md-sys-color-on-surface-variant);padding-left:0}.available-fields{width:250px;border:1px solid var(--md-sys-color-outline-variant);border-radius:12px;padding:10px;background:var(--md-sys-color-surface)}.collapse-toggle{float:right}.available-fields__hint{display:block;margin-bottom:8px;color:var(--md-sys-color-on-surface-variant);font-size:12px}.no-fields-chip{position:absolute;top:8px;right:8px;padding:4px 8px;border:1px dashed var(--md-sys-color-outline);border-radius:16px;color:var(--md-sys-color-outline);font-size:12px;background:var(--md-sys-color-surface);pointer-events:none}.layout-canvas{flex-grow:1;overflow:visible;max-height:none;position:relative}.field-list{min-height:100px}.section-list{display:flex;flex-direction:column;gap:var(--pfx-section-gap, 20px)}.add-section-container{position:relative;padding-top:16px;margin-top:12px;border-top:1px solid var(--md-sys-color-outline-variant);min-height:28px}.fab-add-section{position:absolute;top:-30px;left:50%;transform:translate(-50%,calc(-50% - var(--pfx-divider-w, 1px)));z-index:2;--pfx-fab-size: var(--pfx-fab-size-section, 32px);--pfx-fab-icon: var(--pfx-fab-icon-section, 18px);width:var(--pfx-fab-size);height:var(--pfx-fab-size);border-radius:50%}.fab-add-section mat-icon{font-size:var(--pfx-fab-icon);width:var(--pfx-fab-icon);height:var(--pfx-fab-icon)}.fab-add-section.mat-mdc-fab{width:var(--pfx-fab-size);height:var(--pfx-fab-size);padding:0}.fab-add-section .mat-mdc-button-touch-target,.fab-add-section .mat-mdc-button-persistent-ripple,.fab-add-section .mat-mdc-button-ripple{width:var(--pfx-fab-size);height:var(--pfx-fab-size)}.cdk-drag-placeholder{opacity:.3;transition:opacity .2s ease}:host ::ng-deep .mdc-text-field--filled{--mdc-filled-text-field-container-color: var(--md-sys-color-surface-container)}:host ::ng-deep .mdc-text-field__input::placeholder{color:var(--md-sys-color-on-surface-variant)!important;opacity:.95}:host ::ng-deep .mat-mdc-form-field-subscript-wrapper,:host ::ng-deep .mat-mdc-hint{color:var(--md-sys-color-on-surface-variant)!important}:host ::ng-deep .mdc-text-field--disabled .mdc-text-field__input,:host ::ng-deep .mat-mdc-select-disabled .mat-mdc-select-value{color:var(--md-sys-color-on-surface-variant)!important}:host ::ng-deep .mat-button-toggle-checked{background:var(--md-sys-color-primary-container)!important;color:var(--md-sys-color-on-primary-container)!important}:host ::ng-deep .editor-toolbar .mat-button-toggle-appearance-standard{color:var(--md-sys-color-on-surface-variant)}:host ::ng-deep .editor-toolbar .mat-button-toggle-appearance-standard:hover{background:var(--md-sys-color-surface-container-high);color:var(--md-sys-color-on-surface)}:host ::ng-deep .editor-toolbar .mat-button-toggle-checked:hover{background:var(--md-sys-color-primary-container)!important;color:var(--md-sys-color-on-primary-container)!important}:host{--px-editor-section-gap: 16px;--pfx-grid-gap: 12px;--pfx-section-gap: var(--px-editor-section-gap)}@media(min-width:960px){:host{--px-editor-section-gap: 20px;--pfx-grid-gap: 16px}}@media(min-width:1280px){:host{--px-editor-section-gap: 24px;--pfx-grid-gap: 20px}}\n"] }]
15621
+ `, providers: [providePraxisI18nConfig(LAYOUT_EDITOR_I18N_CONFIG)], styles: [".layout-editor-wrapper{display:flex;flex-wrap:wrap;gap:16px}.layout-editor-wrapper.no-available-fields{gap:0}.editor-toolbar{position:sticky;top:0;z-index:3;display:flex;gap:16px;align-items:center;min-height:56px;background:var(--md-sys-color-surface-container);border-bottom:1px solid var(--md-sys-color-outline-variant);box-shadow:var(--md-sys-elevation-level1, var(--md-sys-elevation-level1));padding:0 12px;margin:0 0 var(--px-editor-section-gap, 16px) 0}.editor-toolbar .title-block{display:flex;flex-direction:column;justify-content:center;gap:2px}.editor-toolbar .toolbar-title{font:var(--mdc-typography-title-small, 600 15px/20px system-ui);color:var(--md-sys-color-on-surface)}.editor-toolbar .toolbar-subtitle{font:var(--mdc-typography-body-small, 400 12px/16px system-ui);color:var(--md-sys-color-on-surface-variant)}.editor-toolbar .spacer{flex:1 1 auto}.editor-toolbar .toolbar-group{display:inline-flex;align-items:center;gap:8px;flex-wrap:wrap}.editor-toolbar .gap-group{align-items:center}.editor-toolbar .group-label{font:var(--mdc-typography-label-medium, 500 12px/16px system-ui);color:var(--md-sys-color-on-surface-variant)}.editor-toolbar .gap-group{align-items:center;gap:10px}.editor-toolbar .density-control{display:flex;align-items:center;gap:8px}.editor-toolbar .density-label{font:var(--mdc-typography-label-medium, 500 12px/16px system-ui);opacity:.9}.editor-toolbar .density-toggle,.editor-toolbar .toggle-icons-group{border:1px solid var(--md-sys-color-outline-variant);border-radius:999px;overflow:hidden;background:var(--md-sys-color-surface-container-low)}.editor-toolbar .density-toggle .mat-button-toggle,.editor-toolbar .toggle-icons-group .mat-button-toggle{background:var(--md-sys-color-surface-container-low);color:var(--md-sys-color-on-surface-variant)}.editor-toolbar .density-toggle .mat-button-toggle+.mat-button-toggle,.editor-toolbar .toggle-icons-group .mat-button-toggle+.mat-button-toggle{border-left:1px solid var(--md-sys-color-outline-variant)}.editor-toolbar .density-toggle .mat-button-toggle-button,.toggle-icons-group .mat-button-toggle-button{height:32px}.editor-toolbar .density-toggle .mat-icon,.toggle-icons-group .mat-icon{font-size:20px;width:20px;height:20px;line-height:20px}.editor-toolbar .density-toggle .mat-icon,.editor-toolbar .toggle-icons-group .mat-icon{color:inherit}.gap-chip{display:inline-flex;align-items:center;gap:2px;padding:0 4px;height:32px;border-radius:8px;border:1px solid var(--md-sys-color-outline-variant);background:var(--md-sys-color-surface-variant)}.gap-chip__btn{width:24px;height:24px;line-height:24px;min-width:0;padding:0;--mdc-icon-button-size: 24px;--mdc-icon-button-state-layer-size: 24px}.gap-chip .mat-mdc-button-touch-target{width:24px;height:24px}.gap-chip mat-icon{font-size:16px;width:16px;height:16px;line-height:16px}.gap-chip__input{width:42px;border:none;background:transparent;color:var(--md-sys-color-on-surface);font:var(--mdc-typography-body-medium, 600 13px/18px system-ui);text-align:center;outline:none;-moz-appearance:textfield}.gap-chip__input::-webkit-outer-spin-button,.gap-chip__input::-webkit-inner-spin-button{-webkit-appearance:none;margin:0}.gap-chip__suffix{color:var(--md-sys-color-on-surface-variant);font:var(--mdc-typography-label-medium, 500 12px/16px system-ui)}.pill{display:inline-flex;align-items:center;gap:6px;padding:4px 8px;border-radius:12px;background:var(--md-sys-color-surface-variant);color:var(--md-sys-color-on-surface-variant);font-size:12px}.pill.subtle{background:transparent;color:var(--md-sys-color-on-surface-variant);padding-left:0}.available-fields{width:250px;border:1px solid var(--md-sys-color-outline-variant);border-radius:12px;padding:10px;background:var(--md-sys-color-surface)}.collapse-toggle{float:right}.available-fields__hint{display:block;margin-bottom:8px;color:var(--md-sys-color-on-surface-variant);font-size:12px}.no-fields-chip{position:absolute;top:8px;right:8px;padding:4px 8px;border:1px dashed var(--md-sys-color-outline);border-radius:16px;color:var(--md-sys-color-outline);font-size:12px;background:var(--md-sys-color-surface);pointer-events:none}.layout-canvas{flex-grow:1;overflow:visible;max-height:none;position:relative}.field-list{min-height:100px}.section-list{display:flex;flex-direction:column;gap:var(--pfx-section-gap, 20px)}.add-section-container{position:relative;padding-top:16px;margin-top:12px;border-top:1px solid var(--md-sys-color-outline-variant);min-height:28px}.fab-add-section{position:absolute;top:-30px;left:50%;transform:translate(-50%,calc(-50% - var(--pfx-divider-w, 1px)));z-index:2;--pfx-fab-size: var(--pfx-fab-size-section, 32px);--pfx-fab-icon: var(--pfx-fab-icon-section, 18px);width:var(--pfx-fab-size);height:var(--pfx-fab-size);border-radius:50%}.fab-add-section mat-icon{font-size:var(--pfx-fab-icon);width:var(--pfx-fab-icon);height:var(--pfx-fab-icon)}.fab-add-section.mat-mdc-fab{width:var(--pfx-fab-size);height:var(--pfx-fab-size);padding:0}.fab-add-section .mat-mdc-button-touch-target,.fab-add-section .mat-mdc-button-persistent-ripple,.fab-add-section .mat-mdc-button-ripple{width:var(--pfx-fab-size);height:var(--pfx-fab-size)}.cdk-drag-placeholder{opacity:.3;transition:opacity .2s ease}:host ::ng-deep .mdc-text-field--filled{--mdc-filled-text-field-container-color: var(--md-sys-color-surface-container)}:host ::ng-deep .mdc-text-field__input::placeholder{color:var(--md-sys-color-on-surface-variant)!important;opacity:.95}:host ::ng-deep .mat-mdc-form-field-subscript-wrapper,:host ::ng-deep .mat-mdc-hint{color:var(--md-sys-color-on-surface-variant)!important}:host ::ng-deep .mdc-text-field--disabled .mdc-text-field__input,:host ::ng-deep .mat-mdc-select-disabled .mat-mdc-select-value{color:var(--md-sys-color-on-surface-variant)!important}:host ::ng-deep .mat-button-toggle-checked{background:var(--md-sys-color-primary-container)!important;color:var(--md-sys-color-on-primary-container)!important}:host ::ng-deep .editor-toolbar .mat-button-toggle-appearance-standard{color:var(--md-sys-color-on-surface-variant)}:host ::ng-deep .editor-toolbar .mat-button-toggle-appearance-standard:hover{background:var(--md-sys-color-surface-container-high);color:var(--md-sys-color-on-surface)}:host ::ng-deep .editor-toolbar .mat-button-toggle-checked:hover{background:var(--md-sys-color-primary-container)!important;color:var(--md-sys-color-on-primary-container)!important}:host{--px-editor-section-gap: 16px;--pfx-grid-gap: 12px;--pfx-section-gap: var(--px-editor-section-gap)}@media(min-width:960px){:host{--px-editor-section-gap: 20px;--pfx-grid-gap: 16px}}@media(min-width:1280px){:host{--px-editor-section-gap: 24px;--pfx-grid-gap: 20px}}\n"] }]
14693
15622
  }], propDecorators: { config: [{
14694
15623
  type: Input
14695
15624
  }], configChange: [{
@@ -19919,7 +20848,8 @@ class PraxisFilterForm {
19919
20848
  }
19920
20849
  getColumnFields(column) {
19921
20850
  const metas = this.fieldMetadata;
19922
- return metas.filter((m) => column.fields.includes(m.name));
20851
+ const fieldNames = new Set(getFormColumnFieldNames(column));
20852
+ return metas.filter((m) => fieldNames.has(m.name));
19923
20853
  }
19924
20854
  get fieldMetadata() {
19925
20855
  return this.config?.fieldMetadata || [];
@@ -24045,7 +24975,7 @@ const FORM_COMPONENT_AI_CAPABILITIES = {
24045
24975
  * Manifesto de authoring canônico para o componente praxis-dynamic-form.
24046
24976
  * Este arquivo define as operações permitidas pela IA para editar formulários.
24047
24977
  *
24048
- * @version 1.4.0
24978
+ * @version 1.5.0
24049
24979
  * @status COMPLIANT - Alinhado com contrato v2, gate de aceitação e semântica local/schema-backed.
24050
24980
  */
24051
24981
  const PRAXIS_DYNAMIC_FORM_AUTHORING_MANIFEST = {
@@ -24053,7 +24983,7 @@ const PRAXIS_DYNAMIC_FORM_AUTHORING_MANIFEST = {
24053
24983
  componentId: 'praxis-dynamic-form',
24054
24984
  ownerPackage: '@praxisui/dynamic-form',
24055
24985
  configSchemaId: 'FormConfig',
24056
- manifestVersion: '1.4.0',
24986
+ manifestVersion: '1.5.0',
24057
24987
  runtimeInputs: [
24058
24988
  { name: 'config', type: 'FormConfig', description: 'Configuração completa do formulário' },
24059
24989
  { name: 'resourcePath', type: 'string', description: 'Caminho do recurso (API)' },
@@ -24076,6 +25006,7 @@ const PRAXIS_DYNAMIC_FORM_AUTHORING_MANIFEST = {
24076
25006
  * Usado conceitualmente por layout.field.move; declarado como target para futuras ops
24077
25007
  * de reposicionamento granular (ex: layout.placement.swap).
24078
25008
  */
25009
+ { kind: 'visualBlock', resolver: 'layout-item-by-id', description: 'Blocos visuais richContent em sections[].rows[].columns[].items[]; não participam do payload de submissão' },
24079
25010
  { kind: 'layoutPlacement', resolver: 'layout-placement-by-field', description: 'Posicionamento de campo no layout; target para ops de reposicionamento' },
24080
25011
  { kind: 'formAction', resolver: 'action-by-id-or-label', description: 'Ações da toolbar (submit, cancel, reset)' },
24081
25012
  { kind: 'formRule', resolver: 'rule-by-id-or-name', description: 'Regras de visibilidade e validação' },
@@ -24102,7 +25033,7 @@ const PRAXIS_DYNAMIC_FORM_AUTHORING_MANIFEST = {
24102
25033
  effects: [{ kind: 'merge-by-key', path: 'fieldMetadata[]', key: 'name' }],
24103
25034
  validators: ['field-exists'],
24104
25035
  affectedPaths: ['fieldMetadata[].label'],
24105
- submissionImpact: false,
25036
+ submissionImpact: 'visual-only',
24106
25037
  preconditions: ['config-initialized', 'target-exists']
24107
25038
  },
24108
25039
  {
@@ -24119,7 +25050,7 @@ const PRAXIS_DYNAMIC_FORM_AUTHORING_MANIFEST = {
24119
25050
  effects: [{ kind: 'merge-by-key', path: 'fieldMetadata[]', key: 'name' }],
24120
25051
  validators: ['field-exists'],
24121
25052
  affectedPaths: ['fieldMetadata[].placeholder'],
24122
- submissionImpact: false,
25053
+ submissionImpact: 'visual-only',
24123
25054
  preconditions: ['config-initialized', 'target-exists']
24124
25055
  },
24125
25056
  {
@@ -24136,7 +25067,7 @@ const PRAXIS_DYNAMIC_FORM_AUTHORING_MANIFEST = {
24136
25067
  effects: [{ kind: 'merge-by-key', path: 'fieldMetadata[]', key: 'name' }],
24137
25068
  validators: ['field-exists'],
24138
25069
  affectedPaths: ['fieldMetadata[].required'],
24139
- submissionImpact: false,
25070
+ submissionImpact: 'affects-schema-backed-data',
24140
25071
  preconditions: ['config-initialized', 'target-exists']
24141
25072
  },
24142
25073
  {
@@ -24153,7 +25084,7 @@ const PRAXIS_DYNAMIC_FORM_AUTHORING_MANIFEST = {
24153
25084
  effects: [{ kind: 'merge-by-key', path: 'fieldMetadata[]', key: 'name' }],
24154
25085
  validators: ['field-exists'],
24155
25086
  affectedPaths: ['fieldMetadata[].readOnly'],
24156
- submissionImpact: false,
25087
+ submissionImpact: 'affects-schema-backed-data',
24157
25088
  preconditions: ['config-initialized', 'target-exists']
24158
25089
  },
24159
25090
  {
@@ -24170,7 +25101,7 @@ const PRAXIS_DYNAMIC_FORM_AUTHORING_MANIFEST = {
24170
25101
  effects: [{ kind: 'merge-by-key', path: 'fieldMetadata[]', key: 'name' }],
24171
25102
  validators: ['field-exists'],
24172
25103
  affectedPaths: ['fieldMetadata[].disabled'],
24173
- submissionImpact: false,
25104
+ submissionImpact: 'affects-schema-backed-data',
24174
25105
  preconditions: ['config-initialized', 'target-exists']
24175
25106
  },
24176
25107
  {
@@ -24187,7 +25118,7 @@ const PRAXIS_DYNAMIC_FORM_AUTHORING_MANIFEST = {
24187
25118
  effects: [{ kind: 'merge-by-key', path: 'fieldMetadata[]', key: 'name' }],
24188
25119
  validators: ['field-exists'],
24189
25120
  affectedPaths: ['fieldMetadata[].hidden'],
24190
- submissionImpact: false,
25121
+ submissionImpact: 'visual-only',
24191
25122
  preconditions: ['config-initialized', 'target-exists']
24192
25123
  },
24193
25124
  {
@@ -24206,7 +25137,7 @@ const PRAXIS_DYNAMIC_FORM_AUTHORING_MANIFEST = {
24206
25137
  requiresConfirmation: true,
24207
25138
  validators: ['field-exists', 'control-type-compatible'],
24208
25139
  affectedPaths: ['fieldMetadata[].controlType'],
24209
- submissionImpact: false,
25140
+ submissionImpact: 'affects-schema-backed-data',
24210
25141
  preconditions: ['config-initialized', 'target-exists']
24211
25142
  },
24212
25143
  {
@@ -24241,7 +25172,7 @@ const PRAXIS_DYNAMIC_FORM_AUTHORING_MANIFEST = {
24241
25172
  effects: [{ kind: 'merge-by-key', path: 'fieldMetadata[]', key: 'name' }],
24242
25173
  validators: ['field-exists', 'option-source-valid'],
24243
25174
  affectedPaths: ['fieldMetadata[].optionSource'],
24244
- submissionImpact: false,
25175
+ submissionImpact: 'affects-remote-binding',
24245
25176
  preconditions: ['config-initialized', 'target-exists']
24246
25177
  },
24247
25178
  // ─── LOCAL FIELD OPERATIONS ───────────────────────────────────────────────
@@ -24279,7 +25210,7 @@ const PRAXIS_DYNAMIC_FORM_AUTHORING_MANIFEST = {
24279
25210
  effects: [{ kind: 'append-unique', path: 'fieldMetadata[]', key: 'name' }],
24280
25211
  validators: ['field-name-unique', 'local-schema-name-no-collision'],
24281
25212
  affectedPaths: ['fieldMetadata[]'],
24282
- submissionImpact: true,
25213
+ submissionImpact: 'affects-submission',
24283
25214
  preconditions: ['config-initialized']
24284
25215
  },
24285
25216
  {
@@ -24299,8 +25230,8 @@ const PRAXIS_DYNAMIC_FORM_AUTHORING_MANIFEST = {
24299
25230
  kind: 'compile-domain-patch',
24300
25231
  handler: 'form-layout-field-cleanup',
24301
25232
  handlerContract: {
24302
- reads: ['fieldMetadata[].name', 'sections[].rows[].columns[].fields'],
24303
- writes: ['sections[].rows[].columns[].fields'],
25233
+ reads: ['fieldMetadata[].name', 'sections[].rows[].columns[].items', 'sections[].rows[].columns[].fields'],
25234
+ writes: ['sections[].rows[].columns[].items', 'sections[].rows[].columns[].fields'],
24304
25235
  identityKeys: ['fieldMetadata[].name', 'sections[].id', 'sections[].rows[].id', 'sections[].rows[].columns[].id'],
24305
25236
  inputSchema: { type: 'object', required: ['target.name'], properties: { 'target.name': { type: 'string' } } },
24306
25237
  failureModes: ['target-field-not-found', 'target-field-not-local', 'layout-reference-conflict'],
@@ -24311,8 +25242,8 @@ const PRAXIS_DYNAMIC_FORM_AUTHORING_MANIFEST = {
24311
25242
  destructive: true,
24312
25243
  requiresConfirmation: true,
24313
25244
  validators: ['field-exists', 'field-is-local'],
24314
- affectedPaths: ['fieldMetadata[]', 'sections[].rows[].columns[].fields'],
24315
- submissionImpact: true,
25245
+ affectedPaths: ['fieldMetadata[]', 'sections[].rows[].columns[].items', 'sections[].rows[].columns[].fields'],
25246
+ submissionImpact: 'affects-submission',
24316
25247
  preconditions: ['config-initialized', 'target-exists']
24317
25248
  },
24318
25249
  {
@@ -24331,7 +25262,7 @@ const PRAXIS_DYNAMIC_FORM_AUTHORING_MANIFEST = {
24331
25262
  effects: [{ kind: 'merge-by-key', path: 'fieldMetadata[]', key: 'name' }],
24332
25263
  validators: ['field-exists', 'field-is-local', 'editor-round-trip-preserve'],
24333
25264
  affectedPaths: ['fieldMetadata[].submitPolicy'],
24334
- submissionImpact: true,
25265
+ submissionImpact: 'affects-submission',
24335
25266
  preconditions: ['config-initialized', 'target-exists']
24336
25267
  },
24337
25268
  // ─── LAYOUT OPERATIONS ────────────────────────────────────────────────────
@@ -24354,7 +25285,7 @@ const PRAXIS_DYNAMIC_FORM_AUTHORING_MANIFEST = {
24354
25285
  effects: [{ kind: 'append-unique', path: 'sections[]', key: 'id' }],
24355
25286
  validators: ['section-id-unique'],
24356
25287
  affectedPaths: ['sections[]'],
24357
- submissionImpact: false,
25288
+ submissionImpact: 'visual-only',
24358
25289
  preconditions: ['config-initialized']
24359
25290
  },
24360
25291
  {
@@ -24375,7 +25306,7 @@ const PRAXIS_DYNAMIC_FORM_AUTHORING_MANIFEST = {
24375
25306
  kind: 'compile-domain-patch',
24376
25307
  handler: 'form-layout-section-cleanup',
24377
25308
  handlerContract: {
24378
- reads: ['sections[].id', 'sections[].rows[].id', 'sections[].rows[].columns[].id', 'sections[].rows[].columns[].fields'],
25309
+ reads: ['sections[].id', 'sections[].rows[].id', 'sections[].rows[].columns[].id', 'sections[].rows[].columns[].items', 'sections[].rows[].columns[].fields'],
24379
25310
  writes: ['sections[]'],
24380
25311
  identityKeys: ['sections[].id'],
24381
25312
  inputSchema: { type: 'object', required: ['target.id'], properties: { 'target.id': { type: 'string' } } },
@@ -24387,8 +25318,8 @@ const PRAXIS_DYNAMIC_FORM_AUTHORING_MANIFEST = {
24387
25318
  destructive: true,
24388
25319
  requiresConfirmation: true,
24389
25320
  validators: ['section-exists'],
24390
- affectedPaths: ['sections[]', 'sections[].rows[]', 'sections[].rows[].columns[]', 'sections[].rows[].columns[].fields'],
24391
- submissionImpact: false,
25321
+ affectedPaths: ['sections[]', 'sections[].rows[]', 'sections[].rows[].columns[]', 'sections[].rows[].columns[].items', 'sections[].rows[].columns[].fields'],
25322
+ submissionImpact: 'visual-only',
24392
25323
  preconditions: ['config-initialized', 'target-exists']
24393
25324
  },
24394
25325
  {
@@ -24408,7 +25339,7 @@ const PRAXIS_DYNAMIC_FORM_AUTHORING_MANIFEST = {
24408
25339
  effects: [{ kind: 'append-unique', path: 'sections[].rows[]', key: 'id' }],
24409
25340
  validators: ['section-exists', 'row-id-unique-in-section'],
24410
25341
  affectedPaths: ['sections[].rows[]'],
24411
- submissionImpact: false,
25342
+ submissionImpact: 'visual-only',
24412
25343
  preconditions: ['config-initialized', 'target-exists']
24413
25344
  },
24414
25345
  {
@@ -24428,7 +25359,7 @@ const PRAXIS_DYNAMIC_FORM_AUTHORING_MANIFEST = {
24428
25359
  effects: [{ kind: 'append-unique', path: 'sections[].rows[].columns[]', key: 'id' }],
24429
25360
  validators: ['row-exists', 'column-id-unique-in-row'],
24430
25361
  affectedPaths: ['sections[].rows[].columns[]'],
24431
- submissionImpact: false,
25362
+ submissionImpact: 'visual-only',
24432
25363
  preconditions: ['config-initialized', 'target-exists']
24433
25364
  },
24434
25365
  {
@@ -24456,9 +25387,10 @@ const PRAXIS_DYNAMIC_FORM_AUTHORING_MANIFEST = {
24456
25387
  'sections[].id',
24457
25388
  'sections[].rows[].id',
24458
25389
  'sections[].rows[].columns[].id',
25390
+ 'sections[].rows[].columns[].items',
24459
25391
  'sections[].rows[].columns[].fields'
24460
25392
  ],
24461
- writes: ['sections[].rows[].columns[].fields'],
25393
+ writes: ['sections[].rows[].columns[].items', 'sections[].rows[].columns[].fields'],
24462
25394
  identityKeys: ['fieldMetadata[].name', 'sections[].id', 'sections[].rows[].id', 'sections[].rows[].columns[].id'],
24463
25395
  inputSchema: {
24464
25396
  type: 'object',
@@ -24476,11 +25408,184 @@ const PRAXIS_DYNAMIC_FORM_AUTHORING_MANIFEST = {
24476
25408
  }
24477
25409
  }],
24478
25410
  validators: ['field-exists', 'layout-target-exists', 'no-index-as-identity', 'field-exists-in-layout'],
24479
- affectedPaths: ['sections[].rows[].columns[].fields'],
24480
- submissionImpact: false,
25411
+ affectedPaths: ['sections[].rows[].columns[].items', 'sections[].rows[].columns[].fields'],
25412
+ submissionImpact: 'visual-only',
24481
25413
  preconditions: ['config-initialized', 'target-exists']
24482
25414
  },
24483
25415
  // ─── RULE OPERATIONS ──────────────────────────────────────────────────────
25416
+ {
25417
+ operationId: 'layout.visualBlock.add',
25418
+ title: 'Adicionar bloco visual',
25419
+ scope: 'column',
25420
+ targetKind: 'column',
25421
+ target: { kind: 'column', resolver: 'column-by-id-in-row', ambiguityPolicy: 'fail', required: true },
25422
+ inputSchema: {
25423
+ type: 'object',
25424
+ required: ['id', 'document'],
25425
+ properties: {
25426
+ id: { type: 'string' },
25427
+ document: {
25428
+ type: 'object',
25429
+ required: ['kind', 'version', 'nodes'],
25430
+ properties: {
25431
+ kind: { const: 'praxis.rich-content' },
25432
+ version: { type: 'string' },
25433
+ nodes: { type: 'array' }
25434
+ }
25435
+ },
25436
+ layout: { enum: ['block', 'inline'], default: 'block' },
25437
+ rootClassName: { type: ['string', 'null'] },
25438
+ index: { type: 'number' }
25439
+ }
25440
+ },
25441
+ effects: [{
25442
+ kind: 'compile-domain-patch',
25443
+ handler: 'form-layout-visual-block-add',
25444
+ handlerContract: {
25445
+ reads: ['sections[].id', 'sections[].rows[].id', 'sections[].rows[].columns[].id', 'sections[].rows[].columns[].items'],
25446
+ writes: ['sections[].rows[].columns[].items'],
25447
+ identityKeys: ['sections[].id', 'sections[].rows[].id', 'sections[].rows[].columns[].id', 'sections[].rows[].columns[].items[].id'],
25448
+ inputSchema: {
25449
+ type: 'object',
25450
+ required: ['target.sectionId', 'target.rowId', 'target.columnId', 'id', 'document'],
25451
+ properties: {
25452
+ 'target.sectionId': { type: 'string' },
25453
+ 'target.rowId': { type: 'string' },
25454
+ 'target.columnId': { type: 'string' },
25455
+ id: { type: 'string' },
25456
+ document: { type: 'object' },
25457
+ layout: { enum: ['block', 'inline'] },
25458
+ rootClassName: { type: ['string', 'null'] },
25459
+ index: { type: 'number' }
25460
+ }
25461
+ },
25462
+ failureModes: ['target-layout-location-not-found', 'duplicate-visual-block-id', 'invalid-rich-content-document'],
25463
+ description: 'Adds a richContent layout item into sections[].rows[].columns[].items[] by stable section, row, and column ids.'
25464
+ }
25465
+ }],
25466
+ validators: ['layout-target-exists', 'visual-block-id-unique', 'rich-content-document-valid'],
25467
+ affectedPaths: ['sections[].rows[].columns[].items'],
25468
+ submissionImpact: 'visual-only',
25469
+ preconditions: ['config-initialized', 'target-exists']
25470
+ },
25471
+ {
25472
+ operationId: 'layout.visualBlock.update',
25473
+ title: 'Atualizar bloco visual',
25474
+ scope: 'layout',
25475
+ targetKind: 'visualBlock',
25476
+ target: { kind: 'visualBlock', resolver: 'layout-item-by-id', ambiguityPolicy: 'fail', required: true },
25477
+ inputSchema: {
25478
+ type: 'object',
25479
+ minProperties: 1,
25480
+ properties: {
25481
+ document: {
25482
+ type: 'object',
25483
+ required: ['kind', 'version', 'nodes'],
25484
+ properties: {
25485
+ kind: { const: 'praxis.rich-content' },
25486
+ version: { type: 'string' },
25487
+ nodes: { type: 'array' }
25488
+ }
25489
+ },
25490
+ layout: { enum: ['block', 'inline'] },
25491
+ rootClassName: { type: ['string', 'null'] }
25492
+ }
25493
+ },
25494
+ effects: [{
25495
+ kind: 'compile-domain-patch',
25496
+ handler: 'form-layout-visual-block-update',
25497
+ handlerContract: {
25498
+ reads: ['sections[].rows[].columns[].items[].id'],
25499
+ writes: ['sections[].rows[].columns[].items'],
25500
+ identityKeys: ['sections[].id', 'sections[].rows[].id', 'sections[].rows[].columns[].id', 'sections[].rows[].columns[].items[].id'],
25501
+ inputSchema: {
25502
+ type: 'object',
25503
+ required: ['target.itemId'],
25504
+ properties: {
25505
+ 'target.itemId': { type: 'string' },
25506
+ document: { type: 'object' },
25507
+ layout: { enum: ['block', 'inline'] },
25508
+ rootClassName: { type: ['string', 'null'] }
25509
+ }
25510
+ },
25511
+ failureModes: ['target-visual-block-not-found', 'invalid-rich-content-document'],
25512
+ description: 'Updates a richContent layout item by stable layout item id without touching fieldMetadata or form submit payload.'
25513
+ }
25514
+ }],
25515
+ validators: ['visual-block-exists', 'rich-content-document-valid', 'editor-round-trip-preserve'],
25516
+ affectedPaths: ['sections[].rows[].columns[].items'],
25517
+ submissionImpact: 'visual-only',
25518
+ preconditions: ['config-initialized', 'target-exists']
25519
+ },
25520
+ {
25521
+ operationId: 'layout.visualBlock.move',
25522
+ title: 'Mover bloco visual',
25523
+ scope: 'layout',
25524
+ targetKind: 'visualBlock',
25525
+ target: { kind: 'visualBlock', resolver: 'layout-item-by-id', ambiguityPolicy: 'fail', required: true },
25526
+ inputSchema: {
25527
+ type: 'object',
25528
+ required: ['targetSectionId', 'targetRowId', 'targetColumnId'],
25529
+ properties: {
25530
+ targetSectionId: { type: 'string' },
25531
+ targetRowId: { type: 'string' },
25532
+ targetColumnId: { type: 'string' },
25533
+ index: { type: 'number' }
25534
+ }
25535
+ },
25536
+ effects: [{
25537
+ kind: 'compile-domain-patch',
25538
+ handler: 'form-layout-visual-block-move',
25539
+ handlerContract: {
25540
+ reads: ['sections[].id', 'sections[].rows[].id', 'sections[].rows[].columns[].id', 'sections[].rows[].columns[].items[].id'],
25541
+ writes: ['sections[].rows[].columns[].items'],
25542
+ identityKeys: ['sections[].id', 'sections[].rows[].id', 'sections[].rows[].columns[].id', 'sections[].rows[].columns[].items[].id'],
25543
+ inputSchema: {
25544
+ type: 'object',
25545
+ required: ['target.itemId', 'targetSectionId', 'targetRowId', 'targetColumnId'],
25546
+ properties: {
25547
+ 'target.itemId': { type: 'string' },
25548
+ targetSectionId: { type: 'string' },
25549
+ targetRowId: { type: 'string' },
25550
+ targetColumnId: { type: 'string' },
25551
+ index: { type: 'number' }
25552
+ }
25553
+ },
25554
+ failureModes: ['target-visual-block-not-found', 'target-layout-location-not-found', 'ambiguous-visual-block-target'],
25555
+ description: 'Moves a richContent layout item by stable item, section, row, and column ids; index is insertion position only.'
25556
+ }
25557
+ }],
25558
+ validators: ['visual-block-exists', 'layout-target-exists', 'no-index-as-identity'],
25559
+ affectedPaths: ['sections[].rows[].columns[].items'],
25560
+ submissionImpact: 'visual-only',
25561
+ preconditions: ['config-initialized', 'target-exists']
25562
+ },
25563
+ {
25564
+ operationId: 'layout.visualBlock.remove',
25565
+ title: 'Remover bloco visual',
25566
+ scope: 'layout',
25567
+ targetKind: 'visualBlock',
25568
+ target: { kind: 'visualBlock', resolver: 'layout-item-by-id', ambiguityPolicy: 'fail', required: true },
25569
+ inputSchema: { type: 'object', properties: {} },
25570
+ effects: [{
25571
+ kind: 'compile-domain-patch',
25572
+ handler: 'form-layout-visual-block-remove',
25573
+ handlerContract: {
25574
+ reads: ['sections[].rows[].columns[].items[].id'],
25575
+ writes: ['sections[].rows[].columns[].items'],
25576
+ identityKeys: ['sections[].id', 'sections[].rows[].id', 'sections[].rows[].columns[].id', 'sections[].rows[].columns[].items[].id'],
25577
+ inputSchema: { type: 'object', required: ['target.itemId'], properties: { 'target.itemId': { type: 'string' } } },
25578
+ failureModes: ['target-visual-block-not-found', 'ambiguous-visual-block-target'],
25579
+ description: 'Removes a richContent layout item from sections[].rows[].columns[].items[] without touching fieldMetadata or form submit payload.'
25580
+ }
25581
+ }],
25582
+ destructive: true,
25583
+ requiresConfirmation: true,
25584
+ validators: ['visual-block-exists'],
25585
+ affectedPaths: ['sections[].rows[].columns[].items'],
25586
+ submissionImpact: 'visual-only',
25587
+ preconditions: ['config-initialized', 'target-exists']
25588
+ },
24484
25589
  {
24485
25590
  operationId: 'rule.visibility.add',
24486
25591
  title: 'Adicionar regra de visibilidade',
@@ -24503,7 +25608,7 @@ const PRAXIS_DYNAMIC_FORM_AUTHORING_MANIFEST = {
24503
25608
  effects: [{ kind: 'append-unique', path: 'formRules[]', key: 'id' }],
24504
25609
  validators: ['rule-id-unique', 'rule-target-refs-exist', 'json-logic-valid'],
24505
25610
  affectedPaths: ['formRules[]'],
24506
- submissionImpact: false,
25611
+ submissionImpact: 'affects-schema-backed-data',
24507
25612
  preconditions: ['config-initialized']
24508
25613
  },
24509
25614
  {
@@ -24534,7 +25639,7 @@ const PRAXIS_DYNAMIC_FORM_AUTHORING_MANIFEST = {
24534
25639
  effects: [{ kind: 'append-unique', path: 'formRules[]', key: 'id' }],
24535
25640
  validators: ['rule-id-unique', 'rule-target-refs-exist', 'json-logic-valid'],
24536
25641
  affectedPaths: ['formRules[]'],
24537
- submissionImpact: false,
25642
+ submissionImpact: 'affects-schema-backed-data',
24538
25643
  preconditions: ['config-initialized']
24539
25644
  },
24540
25645
  {
@@ -24549,7 +25654,7 @@ const PRAXIS_DYNAMIC_FORM_AUTHORING_MANIFEST = {
24549
25654
  requiresConfirmation: true,
24550
25655
  validators: ['rule-exists'],
24551
25656
  affectedPaths: ['formRules[]'],
24552
- submissionImpact: false,
25657
+ submissionImpact: 'affects-schema-backed-data',
24553
25658
  preconditions: ['config-initialized', 'target-exists']
24554
25659
  },
24555
25660
  // ─── ACTION OPERATIONS ────────────────────────────────────────────────────
@@ -24572,7 +25677,7 @@ const PRAXIS_DYNAMIC_FORM_AUTHORING_MANIFEST = {
24572
25677
  effects: [{ kind: 'merge-object', path: 'actions.submit' }],
24573
25678
  validators: ['editor-round-trip-preserve'],
24574
25679
  affectedPaths: ['actions.submit'],
24575
- submissionImpact: false,
25680
+ submissionImpact: 'affects-submission',
24576
25681
  preconditions: ['config-initialized']
24577
25682
  },
24578
25683
  {
@@ -24595,7 +25700,7 @@ const PRAXIS_DYNAMIC_FORM_AUTHORING_MANIFEST = {
24595
25700
  effects: [{ kind: 'merge-object', path: 'actions.cancel' }],
24596
25701
  validators: ['editor-round-trip-preserve'],
24597
25702
  affectedPaths: ['actions.cancel'],
24598
- submissionImpact: false,
25703
+ submissionImpact: 'config-only',
24599
25704
  preconditions: ['config-initialized']
24600
25705
  },
24601
25706
  {
@@ -24618,9 +25723,9 @@ const PRAXIS_DYNAMIC_FORM_AUTHORING_MANIFEST = {
24618
25723
  effects: [{ kind: 'merge-object', path: 'actions.reset' }],
24619
25724
  validators: ['editor-round-trip-preserve'],
24620
25725
  affectedPaths: ['actions.reset'],
24621
- submissionImpact: false,
25726
+ submissionImpact: 'config-only',
24622
25727
  preconditions: ['config-initialized']
24623
- }
25728
+ },
24624
25729
  ],
24625
25730
  validators: [
24626
25731
  {
@@ -24736,12 +25841,31 @@ const PRAXIS_DYNAMIC_FORM_AUTHORING_MANIFEST = {
24736
25841
  level: 'error',
24737
25842
  code: 'DF019',
24738
25843
  description: 'Edição não deve corromper propriedades críticas para o round-trip do editor. Aplicado após operações que afetam submitPolicy ou source de campos locais.'
25844
+ },
25845
+ {
25846
+ validatorId: 'visual-block-exists',
25847
+ level: 'error',
25848
+ code: 'DF020',
25849
+ description: 'O bloco visual alvo deve existir como item kind:"richContent" em sections[].rows[].columns[].items[].'
25850
+ },
25851
+ {
25852
+ validatorId: 'visual-block-id-unique',
25853
+ level: 'error',
25854
+ code: 'DF021',
25855
+ description: 'IDs de blocos visuais devem ser unicos entre os itens de layout do formulario.'
25856
+ },
25857
+ {
25858
+ validatorId: 'rich-content-document-valid',
25859
+ level: 'error',
25860
+ code: 'DF022',
25861
+ description: 'O document do bloco visual deve seguir o contrato RichContentDocument canonico.'
24739
25862
  }
24740
25863
  ],
24741
25864
  roundTripRequirements: [
24742
25865
  'strip-undefined',
24743
25866
  'normalize-json-logic',
24744
25867
  'stable-field-order',
25868
+ 'preserve-column-layout-items',
24745
25869
  'preserve-local-field-source',
24746
25870
  'preserve-section-row-column-ids'
24747
25871
  ],
@@ -24776,6 +25900,30 @@ const PRAXIS_DYNAMIC_FORM_AUTHORING_MANIFEST = {
24776
25900
  params: { targetSectionId: 'secao-contato', targetRowId: 'row-1', targetColumnId: 'col-1' },
24777
25901
  isPositive: true
24778
25902
  },
25903
+ {
25904
+ id: 'add-visual-block',
25905
+ request: 'Adicionar um aviso visual antes dos campos de contato',
25906
+ operationId: 'layout.visualBlock.add',
25907
+ target: 'col-contato',
25908
+ params: {
25909
+ id: 'aviso-contato',
25910
+ document: {
25911
+ kind: 'praxis.rich-content',
25912
+ version: '1.0.0',
25913
+ nodes: [{ type: 'text', text: 'Confira os dados antes de salvar.' }]
25914
+ },
25915
+ layout: 'block'
25916
+ },
25917
+ isPositive: true
25918
+ },
25919
+ {
25920
+ id: 'move-visual-block',
25921
+ request: 'Mover o aviso visual para a segunda coluna da secao de contato',
25922
+ operationId: 'layout.visualBlock.move',
25923
+ target: 'aviso-contato',
25924
+ params: { targetSectionId: 'secao-contato', targetRowId: 'row-1', targetColumnId: 'col-2' },
25925
+ isPositive: true
25926
+ },
24779
25927
  {
24780
25928
  id: 'add-visibility-rule',
24781
25929
  request: 'Ocultar o campo cpf quando o tipo de pessoa for jurídica',