@praxisui/page-builder 8.0.0-beta.31 → 8.0.0-beta.32

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.
@@ -1,29 +1,29 @@
1
- import * as i2$1 from '@angular/common';
2
- import { CommonModule } from '@angular/common';
3
1
  import * as i0 from '@angular/core';
4
2
  import { Inject, ChangeDetectionStrategy, Component, EventEmitter, Output, Input, signal, computed, effect, Optional, inject, ElementRef, input, output, InjectionToken, ENVIRONMENT_INITIALIZER, Injectable, Injector, ViewChild } from '@angular/core';
5
3
  import * as i2 from '@angular/material/button';
6
4
  import { MatButtonModule } from '@angular/material/button';
7
5
  import * as i1 from '@angular/material/dialog';
8
6
  import { MAT_DIALOG_DATA, MatDialogModule } from '@angular/material/dialog';
9
- import * as i3 from '@angular/material/icon';
7
+ import * as i2$1 from '@angular/material/icon';
10
8
  import { MatIconModule } from '@angular/material/icon';
11
9
  import * as i2$2 from '@praxisui/core';
12
10
  import { PraxisIconDirective, BUILTIN_SHELL_PRESETS, providePraxisI18n, PraxisI18nService, SETTINGS_PANEL_DATA as SETTINGS_PANEL_DATA$1, BUILTIN_PAGE_LAYOUT_PRESETS, BUILTIN_PAGE_THEME_PRESETS, deepMerge, generateId, ComponentMetadataRegistry, domainKnowledgeTimelineToRichContentDocument, DomainRuleService, DomainKnowledgeService, SETTINGS_PANEL_BRIDGE, DynamicWidgetPageComponent, DYNAMIC_PAGE_SHELL_EDITOR } from '@praxisui/core';
13
11
  export { WidgetShellComponent } from '@praxisui/core';
14
- import * as i3$1 from '@angular/material/tooltip';
12
+ import * as i3 from '@angular/material/tooltip';
15
13
  import { MatTooltipModule } from '@angular/material/tooltip';
16
- import * as i3$2 from '@angular/material/form-field';
14
+ import * as i3$1 from '@angular/material/form-field';
17
15
  import { MatFormFieldModule } from '@angular/material/form-field';
18
- import * as i6 from '@angular/material/input';
16
+ import * as i5 from '@angular/material/input';
19
17
  import { MatInputModule } from '@angular/material/input';
20
18
  import * as i1$1 from '@angular/forms';
21
19
  import { FormsModule, FormGroup, FormArray, FormControl, Validators, ReactiveFormsModule } from '@angular/forms';
22
- import * as i5 from '@angular/material/checkbox';
20
+ import * as i2$3 from '@angular/common';
21
+ import { CommonModule } from '@angular/common';
22
+ import * as i5$1 from '@angular/material/checkbox';
23
23
  import { MatCheckboxModule } from '@angular/material/checkbox';
24
- import * as i6$1 from '@angular/material/divider';
24
+ import * as i6 from '@angular/material/divider';
25
25
  import { MatDividerModule } from '@angular/material/divider';
26
- import * as i6$2 from '@angular/material/select';
26
+ import * as i6$1 from '@angular/material/select';
27
27
  import { MatSelectModule } from '@angular/material/select';
28
28
  import { BehaviorSubject, merge, timeout, map, switchMap, Observable, from, firstValueFrom, concatMap, catchError, of, filter, take } from 'rxjs';
29
29
  import { SETTINGS_PANEL_DATA } from '@praxisui/settings-panel';
@@ -42,8 +42,8 @@ class ConfirmDialogComponent {
42
42
  this.data = data;
43
43
  this.ref = ref;
44
44
  }
45
- static ɵfac = i0.ɵɵngDeclareFactory({ minVersion: "12.0.0", version: "20.3.17", ngImport: i0, type: ConfirmDialogComponent, deps: [{ token: MAT_DIALOG_DATA }, { token: i1.MatDialogRef }], target: i0.ɵɵFactoryTarget.Component });
46
- static ɵcmp = i0.ɵɵngDeclareComponent({ minVersion: "14.0.0", version: "20.3.17", type: ConfirmDialogComponent, isStandalone: true, selector: "praxis-confirm-dialog", ngImport: i0, template: `
45
+ static ɵfac = i0.ɵɵngDeclareFactory({ minVersion: "12.0.0", version: "21.2.14", ngImport: i0, type: ConfirmDialogComponent, deps: [{ token: MAT_DIALOG_DATA }, { token: i1.MatDialogRef }], target: i0.ɵɵFactoryTarget.Component });
46
+ static ɵcmp = i0.ɵɵngDeclareComponent({ minVersion: "14.0.0", version: "21.2.14", type: ConfirmDialogComponent, isStandalone: true, selector: "praxis-confirm-dialog", ngImport: i0, template: `
47
47
  <h2 mat-dialog-title>
48
48
  <mat-icon class="dlg-icon" aria-hidden="true" [praxisIcon]="data.icon || 'warning'"></mat-icon>
49
49
  {{ data.title || 'Confirmar ação' }}
@@ -55,11 +55,11 @@ class ConfirmDialogComponent {
55
55
  <button mat-button mat-dialog-close>{{ data.cancelLabel || 'Cancelar' }}</button>
56
56
  <button mat-raised-button color="warn" [mat-dialog-close]="true">{{ data.confirmLabel || 'Excluir' }}</button>
57
57
  </div>
58
- `, isInline: true, styles: [":host{color:var(--md-sys-color-on-surface)}.dlg-icon{vertical-align:middle;margin-right:8px;color:var(--md-sys-color-error)}\n"], dependencies: [{ kind: "ngmodule", type: CommonModule }, { kind: "ngmodule", type: MatDialogModule }, { kind: "directive", type: i1.MatDialogClose, selector: "[mat-dialog-close], [matDialogClose]", inputs: ["aria-label", "type", "mat-dialog-close", "matDialogClose"], exportAs: ["matDialogClose"] }, { kind: "directive", type: i1.MatDialogTitle, selector: "[mat-dialog-title], [matDialogTitle]", inputs: ["id"], exportAs: ["matDialogTitle"] }, { kind: "directive", type: i1.MatDialogActions, selector: "[mat-dialog-actions], mat-dialog-actions, [matDialogActions]", inputs: ["align"] }, { kind: "directive", type: i1.MatDialogContent, selector: "[mat-dialog-content], mat-dialog-content, [matDialogContent]" }, { kind: "ngmodule", type: MatButtonModule }, { kind: "component", type: i2.MatButton, selector: " button[matButton], a[matButton], button[mat-button], button[mat-raised-button], button[mat-flat-button], button[mat-stroked-button], a[mat-button], a[mat-raised-button], a[mat-flat-button], a[mat-stroked-button] ", inputs: ["matButton"], exportAs: ["matButton", "matAnchor"] }, { kind: "ngmodule", type: MatIconModule }, { kind: "component", type: i3.MatIcon, selector: "mat-icon", inputs: ["color", "inline", "svgIcon", "fontSet", "fontIcon"], exportAs: ["matIcon"] }, { kind: "directive", type: PraxisIconDirective, selector: "mat-icon[praxisIcon]", inputs: ["praxisIcon"] }], changeDetection: i0.ChangeDetectionStrategy.OnPush });
58
+ `, isInline: true, styles: [":host{color:var(--md-sys-color-on-surface)}.dlg-icon{vertical-align:middle;margin-right:8px;color:var(--md-sys-color-error)}\n"], dependencies: [{ kind: "ngmodule", type: MatDialogModule }, { kind: "directive", type: i1.MatDialogClose, selector: "[mat-dialog-close], [matDialogClose]", inputs: ["aria-label", "type", "mat-dialog-close", "matDialogClose"], exportAs: ["matDialogClose"] }, { kind: "directive", type: i1.MatDialogTitle, selector: "[mat-dialog-title], [matDialogTitle]", inputs: ["id"], exportAs: ["matDialogTitle"] }, { kind: "directive", type: i1.MatDialogActions, selector: "[mat-dialog-actions], mat-dialog-actions, [matDialogActions]", inputs: ["align"] }, { kind: "directive", type: i1.MatDialogContent, selector: "[mat-dialog-content], mat-dialog-content, [matDialogContent]" }, { kind: "ngmodule", type: MatButtonModule }, { kind: "component", type: i2.MatButton, selector: " button[matButton], a[matButton], button[mat-button], button[mat-raised-button], button[mat-flat-button], button[mat-stroked-button], a[mat-button], a[mat-raised-button], a[mat-flat-button], a[mat-stroked-button] ", inputs: ["matButton"], exportAs: ["matButton", "matAnchor"] }, { kind: "ngmodule", type: MatIconModule }, { kind: "component", type: i2$1.MatIcon, selector: "mat-icon", inputs: ["color", "inline", "svgIcon", "fontSet", "fontIcon"], exportAs: ["matIcon"] }, { kind: "directive", type: PraxisIconDirective, selector: "mat-icon[praxisIcon]", inputs: ["praxisIcon"] }], changeDetection: i0.ChangeDetectionStrategy.OnPush });
59
59
  }
60
- i0.ɵɵngDeclareClassMetadata({ minVersion: "12.0.0", version: "20.3.17", ngImport: i0, type: ConfirmDialogComponent, decorators: [{
60
+ i0.ɵɵngDeclareClassMetadata({ minVersion: "12.0.0", version: "21.2.14", ngImport: i0, type: ConfirmDialogComponent, decorators: [{
61
61
  type: Component,
62
- args: [{ selector: 'praxis-confirm-dialog', standalone: true, imports: [CommonModule, MatDialogModule, MatButtonModule, MatIconModule, PraxisIconDirective], template: `
62
+ args: [{ selector: 'praxis-confirm-dialog', standalone: true, imports: [MatDialogModule, MatButtonModule, MatIconModule, PraxisIconDirective], template: `
63
63
  <h2 mat-dialog-title>
64
64
  <mat-icon class="dlg-icon" aria-hidden="true" [praxisIcon]="data.icon || 'warning'"></mat-icon>
65
65
  {{ data.title || 'Confirmar ação' }}
@@ -83,8 +83,8 @@ class TileToolbarComponent {
83
83
  remove = new EventEmitter();
84
84
  settings = new EventEmitter();
85
85
  shell = new EventEmitter();
86
- static ɵfac = i0.ɵɵngDeclareFactory({ minVersion: "12.0.0", version: "20.3.17", ngImport: i0, type: TileToolbarComponent, deps: [], target: i0.ɵɵFactoryTarget.Component });
87
- static ɵcmp = i0.ɵɵngDeclareComponent({ minVersion: "14.0.0", version: "20.3.17", type: TileToolbarComponent, isStandalone: true, selector: "praxis-tile-toolbar", inputs: { selected: "selected", widgetType: "widgetType" }, outputs: { remove: "remove", settings: "settings", shell: "shell" }, ngImport: i0, template: `
86
+ static ɵfac = i0.ɵɵngDeclareFactory({ minVersion: "12.0.0", version: "21.2.14", ngImport: i0, type: TileToolbarComponent, deps: [], target: i0.ɵɵFactoryTarget.Component });
87
+ static ɵcmp = i0.ɵɵngDeclareComponent({ minVersion: "14.0.0", version: "21.2.14", type: TileToolbarComponent, isStandalone: true, selector: "praxis-tile-toolbar", inputs: { selected: "selected", widgetType: "widgetType" }, outputs: { remove: "remove", settings: "settings", shell: "shell" }, ngImport: i0, template: `
88
88
  <div class="pdx-tile-toolbar" [class.always-visible]="selected" role="toolbar" aria-label="Ações do widget">
89
89
  <button
90
90
  mat-mini-fab
@@ -121,11 +121,11 @@ class TileToolbarComponent {
121
121
  <mat-icon [praxisIcon]="'delete'"></mat-icon>
122
122
  </button>
123
123
  </div>
124
- `, isInline: true, styles: [":host{position:absolute;inset:0;pointer-events:none}.pdx-tile-toolbar{position:absolute;right:6px;top:-18px;display:flex;gap:6px;z-index:5;opacity:0;transition:opacity .12s ease-in-out;pointer-events:auto;background:var(--md-sys-color-surface-container-low);-webkit-backdrop-filter:blur(4px);backdrop-filter:blur(4px);border-radius:999px;padding:4px;box-shadow:var(--mat-elevation-level3)}.pdx-tile-toolbar.always-visible{opacity:1}\n"], dependencies: [{ kind: "ngmodule", type: CommonModule }, { kind: "ngmodule", type: MatButtonModule }, { kind: "component", type: i2.MatMiniFabButton, selector: "button[mat-mini-fab], a[mat-mini-fab], button[matMiniFab], a[matMiniFab]", exportAs: ["matButton", "matAnchor"] }, { kind: "ngmodule", type: MatIconModule }, { kind: "component", type: i3.MatIcon, selector: "mat-icon", inputs: ["color", "inline", "svgIcon", "fontSet", "fontIcon"], exportAs: ["matIcon"] }, { kind: "ngmodule", type: MatTooltipModule }, { kind: "directive", type: i3$1.MatTooltip, selector: "[matTooltip]", inputs: ["matTooltipPosition", "matTooltipPositionAtOrigin", "matTooltipDisabled", "matTooltipShowDelay", "matTooltipHideDelay", "matTooltipTouchGestures", "matTooltip", "matTooltipClass"], exportAs: ["matTooltip"] }, { kind: "directive", type: PraxisIconDirective, selector: "mat-icon[praxisIcon]", inputs: ["praxisIcon"] }], changeDetection: i0.ChangeDetectionStrategy.OnPush });
124
+ `, isInline: true, styles: [":host{position:absolute;inset:0;pointer-events:none}.pdx-tile-toolbar{position:absolute;right:6px;top:-18px;display:flex;gap:6px;z-index:5;opacity:0;transition:opacity .12s ease-in-out;pointer-events:auto;background:var(--md-sys-color-surface-container-low);-webkit-backdrop-filter:blur(4px);backdrop-filter:blur(4px);border-radius:999px;padding:4px;box-shadow:var(--mat-elevation-level3)}.pdx-tile-toolbar.always-visible{opacity:1}\n"], dependencies: [{ kind: "ngmodule", type: MatButtonModule }, { kind: "component", type: i2.MatMiniFabButton, selector: "button[mat-mini-fab], a[mat-mini-fab], button[matMiniFab], a[matMiniFab]", exportAs: ["matButton", "matAnchor"] }, { kind: "ngmodule", type: MatIconModule }, { kind: "component", type: i2$1.MatIcon, selector: "mat-icon", inputs: ["color", "inline", "svgIcon", "fontSet", "fontIcon"], exportAs: ["matIcon"] }, { kind: "ngmodule", type: MatTooltipModule }, { kind: "directive", type: i3.MatTooltip, selector: "[matTooltip]", inputs: ["matTooltipPosition", "matTooltipPositionAtOrigin", "matTooltipDisabled", "matTooltipShowDelay", "matTooltipHideDelay", "matTooltipTouchGestures", "matTooltip", "matTooltipClass"], exportAs: ["matTooltip"] }, { kind: "directive", type: PraxisIconDirective, selector: "mat-icon[praxisIcon]", inputs: ["praxisIcon"] }], changeDetection: i0.ChangeDetectionStrategy.OnPush });
125
125
  }
126
- i0.ɵɵngDeclareClassMetadata({ minVersion: "12.0.0", version: "20.3.17", ngImport: i0, type: TileToolbarComponent, decorators: [{
126
+ i0.ɵɵngDeclareClassMetadata({ minVersion: "12.0.0", version: "21.2.14", ngImport: i0, type: TileToolbarComponent, decorators: [{
127
127
  type: Component,
128
- args: [{ selector: 'praxis-tile-toolbar', standalone: true, imports: [CommonModule, MatButtonModule, MatIconModule, MatTooltipModule, PraxisIconDirective], template: `
128
+ args: [{ selector: 'praxis-tile-toolbar', standalone: true, imports: [MatButtonModule, MatIconModule, MatTooltipModule, PraxisIconDirective], template: `
129
129
  <div class="pdx-tile-toolbar" [class.always-visible]="selected" role="toolbar" aria-label="Ações do widget">
130
130
  <button
131
131
  mat-mini-fab
@@ -187,60 +187,80 @@ class FloatingToolbarComponent {
187
187
  settings = new EventEmitter();
188
188
  preview = new EventEmitter();
189
189
  save = new EventEmitter();
190
- static ɵfac = i0.ɵɵngDeclareFactory({ minVersion: "12.0.0", version: "20.3.17", ngImport: i0, type: FloatingToolbarComponent, deps: [], target: i0.ɵɵFactoryTarget.Component });
191
- static ɵcmp = i0.ɵɵngDeclareComponent({ minVersion: "14.0.0", version: "20.3.17", type: FloatingToolbarComponent, isStandalone: true, selector: "praxis-floating-toolbar", inputs: { visible: "visible", canUndo: "canUndo", canRedo: "canRedo", showSave: "showSave", showPreview: "showPreview" }, outputs: { add: "add", undo: "undo", redo: "redo", settings: "settings", preview: "preview", save: "save" }, ngImport: i0, template: `
192
- <div class="pdx-floating-toolbar" *ngIf="visible">
193
- <div class="pdx-actions">
194
- <button mat-mini-fab color="primary" (click)="add.emit()" [matTooltip]="'Inserir componente'" aria-label="Inserir componente">
195
- <mat-icon [praxisIcon]="'add'"></mat-icon>
196
- </button>
197
- <button *ngIf="showSave" mat-mini-fab color="accent" (click)="save.emit()" [matTooltip]="'Salvar pagina'" aria-label="Salvar pagina">
198
- <mat-icon [praxisIcon]="'save'"></mat-icon>
199
- </button>
200
- <button *ngIf="canUndo" mat-mini-fab (click)="undo.emit()" [matTooltip]="'Desfazer'" aria-label="Desfazer">
201
- <mat-icon [praxisIcon]="'undo'"></mat-icon>
202
- </button>
203
- <button *ngIf="canRedo" mat-mini-fab (click)="redo.emit()" [matTooltip]="'Refazer'" aria-label="Refazer">
204
- <mat-icon [praxisIcon]="'redo'"></mat-icon>
205
- </button>
206
- <button mat-mini-fab (click)="settings.emit()" [matTooltip]="'Configuracoes da pagina'" aria-label="Configuracoes da pagina">
207
- <mat-icon [praxisIcon]="'settings'"></mat-icon>
208
- </button>
209
- <button *ngIf="showPreview" mat-mini-fab (click)="preview.emit()" [matTooltip]="'Pre-visualizar'" aria-label="Pre-visualizar">
210
- <mat-icon [praxisIcon]="'visibility'"></mat-icon>
211
- </button>
212
- <ng-content select="[pdx-toolbar-extra]"></ng-content>
190
+ static ɵfac = i0.ɵɵngDeclareFactory({ minVersion: "12.0.0", version: "21.2.14", ngImport: i0, type: FloatingToolbarComponent, deps: [], target: i0.ɵɵFactoryTarget.Component });
191
+ static ɵcmp = i0.ɵɵngDeclareComponent({ minVersion: "17.0.0", version: "21.2.14", type: FloatingToolbarComponent, isStandalone: true, selector: "praxis-floating-toolbar", inputs: { visible: "visible", canUndo: "canUndo", canRedo: "canRedo", showSave: "showSave", showPreview: "showPreview" }, outputs: { add: "add", undo: "undo", redo: "redo", settings: "settings", preview: "preview", save: "save" }, ngImport: i0, template: `
192
+ @if (visible) {
193
+ <div class="pdx-floating-toolbar">
194
+ <div class="pdx-actions">
195
+ <button mat-mini-fab color="primary" (click)="add.emit()" [matTooltip]="'Inserir componente'" aria-label="Inserir componente">
196
+ <mat-icon [praxisIcon]="'add'"></mat-icon>
197
+ </button>
198
+ @if (showSave) {
199
+ <button mat-mini-fab color="accent" (click)="save.emit()" [matTooltip]="'Salvar pagina'" aria-label="Salvar pagina">
200
+ <mat-icon [praxisIcon]="'save'"></mat-icon>
201
+ </button>
202
+ }
203
+ @if (canUndo) {
204
+ <button mat-mini-fab (click)="undo.emit()" [matTooltip]="'Desfazer'" aria-label="Desfazer">
205
+ <mat-icon [praxisIcon]="'undo'"></mat-icon>
206
+ </button>
207
+ }
208
+ @if (canRedo) {
209
+ <button mat-mini-fab (click)="redo.emit()" [matTooltip]="'Refazer'" aria-label="Refazer">
210
+ <mat-icon [praxisIcon]="'redo'"></mat-icon>
211
+ </button>
212
+ }
213
+ <button mat-mini-fab (click)="settings.emit()" [matTooltip]="'Configuracoes da pagina'" aria-label="Configuracoes da pagina">
214
+ <mat-icon [praxisIcon]="'settings'"></mat-icon>
215
+ </button>
216
+ @if (showPreview) {
217
+ <button mat-mini-fab (click)="preview.emit()" [matTooltip]="'Pre-visualizar'" aria-label="Pre-visualizar">
218
+ <mat-icon [praxisIcon]="'visibility'"></mat-icon>
219
+ </button>
220
+ }
221
+ <ng-content select="[pdx-toolbar-extra]"></ng-content>
222
+ </div>
213
223
  </div>
214
- </div>
215
- `, isInline: true, styles: [":host{position:absolute;inset:0;pointer-events:none}.pdx-floating-toolbar{position:absolute;right:16px;bottom:16px;display:flex;gap:8px;align-items:center;pointer-events:auto}.pdx-actions{display:flex;gap:8px}@media(max-width:720px){.pdx-actions{gap:6px}.pdx-floating-toolbar{right:12px;bottom:12px}}\n"], dependencies: [{ kind: "ngmodule", type: CommonModule }, { kind: "directive", type: i2$1.NgIf, selector: "[ngIf]", inputs: ["ngIf", "ngIfThen", "ngIfElse"] }, { kind: "ngmodule", type: MatButtonModule }, { kind: "component", type: i2.MatMiniFabButton, selector: "button[mat-mini-fab], a[mat-mini-fab], button[matMiniFab], a[matMiniFab]", exportAs: ["matButton", "matAnchor"] }, { kind: "ngmodule", type: MatIconModule }, { kind: "component", type: i3.MatIcon, selector: "mat-icon", inputs: ["color", "inline", "svgIcon", "fontSet", "fontIcon"], exportAs: ["matIcon"] }, { kind: "ngmodule", type: MatTooltipModule }, { kind: "directive", type: i3$1.MatTooltip, selector: "[matTooltip]", inputs: ["matTooltipPosition", "matTooltipPositionAtOrigin", "matTooltipDisabled", "matTooltipShowDelay", "matTooltipHideDelay", "matTooltipTouchGestures", "matTooltip", "matTooltipClass"], exportAs: ["matTooltip"] }, { kind: "directive", type: PraxisIconDirective, selector: "mat-icon[praxisIcon]", inputs: ["praxisIcon"] }], changeDetection: i0.ChangeDetectionStrategy.OnPush });
224
+ }
225
+ `, isInline: true, styles: [":host{position:absolute;inset:0;pointer-events:none}.pdx-floating-toolbar{position:absolute;right:16px;bottom:16px;display:flex;gap:8px;align-items:center;pointer-events:auto}.pdx-actions{display:flex;gap:8px}@media(max-width:720px){.pdx-actions{gap:6px}.pdx-floating-toolbar{right:12px;bottom:12px}}\n"], dependencies: [{ kind: "ngmodule", type: MatButtonModule }, { kind: "component", type: i2.MatMiniFabButton, selector: "button[mat-mini-fab], a[mat-mini-fab], button[matMiniFab], a[matMiniFab]", exportAs: ["matButton", "matAnchor"] }, { kind: "ngmodule", type: MatIconModule }, { kind: "component", type: i2$1.MatIcon, selector: "mat-icon", inputs: ["color", "inline", "svgIcon", "fontSet", "fontIcon"], exportAs: ["matIcon"] }, { kind: "ngmodule", type: MatTooltipModule }, { kind: "directive", type: i3.MatTooltip, selector: "[matTooltip]", inputs: ["matTooltipPosition", "matTooltipPositionAtOrigin", "matTooltipDisabled", "matTooltipShowDelay", "matTooltipHideDelay", "matTooltipTouchGestures", "matTooltip", "matTooltipClass"], exportAs: ["matTooltip"] }, { kind: "directive", type: PraxisIconDirective, selector: "mat-icon[praxisIcon]", inputs: ["praxisIcon"] }], changeDetection: i0.ChangeDetectionStrategy.OnPush });
216
226
  }
217
- i0.ɵɵngDeclareClassMetadata({ minVersion: "12.0.0", version: "20.3.17", ngImport: i0, type: FloatingToolbarComponent, decorators: [{
227
+ i0.ɵɵngDeclareClassMetadata({ minVersion: "12.0.0", version: "21.2.14", ngImport: i0, type: FloatingToolbarComponent, decorators: [{
218
228
  type: Component,
219
- args: [{ selector: 'praxis-floating-toolbar', standalone: true, imports: [CommonModule, MatButtonModule, MatIconModule, MatTooltipModule, PraxisIconDirective], template: `
220
- <div class="pdx-floating-toolbar" *ngIf="visible">
221
- <div class="pdx-actions">
222
- <button mat-mini-fab color="primary" (click)="add.emit()" [matTooltip]="'Inserir componente'" aria-label="Inserir componente">
223
- <mat-icon [praxisIcon]="'add'"></mat-icon>
224
- </button>
225
- <button *ngIf="showSave" mat-mini-fab color="accent" (click)="save.emit()" [matTooltip]="'Salvar pagina'" aria-label="Salvar pagina">
226
- <mat-icon [praxisIcon]="'save'"></mat-icon>
227
- </button>
228
- <button *ngIf="canUndo" mat-mini-fab (click)="undo.emit()" [matTooltip]="'Desfazer'" aria-label="Desfazer">
229
- <mat-icon [praxisIcon]="'undo'"></mat-icon>
230
- </button>
231
- <button *ngIf="canRedo" mat-mini-fab (click)="redo.emit()" [matTooltip]="'Refazer'" aria-label="Refazer">
232
- <mat-icon [praxisIcon]="'redo'"></mat-icon>
233
- </button>
234
- <button mat-mini-fab (click)="settings.emit()" [matTooltip]="'Configuracoes da pagina'" aria-label="Configuracoes da pagina">
235
- <mat-icon [praxisIcon]="'settings'"></mat-icon>
236
- </button>
237
- <button *ngIf="showPreview" mat-mini-fab (click)="preview.emit()" [matTooltip]="'Pre-visualizar'" aria-label="Pre-visualizar">
238
- <mat-icon [praxisIcon]="'visibility'"></mat-icon>
239
- </button>
240
- <ng-content select="[pdx-toolbar-extra]"></ng-content>
229
+ args: [{ selector: 'praxis-floating-toolbar', standalone: true, imports: [MatButtonModule, MatIconModule, MatTooltipModule, PraxisIconDirective], template: `
230
+ @if (visible) {
231
+ <div class="pdx-floating-toolbar">
232
+ <div class="pdx-actions">
233
+ <button mat-mini-fab color="primary" (click)="add.emit()" [matTooltip]="'Inserir componente'" aria-label="Inserir componente">
234
+ <mat-icon [praxisIcon]="'add'"></mat-icon>
235
+ </button>
236
+ @if (showSave) {
237
+ <button mat-mini-fab color="accent" (click)="save.emit()" [matTooltip]="'Salvar pagina'" aria-label="Salvar pagina">
238
+ <mat-icon [praxisIcon]="'save'"></mat-icon>
239
+ </button>
240
+ }
241
+ @if (canUndo) {
242
+ <button mat-mini-fab (click)="undo.emit()" [matTooltip]="'Desfazer'" aria-label="Desfazer">
243
+ <mat-icon [praxisIcon]="'undo'"></mat-icon>
244
+ </button>
245
+ }
246
+ @if (canRedo) {
247
+ <button mat-mini-fab (click)="redo.emit()" [matTooltip]="'Refazer'" aria-label="Refazer">
248
+ <mat-icon [praxisIcon]="'redo'"></mat-icon>
249
+ </button>
250
+ }
251
+ <button mat-mini-fab (click)="settings.emit()" [matTooltip]="'Configuracoes da pagina'" aria-label="Configuracoes da pagina">
252
+ <mat-icon [praxisIcon]="'settings'"></mat-icon>
253
+ </button>
254
+ @if (showPreview) {
255
+ <button mat-mini-fab (click)="preview.emit()" [matTooltip]="'Pre-visualizar'" aria-label="Pre-visualizar">
256
+ <mat-icon [praxisIcon]="'visibility'"></mat-icon>
257
+ </button>
258
+ }
259
+ <ng-content select="[pdx-toolbar-extra]"></ng-content>
260
+ </div>
241
261
  </div>
242
- </div>
243
- `, changeDetection: ChangeDetectionStrategy.OnPush, styles: [":host{position:absolute;inset:0;pointer-events:none}.pdx-floating-toolbar{position:absolute;right:16px;bottom:16px;display:flex;gap:8px;align-items:center;pointer-events:auto}.pdx-actions{display:flex;gap:8px}@media(max-width:720px){.pdx-actions{gap:6px}.pdx-floating-toolbar{right:12px;bottom:12px}}\n"] }]
262
+ }
263
+ `, changeDetection: ChangeDetectionStrategy.OnPush, styles: [":host{position:absolute;inset:0;pointer-events:none}.pdx-floating-toolbar{position:absolute;right:16px;bottom:16px;display:flex;gap:8px;align-items:center;pointer-events:auto}.pdx-actions{display:flex;gap:8px}@media(max-width:720px){.pdx-actions{gap:6px}.pdx-floating-toolbar{right:12px;bottom:12px}}\n"] }]
244
264
  }], propDecorators: { visible: [{
245
265
  type: Input
246
266
  }], canUndo: [{
@@ -269,9 +289,9 @@ class ComponentPaletteDialogComponent {
269
289
  dialogRef;
270
290
  registry;
271
291
  data;
272
- query = signal('', ...(ngDevMode ? [{ debugName: "query" }] : []));
273
- all = signal([], ...(ngDevMode ? [{ debugName: "all" }] : []));
274
- filtered = computed(() => this.applyFilters(), ...(ngDevMode ? [{ debugName: "filtered" }] : []));
292
+ query = signal('', ...(ngDevMode ? [{ debugName: "query" }] : /* istanbul ignore next */ []));
293
+ all = signal([], ...(ngDevMode ? [{ debugName: "all" }] : /* istanbul ignore next */ []));
294
+ filtered = computed(() => this.applyFilters(), ...(ngDevMode ? [{ debugName: "filtered" }] : /* istanbul ignore next */ []));
275
295
  density = computed(() => {
276
296
  const n = this.filtered().length;
277
297
  if (n <= 4)
@@ -279,7 +299,7 @@ class ComponentPaletteDialogComponent {
279
299
  if (n > 12)
280
300
  return 'dense';
281
301
  return 'normal';
282
- }, ...(ngDevMode ? [{ debugName: "density" }] : []));
302
+ }, ...(ngDevMode ? [{ debugName: "density" }] : /* istanbul ignore next */ []));
283
303
  constructor(dialogRef, registry, data) {
284
304
  this.dialogRef = dialogRef;
285
305
  this.registry = registry;
@@ -311,7 +331,7 @@ class ComponentPaletteDialogComponent {
311
331
  if (container && container._config) {
312
332
  container._config.width = width;
313
333
  }
314
- }, ...(ngDevMode ? [{ debugName: "_adjustSizeEffect" }] : []));
334
+ }, ...(ngDevMode ? [{ debugName: "_adjustSizeEffect" }] : /* istanbul ignore next */ []));
315
335
  applyFilters() {
316
336
  const list = (this.all() || []);
317
337
  const q = (this.query() || '').toLowerCase();
@@ -428,8 +448,8 @@ class ComponentPaletteDialogComponent {
428
448
  hasDataSourceInputs(meta) {
429
449
  return (meta.inputs ?? []).some((input) => /resource|schema|api|data(source)?|endpoint|resolver/i.test(input.name));
430
450
  }
431
- static ɵfac = i0.ɵɵngDeclareFactory({ minVersion: "12.0.0", version: "20.3.17", ngImport: i0, type: ComponentPaletteDialogComponent, deps: [{ token: i1.MatDialogRef }, { token: i2$2.ComponentMetadataRegistry }, { token: MAT_DIALOG_DATA }], target: i0.ɵɵFactoryTarget.Component });
432
- static ɵcmp = i0.ɵɵngDeclareComponent({ minVersion: "14.0.0", version: "20.3.17", type: ComponentPaletteDialogComponent, isStandalone: true, selector: "praxis-component-palette-dialog", ngImport: i0, template: `
451
+ static ɵfac = i0.ɵɵngDeclareFactory({ minVersion: "12.0.0", version: "21.2.14", ngImport: i0, type: ComponentPaletteDialogComponent, deps: [{ token: i1.MatDialogRef }, { token: i2$2.ComponentMetadataRegistry }, { token: MAT_DIALOG_DATA }], target: i0.ɵɵFactoryTarget.Component });
452
+ static ɵcmp = i0.ɵɵngDeclareComponent({ minVersion: "17.0.0", version: "21.2.14", type: ComponentPaletteDialogComponent, isStandalone: true, selector: "praxis-component-palette-dialog", ngImport: i0, template: `
433
453
  <h2 mat-dialog-title>
434
454
  <div class="dlg-title">
435
455
  <mat-icon class="dlg-icon" [praxisIcon]="'widgets'"></mat-icon>
@@ -450,52 +470,57 @@ class ComponentPaletteDialogComponent {
450
470
  (ngModelChange)="query.set($event)"
451
471
  placeholder="Nome, capability ou readiness"
452
472
  data-testid="component-palette-search"
453
- />
473
+ />
454
474
  </mat-form-field>
455
- <div [class]="'pdx-grid ' + density()" *ngIf="filtered().length; else emptyState">
456
- <button
457
- *ngFor="let entry of filtered(); trackBy: trackById"
458
- class="pdx-card mat-elevation-z2"
459
- type="button"
460
- [attr.aria-label]="'Adicionar ' + entry.title"
461
- (click)="select(entry)"
462
- >
463
- <div class="pdx-card-icon">
464
- <mat-icon [praxisIcon]="entry.icon"></mat-icon>
465
- </div>
466
- <div class="pdx-card-body">
467
- <div class="pdx-card-title">{{ entry.title }}</div>
468
- <div class="pdx-card-desc">{{ entry.description }}</div>
469
- <div class="pdx-card-badges" *ngIf="entry.badges.length">
470
- <span
471
- *ngFor="let badge of entry.badges"
472
- class="pdx-card-badge"
473
- [class]="'pdx-card-badge ' + badge.tone"
474
- [title]="badge.description"
475
+ @if (filtered().length) {
476
+ <div [class]="'pdx-grid ' + density()">
477
+ @for (entry of filtered(); track trackById($index, entry)) {
478
+ <button
479
+ class="pdx-card mat-elevation-z2"
480
+ type="button"
481
+ [attr.aria-label]="'Adicionar ' + entry.title"
482
+ (click)="select(entry)"
475
483
  >
476
- <mat-icon [praxisIcon]="badge.icon" aria-hidden="true"></mat-icon>
477
- {{ badge.label }}
478
- </span>
479
- </div>
480
- </div>
481
- </button>
482
- </div>
483
-
484
- <ng-template #emptyState>
484
+ <div class="pdx-card-icon">
485
+ <mat-icon [praxisIcon]="entry.icon"></mat-icon>
486
+ </div>
487
+ <div class="pdx-card-body">
488
+ <div class="pdx-card-title">{{ entry.title }}</div>
489
+ <div class="pdx-card-desc">{{ entry.description }}</div>
490
+ @if (entry.badges.length) {
491
+ <div class="pdx-card-badges">
492
+ @for (badge of entry.badges; track badge) {
493
+ <span
494
+ class="pdx-card-badge"
495
+ [class]="'pdx-card-badge ' + badge.tone"
496
+ [title]="badge.description"
497
+ >
498
+ <mat-icon [praxisIcon]="badge.icon" aria-hidden="true"></mat-icon>
499
+ {{ badge.label }}
500
+ </span>
501
+ }
502
+ </div>
503
+ }
504
+ </div>
505
+ </button>
506
+ }
507
+ </div>
508
+ } @else {
485
509
  <div class="pdx-empty">
486
510
  <mat-icon [praxisIcon]="'sentiment_dissatisfied'"></mat-icon>
487
511
  <div>Nenhum componente disponível</div>
488
512
  </div>
489
- </ng-template>
513
+ }
514
+
490
515
  </div>
491
516
  <div mat-dialog-actions align="end">
492
517
  <button mat-stroked-button color="primary" mat-dialog-close>Cancelar</button>
493
518
  </div>
494
- `, isInline: true, styles: [":host{display:block}h2[mat-dialog-title]{margin:0;padding:12px 24px 10px;border-bottom:1px solid var(--md-sys-color-outline-variant)}.dlg-title{display:flex;align-items:center;gap:10px}.dlg-icon{color:var(--md-sys-color-primary)}.dlg-head{font-size:18px;font-weight:600;line-height:1.2}.dlg-sub{font-size:12px;opacity:.85;color:var(--md-sys-color-on-surface-variant)}.pdx-palette-content{min-width:480px;max-width:920px;padding-top:8px}.pdx-palette-search{width:100%;margin-bottom:12px}.pdx-grid{display:grid;grid-template-columns:repeat(auto-fill,minmax(260px,1fr));gap:14px}.pdx-grid.dense{grid-template-columns:repeat(auto-fill,minmax(220px,1fr));gap:12px}.pdx-grid.roomy{grid-template-columns:repeat(auto-fill,minmax(300px,1fr));gap:16px}.pdx-card{appearance:none;position:relative;display:grid;grid-template-columns:44px 1fr;grid-template-rows:auto auto;gap:10px;padding:14px;border:1px solid transparent;border-radius:14px;cursor:pointer;outline:none;color:inherit;font:inherit;min-height:92px;text-align:left;background:var(--md-sys-color-surface);border-color:var(--md-sys-color-outline-variant);transition:box-shadow .2s ease,background .25s ease,transform .06s ease}.pdx-grid.dense .pdx-card{padding:10px;border-radius:12px;min-height:84px}.pdx-grid.roomy .pdx-card{padding:16px;border-radius:16px;min-height:100px}.pdx-card:focus,.pdx-card:hover{box-shadow:var(--mat-elevation-level4);background:var(--md-sys-color-surface-container-low);border-color:var(--md-sys-color-primary)}.pdx-card:focus-visible{outline:2px solid var(--md-sys-color-primary);outline-offset:2px}.pdx-card:active{transform:translateY(1px)}.pdx-card-icon{grid-row:span 2;display:flex;align-items:center;justify-content:center;color:var(--md-sys-color-primary)}.pdx-card-title{font-weight:600;line-height:1.2;overflow:hidden;text-overflow:ellipsis;white-space:nowrap}.pdx-card-desc{color:var(--md-sys-color-on-surface-variant);display:-webkit-box;-webkit-line-clamp:3;-webkit-box-orient:vertical;overflow:hidden;word-break:break-word}.pdx-card-badges{display:flex;flex-wrap:wrap;gap:6px;margin-top:8px}.pdx-card-badge{display:inline-flex;align-items:center;gap:4px;min-height:22px;padding:2px 8px;border-radius:999px;border:1px solid var(--md-sys-color-outline-variant);color:var(--md-sys-color-on-surface-variant);background:var(--md-sys-color-surface-container-highest);font-size:11px;line-height:1.2;font-weight:600;letter-spacing:.01em}.pdx-card-badge mat-icon{width:14px;height:14px;font-size:14px}.pdx-card-badge.ready{color:var(--md-sys-color-primary);border-color:color-mix(in srgb,var(--md-sys-color-primary) 45%,transparent);background:color-mix(in srgb,var(--md-sys-color-primary-container) 72%,transparent)}.pdx-card-badge.info{color:var(--md-sys-color-tertiary);border-color:color-mix(in srgb,var(--md-sys-color-tertiary) 38%,transparent);background:color-mix(in srgb,var(--md-sys-color-tertiary-container) 68%,transparent)}.pdx-card-badge.warning{color:var(--md-sys-color-error);border-color:color-mix(in srgb,var(--md-sys-color-error) 35%,transparent);background:color-mix(in srgb,var(--md-sys-color-error-container) 62%,transparent)}.pdx-empty{padding:24px;display:grid;place-items:center;color:var(--md-sys-color-on-surface-variant);gap:8px}@media(max-width:600px){.pdx-palette-content{min-width:320px}.pdx-grid{grid-template-columns:repeat(auto-fill,minmax(200px,1fr))}}\n"], dependencies: [{ kind: "ngmodule", type: CommonModule }, { kind: "directive", type: i2$1.NgForOf, selector: "[ngFor][ngForOf]", inputs: ["ngForOf", "ngForTrackBy", "ngForTemplate"] }, { kind: "directive", type: i2$1.NgIf, selector: "[ngIf]", inputs: ["ngIf", "ngIfThen", "ngIfElse"] }, { kind: "ngmodule", type: FormsModule }, { kind: "directive", type: i1$1.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$1.NgControlStatus, selector: "[formControlName],[ngModel],[formControl]" }, { kind: "directive", type: i1$1.NgModel, selector: "[ngModel]:not([formControlName]):not([formControl])", inputs: ["name", "disabled", "ngModel", "ngModelOptions"], outputs: ["ngModelChange"], exportAs: ["ngModel"] }, { kind: "ngmodule", type: MatDialogModule }, { kind: "directive", type: i1.MatDialogClose, selector: "[mat-dialog-close], [matDialogClose]", inputs: ["aria-label", "type", "mat-dialog-close", "matDialogClose"], exportAs: ["matDialogClose"] }, { kind: "directive", type: i1.MatDialogTitle, selector: "[mat-dialog-title], [matDialogTitle]", inputs: ["id"], exportAs: ["matDialogTitle"] }, { kind: "directive", type: i1.MatDialogActions, selector: "[mat-dialog-actions], mat-dialog-actions, [matDialogActions]", inputs: ["align"] }, { kind: "directive", type: i1.MatDialogContent, selector: "[mat-dialog-content], mat-dialog-content, [matDialogContent]" }, { kind: "ngmodule", type: MatFormFieldModule }, { kind: "component", type: i3$2.MatFormField, selector: "mat-form-field", inputs: ["hideRequiredMarker", "color", "floatLabel", "appearance", "subscriptSizing", "hintLabel"], exportAs: ["matFormField"] }, { kind: "directive", type: i3$2.MatLabel, selector: "mat-label" }, { kind: "directive", type: i3$2.MatPrefix, selector: "[matPrefix], [matIconPrefix], [matTextPrefix]", inputs: ["matTextPrefix"] }, { kind: "ngmodule", type: MatInputModule }, { kind: "directive", type: i6.MatInput, selector: "input[matInput], textarea[matInput], select[matNativeControl], input[matNativeControl], textarea[matNativeControl]", inputs: ["disabled", "id", "placeholder", "name", "required", "type", "errorStateMatcher", "aria-describedby", "value", "readonly", "disabledInteractive"], exportAs: ["matInput"] }, { kind: "ngmodule", type: MatIconModule }, { kind: "component", type: i3.MatIcon, selector: "mat-icon", inputs: ["color", "inline", "svgIcon", "fontSet", "fontIcon"], exportAs: ["matIcon"] }, { kind: "ngmodule", type: MatButtonModule }, { kind: "component", type: i2.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: "directive", type: PraxisIconDirective, selector: "mat-icon[praxisIcon]", inputs: ["praxisIcon"] }], changeDetection: i0.ChangeDetectionStrategy.OnPush });
519
+ `, isInline: true, styles: [":host{display:block}h2[mat-dialog-title]{margin:0;padding:12px 24px 10px;border-bottom:1px solid var(--md-sys-color-outline-variant)}.dlg-title{display:flex;align-items:center;gap:10px}.dlg-icon{color:var(--md-sys-color-primary)}.dlg-head{font-size:18px;font-weight:600;line-height:1.2}.dlg-sub{font-size:12px;opacity:.85;color:var(--md-sys-color-on-surface-variant)}.pdx-palette-content{min-width:480px;max-width:920px;padding-top:8px}.pdx-palette-search{width:100%;margin-bottom:12px}.pdx-grid{display:grid;grid-template-columns:repeat(auto-fill,minmax(260px,1fr));gap:14px}.pdx-grid.dense{grid-template-columns:repeat(auto-fill,minmax(220px,1fr));gap:12px}.pdx-grid.roomy{grid-template-columns:repeat(auto-fill,minmax(300px,1fr));gap:16px}.pdx-card{appearance:none;position:relative;display:grid;grid-template-columns:44px 1fr;grid-template-rows:auto auto;gap:10px;padding:14px;border:1px solid transparent;border-radius:14px;cursor:pointer;outline:none;color:inherit;font:inherit;min-height:92px;text-align:left;background:var(--md-sys-color-surface);border-color:var(--md-sys-color-outline-variant);transition:box-shadow .2s ease,background .25s ease,transform .06s ease}.pdx-grid.dense .pdx-card{padding:10px;border-radius:12px;min-height:84px}.pdx-grid.roomy .pdx-card{padding:16px;border-radius:16px;min-height:100px}.pdx-card:focus,.pdx-card:hover{box-shadow:var(--mat-elevation-level4);background:var(--md-sys-color-surface-container-low);border-color:var(--md-sys-color-primary)}.pdx-card:focus-visible{outline:2px solid var(--md-sys-color-primary);outline-offset:2px}.pdx-card:active{transform:translateY(1px)}.pdx-card-icon{grid-row:span 2;display:flex;align-items:center;justify-content:center;color:var(--md-sys-color-primary)}.pdx-card-title{font-weight:600;line-height:1.2;overflow:hidden;text-overflow:ellipsis;white-space:nowrap}.pdx-card-desc{color:var(--md-sys-color-on-surface-variant);display:-webkit-box;-webkit-line-clamp:3;-webkit-box-orient:vertical;overflow:hidden;word-break:break-word}.pdx-card-badges{display:flex;flex-wrap:wrap;gap:6px;margin-top:8px}.pdx-card-badge{display:inline-flex;align-items:center;gap:4px;min-height:22px;padding:2px 8px;border-radius:999px;border:1px solid var(--md-sys-color-outline-variant);color:var(--md-sys-color-on-surface-variant);background:var(--md-sys-color-surface-container-highest);font-size:11px;line-height:1.2;font-weight:600;letter-spacing:.01em}.pdx-card-badge mat-icon{width:14px;height:14px;font-size:14px}.pdx-card-badge.ready{color:var(--md-sys-color-primary);border-color:color-mix(in srgb,var(--md-sys-color-primary) 45%,transparent);background:color-mix(in srgb,var(--md-sys-color-primary-container) 72%,transparent)}.pdx-card-badge.info{color:var(--md-sys-color-tertiary);border-color:color-mix(in srgb,var(--md-sys-color-tertiary) 38%,transparent);background:color-mix(in srgb,var(--md-sys-color-tertiary-container) 68%,transparent)}.pdx-card-badge.warning{color:var(--md-sys-color-error);border-color:color-mix(in srgb,var(--md-sys-color-error) 35%,transparent);background:color-mix(in srgb,var(--md-sys-color-error-container) 62%,transparent)}.pdx-empty{padding:24px;display:grid;place-items:center;color:var(--md-sys-color-on-surface-variant);gap:8px}@media(max-width:600px){.pdx-palette-content{min-width:320px}.pdx-grid{grid-template-columns:repeat(auto-fill,minmax(200px,1fr))}}\n"], dependencies: [{ kind: "ngmodule", type: FormsModule }, { kind: "directive", type: i1$1.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$1.NgControlStatus, selector: "[formControlName],[ngModel],[formControl]" }, { kind: "directive", type: i1$1.NgModel, selector: "[ngModel]:not([formControlName]):not([formControl])", inputs: ["name", "disabled", "ngModel", "ngModelOptions"], outputs: ["ngModelChange"], exportAs: ["ngModel"] }, { kind: "ngmodule", type: MatDialogModule }, { kind: "directive", type: i1.MatDialogClose, selector: "[mat-dialog-close], [matDialogClose]", inputs: ["aria-label", "type", "mat-dialog-close", "matDialogClose"], exportAs: ["matDialogClose"] }, { kind: "directive", type: i1.MatDialogTitle, selector: "[mat-dialog-title], [matDialogTitle]", inputs: ["id"], exportAs: ["matDialogTitle"] }, { kind: "directive", type: i1.MatDialogActions, selector: "[mat-dialog-actions], mat-dialog-actions, [matDialogActions]", inputs: ["align"] }, { kind: "directive", type: i1.MatDialogContent, selector: "[mat-dialog-content], mat-dialog-content, [matDialogContent]" }, { kind: "ngmodule", type: MatFormFieldModule }, { kind: "component", type: i3$1.MatFormField, selector: "mat-form-field", inputs: ["hideRequiredMarker", "color", "floatLabel", "appearance", "subscriptSizing", "hintLabel"], exportAs: ["matFormField"] }, { kind: "directive", type: i3$1.MatLabel, selector: "mat-label" }, { kind: "directive", type: i3$1.MatPrefix, selector: "[matPrefix], [matIconPrefix], [matTextPrefix]", inputs: ["matTextPrefix"] }, { kind: "ngmodule", type: MatInputModule }, { kind: "directive", type: i5.MatInput, selector: "input[matInput], textarea[matInput], select[matNativeControl], input[matNativeControl], textarea[matNativeControl]", inputs: ["disabled", "id", "placeholder", "name", "required", "type", "errorStateMatcher", "aria-describedby", "value", "readonly", "disabledInteractive"], exportAs: ["matInput"] }, { kind: "ngmodule", type: MatIconModule }, { kind: "component", type: i2$1.MatIcon, selector: "mat-icon", inputs: ["color", "inline", "svgIcon", "fontSet", "fontIcon"], exportAs: ["matIcon"] }, { kind: "ngmodule", type: MatButtonModule }, { kind: "component", type: i2.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: "directive", type: PraxisIconDirective, selector: "mat-icon[praxisIcon]", inputs: ["praxisIcon"] }], changeDetection: i0.ChangeDetectionStrategy.OnPush });
495
520
  }
496
- i0.ɵɵngDeclareClassMetadata({ minVersion: "12.0.0", version: "20.3.17", ngImport: i0, type: ComponentPaletteDialogComponent, decorators: [{
521
+ i0.ɵɵngDeclareClassMetadata({ minVersion: "12.0.0", version: "21.2.14", ngImport: i0, type: ComponentPaletteDialogComponent, decorators: [{
497
522
  type: Component,
498
- args: [{ selector: 'praxis-component-palette-dialog', standalone: true, imports: [CommonModule, FormsModule, MatDialogModule, MatFormFieldModule, MatInputModule, MatIconModule, MatButtonModule, PraxisIconDirective], template: `
523
+ args: [{ selector: 'praxis-component-palette-dialog', standalone: true, imports: [FormsModule, MatDialogModule, MatFormFieldModule, MatInputModule, MatIconModule, MatButtonModule, PraxisIconDirective], template: `
499
524
  <h2 mat-dialog-title>
500
525
  <div class="dlg-title">
501
526
  <mat-icon class="dlg-icon" [praxisIcon]="'widgets'"></mat-icon>
@@ -516,48 +541,53 @@ i0.ɵɵngDeclareClassMetadata({ minVersion: "12.0.0", version: "20.3.17", ngImpo
516
541
  (ngModelChange)="query.set($event)"
517
542
  placeholder="Nome, capability ou readiness"
518
543
  data-testid="component-palette-search"
519
- />
544
+ />
520
545
  </mat-form-field>
521
- <div [class]="'pdx-grid ' + density()" *ngIf="filtered().length; else emptyState">
522
- <button
523
- *ngFor="let entry of filtered(); trackBy: trackById"
524
- class="pdx-card mat-elevation-z2"
525
- type="button"
526
- [attr.aria-label]="'Adicionar ' + entry.title"
527
- (click)="select(entry)"
528
- >
529
- <div class="pdx-card-icon">
530
- <mat-icon [praxisIcon]="entry.icon"></mat-icon>
531
- </div>
532
- <div class="pdx-card-body">
533
- <div class="pdx-card-title">{{ entry.title }}</div>
534
- <div class="pdx-card-desc">{{ entry.description }}</div>
535
- <div class="pdx-card-badges" *ngIf="entry.badges.length">
536
- <span
537
- *ngFor="let badge of entry.badges"
538
- class="pdx-card-badge"
539
- [class]="'pdx-card-badge ' + badge.tone"
540
- [title]="badge.description"
546
+ @if (filtered().length) {
547
+ <div [class]="'pdx-grid ' + density()">
548
+ @for (entry of filtered(); track trackById($index, entry)) {
549
+ <button
550
+ class="pdx-card mat-elevation-z2"
551
+ type="button"
552
+ [attr.aria-label]="'Adicionar ' + entry.title"
553
+ (click)="select(entry)"
541
554
  >
542
- <mat-icon [praxisIcon]="badge.icon" aria-hidden="true"></mat-icon>
543
- {{ badge.label }}
544
- </span>
545
- </div>
546
- </div>
547
- </button>
548
- </div>
549
-
550
- <ng-template #emptyState>
555
+ <div class="pdx-card-icon">
556
+ <mat-icon [praxisIcon]="entry.icon"></mat-icon>
557
+ </div>
558
+ <div class="pdx-card-body">
559
+ <div class="pdx-card-title">{{ entry.title }}</div>
560
+ <div class="pdx-card-desc">{{ entry.description }}</div>
561
+ @if (entry.badges.length) {
562
+ <div class="pdx-card-badges">
563
+ @for (badge of entry.badges; track badge) {
564
+ <span
565
+ class="pdx-card-badge"
566
+ [class]="'pdx-card-badge ' + badge.tone"
567
+ [title]="badge.description"
568
+ >
569
+ <mat-icon [praxisIcon]="badge.icon" aria-hidden="true"></mat-icon>
570
+ {{ badge.label }}
571
+ </span>
572
+ }
573
+ </div>
574
+ }
575
+ </div>
576
+ </button>
577
+ }
578
+ </div>
579
+ } @else {
551
580
  <div class="pdx-empty">
552
581
  <mat-icon [praxisIcon]="'sentiment_dissatisfied'"></mat-icon>
553
582
  <div>Nenhum componente disponível</div>
554
583
  </div>
555
- </ng-template>
584
+ }
585
+
556
586
  </div>
557
587
  <div mat-dialog-actions align="end">
558
588
  <button mat-stroked-button color="primary" mat-dialog-close>Cancelar</button>
559
589
  </div>
560
- `, changeDetection: ChangeDetectionStrategy.OnPush, styles: [":host{display:block}h2[mat-dialog-title]{margin:0;padding:12px 24px 10px;border-bottom:1px solid var(--md-sys-color-outline-variant)}.dlg-title{display:flex;align-items:center;gap:10px}.dlg-icon{color:var(--md-sys-color-primary)}.dlg-head{font-size:18px;font-weight:600;line-height:1.2}.dlg-sub{font-size:12px;opacity:.85;color:var(--md-sys-color-on-surface-variant)}.pdx-palette-content{min-width:480px;max-width:920px;padding-top:8px}.pdx-palette-search{width:100%;margin-bottom:12px}.pdx-grid{display:grid;grid-template-columns:repeat(auto-fill,minmax(260px,1fr));gap:14px}.pdx-grid.dense{grid-template-columns:repeat(auto-fill,minmax(220px,1fr));gap:12px}.pdx-grid.roomy{grid-template-columns:repeat(auto-fill,minmax(300px,1fr));gap:16px}.pdx-card{appearance:none;position:relative;display:grid;grid-template-columns:44px 1fr;grid-template-rows:auto auto;gap:10px;padding:14px;border:1px solid transparent;border-radius:14px;cursor:pointer;outline:none;color:inherit;font:inherit;min-height:92px;text-align:left;background:var(--md-sys-color-surface);border-color:var(--md-sys-color-outline-variant);transition:box-shadow .2s ease,background .25s ease,transform .06s ease}.pdx-grid.dense .pdx-card{padding:10px;border-radius:12px;min-height:84px}.pdx-grid.roomy .pdx-card{padding:16px;border-radius:16px;min-height:100px}.pdx-card:focus,.pdx-card:hover{box-shadow:var(--mat-elevation-level4);background:var(--md-sys-color-surface-container-low);border-color:var(--md-sys-color-primary)}.pdx-card:focus-visible{outline:2px solid var(--md-sys-color-primary);outline-offset:2px}.pdx-card:active{transform:translateY(1px)}.pdx-card-icon{grid-row:span 2;display:flex;align-items:center;justify-content:center;color:var(--md-sys-color-primary)}.pdx-card-title{font-weight:600;line-height:1.2;overflow:hidden;text-overflow:ellipsis;white-space:nowrap}.pdx-card-desc{color:var(--md-sys-color-on-surface-variant);display:-webkit-box;-webkit-line-clamp:3;-webkit-box-orient:vertical;overflow:hidden;word-break:break-word}.pdx-card-badges{display:flex;flex-wrap:wrap;gap:6px;margin-top:8px}.pdx-card-badge{display:inline-flex;align-items:center;gap:4px;min-height:22px;padding:2px 8px;border-radius:999px;border:1px solid var(--md-sys-color-outline-variant);color:var(--md-sys-color-on-surface-variant);background:var(--md-sys-color-surface-container-highest);font-size:11px;line-height:1.2;font-weight:600;letter-spacing:.01em}.pdx-card-badge mat-icon{width:14px;height:14px;font-size:14px}.pdx-card-badge.ready{color:var(--md-sys-color-primary);border-color:color-mix(in srgb,var(--md-sys-color-primary) 45%,transparent);background:color-mix(in srgb,var(--md-sys-color-primary-container) 72%,transparent)}.pdx-card-badge.info{color:var(--md-sys-color-tertiary);border-color:color-mix(in srgb,var(--md-sys-color-tertiary) 38%,transparent);background:color-mix(in srgb,var(--md-sys-color-tertiary-container) 68%,transparent)}.pdx-card-badge.warning{color:var(--md-sys-color-error);border-color:color-mix(in srgb,var(--md-sys-color-error) 35%,transparent);background:color-mix(in srgb,var(--md-sys-color-error-container) 62%,transparent)}.pdx-empty{padding:24px;display:grid;place-items:center;color:var(--md-sys-color-on-surface-variant);gap:8px}@media(max-width:600px){.pdx-palette-content{min-width:320px}.pdx-grid{grid-template-columns:repeat(auto-fill,minmax(200px,1fr))}}\n"] }]
590
+ `, changeDetection: ChangeDetectionStrategy.OnPush, styles: [":host{display:block}h2[mat-dialog-title]{margin:0;padding:12px 24px 10px;border-bottom:1px solid var(--md-sys-color-outline-variant)}.dlg-title{display:flex;align-items:center;gap:10px}.dlg-icon{color:var(--md-sys-color-primary)}.dlg-head{font-size:18px;font-weight:600;line-height:1.2}.dlg-sub{font-size:12px;opacity:.85;color:var(--md-sys-color-on-surface-variant)}.pdx-palette-content{min-width:480px;max-width:920px;padding-top:8px}.pdx-palette-search{width:100%;margin-bottom:12px}.pdx-grid{display:grid;grid-template-columns:repeat(auto-fill,minmax(260px,1fr));gap:14px}.pdx-grid.dense{grid-template-columns:repeat(auto-fill,minmax(220px,1fr));gap:12px}.pdx-grid.roomy{grid-template-columns:repeat(auto-fill,minmax(300px,1fr));gap:16px}.pdx-card{appearance:none;position:relative;display:grid;grid-template-columns:44px 1fr;grid-template-rows:auto auto;gap:10px;padding:14px;border:1px solid transparent;border-radius:14px;cursor:pointer;outline:none;color:inherit;font:inherit;min-height:92px;text-align:left;background:var(--md-sys-color-surface);border-color:var(--md-sys-color-outline-variant);transition:box-shadow .2s ease,background .25s ease,transform .06s ease}.pdx-grid.dense .pdx-card{padding:10px;border-radius:12px;min-height:84px}.pdx-grid.roomy .pdx-card{padding:16px;border-radius:16px;min-height:100px}.pdx-card:focus,.pdx-card:hover{box-shadow:var(--mat-elevation-level4);background:var(--md-sys-color-surface-container-low);border-color:var(--md-sys-color-primary)}.pdx-card:focus-visible{outline:2px solid var(--md-sys-color-primary);outline-offset:2px}.pdx-card:active{transform:translateY(1px)}.pdx-card-icon{grid-row:span 2;display:flex;align-items:center;justify-content:center;color:var(--md-sys-color-primary)}.pdx-card-title{font-weight:600;line-height:1.2;overflow:hidden;text-overflow:ellipsis;white-space:nowrap}.pdx-card-desc{color:var(--md-sys-color-on-surface-variant);display:-webkit-box;-webkit-line-clamp:3;-webkit-box-orient:vertical;overflow:hidden;word-break:break-word}.pdx-card-badges{display:flex;flex-wrap:wrap;gap:6px;margin-top:8px}.pdx-card-badge{display:inline-flex;align-items:center;gap:4px;min-height:22px;padding:2px 8px;border-radius:999px;border:1px solid var(--md-sys-color-outline-variant);color:var(--md-sys-color-on-surface-variant);background:var(--md-sys-color-surface-container-highest);font-size:11px;line-height:1.2;font-weight:600;letter-spacing:.01em}.pdx-card-badge mat-icon{width:14px;height:14px;font-size:14px}.pdx-card-badge.ready{color:var(--md-sys-color-primary);border-color:color-mix(in srgb,var(--md-sys-color-primary) 45%,transparent);background:color-mix(in srgb,var(--md-sys-color-primary-container) 72%,transparent)}.pdx-card-badge.info{color:var(--md-sys-color-tertiary);border-color:color-mix(in srgb,var(--md-sys-color-tertiary) 38%,transparent);background:color-mix(in srgb,var(--md-sys-color-tertiary-container) 68%,transparent)}.pdx-card-badge.warning{color:var(--md-sys-color-error);border-color:color-mix(in srgb,var(--md-sys-color-error) 35%,transparent);background:color-mix(in srgb,var(--md-sys-color-error-container) 62%,transparent)}.pdx-empty{padding:24px;display:grid;place-items:center;color:var(--md-sys-color-on-surface-variant);gap:8px}@media(max-width:600px){.pdx-palette-content{min-width:320px}.pdx-grid{grid-template-columns:repeat(auto-fill,minmax(200px,1fr))}}\n"] }]
561
591
  }], ctorParameters: () => [{ type: i1.MatDialogRef }, { type: i2$2.ComponentMetadataRegistry }, { type: undefined, decorators: [{
562
592
  type: Inject,
563
593
  args: [MAT_DIALOG_DATA]
@@ -1323,8 +1353,8 @@ class WidgetShellEditorComponent {
1323
1353
  this.setInputValue.setValue(firstValue.value, { emitEvent: false });
1324
1354
  }
1325
1355
  }
1326
- static ɵfac = i0.ɵɵngDeclareFactory({ minVersion: "12.0.0", version: "20.3.17", ngImport: i0, type: WidgetShellEditorComponent, deps: [{ token: SETTINGS_PANEL_DATA, optional: true }, { token: i2$2.ComponentMetadataRegistry, optional: true }], target: i0.ɵɵFactoryTarget.Component });
1327
- static ɵcmp = i0.ɵɵngDeclareComponent({ minVersion: "14.0.0", version: "20.3.17", type: WidgetShellEditorComponent, isStandalone: true, selector: "praxis-widget-shell-editor", ngImport: i0, template: `
1356
+ static ɵfac = i0.ɵɵngDeclareFactory({ minVersion: "12.0.0", version: "21.2.14", ngImport: i0, type: WidgetShellEditorComponent, deps: [{ token: SETTINGS_PANEL_DATA, optional: true }, { token: i2$2.ComponentMetadataRegistry, optional: true }], target: i0.ɵɵFactoryTarget.Component });
1357
+ static ɵcmp = i0.ɵɵngDeclareComponent({ minVersion: "17.0.0", version: "21.2.14", type: WidgetShellEditorComponent, isStandalone: true, selector: "praxis-widget-shell-editor", ngImport: i0, template: `
1328
1358
  <div class="shell-editor">
1329
1359
  <div class="shell-head">
1330
1360
  <div>
@@ -1333,7 +1363,7 @@ class WidgetShellEditorComponent {
1333
1363
  </div>
1334
1364
  <button mat-stroked-button type="button" (click)="reset()">Recarregar</button>
1335
1365
  </div>
1336
-
1366
+
1337
1367
  <div class="shell-section">Geral</div>
1338
1368
  <div class="shell-grid">
1339
1369
  <mat-form-field appearance="outline">
@@ -1347,16 +1377,24 @@ class WidgetShellEditorComponent {
1347
1377
  <mat-label>Preset</mat-label>
1348
1378
  <mat-select [formControl]="form.controls.preset">
1349
1379
  <mat-option value="">Nenhum</mat-option>
1350
- <mat-option *ngIf="pagePreset" [value]="pagePreset">Usar preset da página ({{ pagePreset }})</mat-option>
1351
- <mat-option *ngFor="let p of presetOptions" [value]="p.id">{{ p.label }}</mat-option>
1380
+ @if (pagePreset) {
1381
+ <mat-option [value]="pagePreset">Usar preset da página ({{ pagePreset }})</mat-option>
1382
+ }
1383
+ @for (p of presetOptions; track p) {
1384
+ <mat-option [value]="p.id">{{ p.label }}</mat-option>
1385
+ }
1352
1386
  </mat-select>
1353
1387
  </mat-form-field>
1354
- <div class="shell-hint" *ngIf="!form.controls.preset.value && pagePreset">
1355
- Preset da página: {{ pagePreset }}
1356
- </div>
1357
- <mat-checkbox [formControl]="form.controls.applyToAll" *ngIf="form.controls.preset.value">
1358
- Aplicar preset como padrão da página
1359
- </mat-checkbox>
1388
+ @if (!form.controls.preset.value && pagePreset) {
1389
+ <div class="shell-hint">
1390
+ Preset da página: {{ pagePreset }}
1391
+ </div>
1392
+ }
1393
+ @if (form.controls.preset.value) {
1394
+ <mat-checkbox [formControl]="form.controls.applyToAll">
1395
+ Aplicar preset como padrão da página
1396
+ </mat-checkbox>
1397
+ }
1360
1398
  <mat-form-field appearance="outline">
1361
1399
  <mat-label>Ícone</mat-label>
1362
1400
  <input matInput [formControl]="form.controls.icon" placeholder="ex: badge" />
@@ -1378,14 +1416,14 @@ class WidgetShellEditorComponent {
1378
1416
  </mat-select>
1379
1417
  </mat-form-field>
1380
1418
  </div>
1381
-
1419
+
1382
1420
  <div class="shell-section">Controles de janela</div>
1383
1421
  <div class="shell-flags">
1384
1422
  <mat-checkbox [formControl]="form.controls.collapsible">Permitir recolher</mat-checkbox>
1385
1423
  </div>
1386
-
1424
+
1387
1425
  <mat-divider></mat-divider>
1388
-
1426
+
1389
1427
  <div class="shell-section">Aparência</div>
1390
1428
  <div class="shell-grid">
1391
1429
  <mat-form-field appearance="outline">
@@ -1449,245 +1487,294 @@ class WidgetShellEditorComponent {
1449
1487
  <input matInput [formControl]="form.controls.subtitleSize" placeholder="ex: 12px" />
1450
1488
  </mat-form-field>
1451
1489
  </div>
1452
-
1490
+
1453
1491
  <div class="shell-preview" [ngStyle]="previewVars()">
1454
1492
  <div class="shell-preview-card" [class.no-shell]="form.controls.kind.value === 'none'" [class.expanded]="previewExpanded">
1455
- <div class="shell-preview-header" *ngIf="previewShowHeader()">
1456
- <div class="shell-preview-title">
1457
- <mat-icon *ngIf="form.controls.icon.value" [praxisIcon]="form.controls.icon.value"></mat-icon>
1458
- <div class="shell-preview-text">
1459
- <div class="shell-preview-title-text">{{ previewTitle() }}</div>
1460
- <div class="shell-preview-subtitle">{{ previewSubtitle() }}</div>
1493
+ @if (previewShowHeader()) {
1494
+ <div class="shell-preview-header">
1495
+ <div class="shell-preview-title">
1496
+ @if (form.controls.icon.value) {
1497
+ <mat-icon [praxisIcon]="form.controls.icon.value"></mat-icon>
1498
+ }
1499
+ <div class="shell-preview-text">
1500
+ <div class="shell-preview-title-text">{{ previewTitle() }}</div>
1501
+ <div class="shell-preview-subtitle">{{ previewSubtitle() }}</div>
1502
+ </div>
1503
+ </div>
1504
+ <div class="shell-preview-actions">
1505
+ @for (action of previewHeaderActions(); track action) {
1506
+ <button
1507
+ type="button"
1508
+ [disabled]="action.disabled"
1509
+ [ngClass]="action.variant === 'outlined' ? 'pdx-preview-outlined' : 'pdx-preview-text'"
1510
+ mat-button
1511
+ >
1512
+ @if (action.icon) {
1513
+ <mat-icon [praxisIcon]="action.icon"></mat-icon>
1514
+ }
1515
+ <span class="pdx-preview-label">{{ action.label || action.id }}</span>
1516
+ </button>
1517
+ }
1518
+ @if (previewOverflowCount()) {
1519
+ <button
1520
+ mat-icon-button
1521
+ type="button"
1522
+ aria-label="Mais ações"
1523
+ >
1524
+ <mat-icon>more_horiz</mat-icon>
1525
+ </button>
1526
+ }
1527
+ @for (action of previewWindowActions(); track action) {
1528
+ <button
1529
+ mat-icon-button
1530
+ type="button"
1531
+ [disabled]="action.disabled"
1532
+ [attr.aria-label]="action.label || action.id"
1533
+ >
1534
+ @if (action.icon) {
1535
+ <mat-icon [praxisIcon]="action.icon"></mat-icon>
1536
+ }
1537
+ </button>
1538
+ }
1539
+ <button mat-icon-button type="button" (click)="togglePreviewCollapse()" aria-label="Recolher">
1540
+ <mat-icon>{{ previewCollapsed ? 'unfold_more' : 'unfold_less' }}</mat-icon>
1541
+ </button>
1542
+ <button mat-icon-button type="button" (click)="togglePreviewExpand()" aria-label="Expandir">
1543
+ <mat-icon>{{ previewExpanded ? 'close_fullscreen' : 'open_in_full' }}</mat-icon>
1544
+ </button>
1461
1545
  </div>
1462
1546
  </div>
1463
- <div class="shell-preview-actions">
1464
- <button
1465
- *ngFor="let action of previewHeaderActions()"
1466
- type="button"
1467
- [disabled]="action.disabled"
1468
- [ngClass]="action.variant === 'outlined' ? 'pdx-preview-outlined' : 'pdx-preview-text'"
1469
- mat-button
1470
- >
1471
- <mat-icon *ngIf="action.icon" [praxisIcon]="action.icon"></mat-icon>
1472
- <span class="pdx-preview-label">{{ action.label || action.id }}</span>
1473
- </button>
1474
- <button
1475
- *ngIf="previewOverflowCount()"
1476
- mat-icon-button
1477
- type="button"
1478
- aria-label="Mais ações"
1479
- >
1480
- <mat-icon>more_horiz</mat-icon>
1481
- </button>
1482
- <button
1483
- *ngFor="let action of previewWindowActions()"
1484
- mat-icon-button
1485
- type="button"
1486
- [disabled]="action.disabled"
1487
- [attr.aria-label]="action.label || action.id"
1488
- >
1489
- <mat-icon *ngIf="action.icon" [praxisIcon]="action.icon"></mat-icon>
1490
- </button>
1491
- <button mat-icon-button type="button" (click)="togglePreviewCollapse()" aria-label="Recolher">
1492
- <mat-icon>{{ previewCollapsed ? 'unfold_more' : 'unfold_less' }}</mat-icon>
1493
- </button>
1494
- <button mat-icon-button type="button" (click)="togglePreviewExpand()" aria-label="Expandir">
1495
- <mat-icon>{{ previewExpanded ? 'close_fullscreen' : 'open_in_full' }}</mat-icon>
1496
- </button>
1497
- </div>
1498
- </div>
1547
+ }
1499
1548
  <div class="shell-preview-body" [class.hidden]="previewCollapsed">Conteudo do widget</div>
1500
1549
  </div>
1501
1550
  </div>
1502
-
1551
+
1503
1552
  <mat-divider></mat-divider>
1504
-
1505
- <div class="shell-section" *ngIf="hasAvailableActions">Ações disponíveis</div>
1506
- <div class="shell-available" *ngIf="hasAvailableActions; else noAvailableActions">
1507
- <div class="shell-available-toolbar">
1508
- <mat-form-field appearance="outline">
1509
- <mat-label>Buscar ação</mat-label>
1510
- <input matInput [formControl]="actionQuery" placeholder="ex: export, editar, submit" />
1511
- </mat-form-field>
1512
- <div class="shell-available-filters">
1513
- <mat-checkbox [(ngModel)]="showScopeShell">Shell</mat-checkbox>
1514
- <mat-checkbox [(ngModel)]="showScopeAny">Any</mat-checkbox>
1515
- <mat-checkbox [(ngModel)]="showScopeToolbar">Toolbar</mat-checkbox>
1516
- <mat-checkbox [(ngModel)]="showScopeContext">Context</mat-checkbox>
1553
+
1554
+ @if (hasAvailableActions) {
1555
+ <div class="shell-section">Ações disponíveis</div>
1556
+ }
1557
+ @if (hasAvailableActions) {
1558
+ <div class="shell-available">
1559
+ <div class="shell-available-toolbar">
1560
+ <mat-form-field appearance="outline">
1561
+ <mat-label>Buscar ação</mat-label>
1562
+ <input matInput [formControl]="actionQuery" placeholder="ex: export, editar, submit" />
1563
+ </mat-form-field>
1564
+ <div class="shell-available-filters">
1565
+ <mat-checkbox [(ngModel)]="showScopeShell">Shell</mat-checkbox>
1566
+ <mat-checkbox [(ngModel)]="showScopeAny">Any</mat-checkbox>
1567
+ <mat-checkbox [(ngModel)]="showScopeToolbar">Toolbar</mat-checkbox>
1568
+ <mat-checkbox [(ngModel)]="showScopeContext">Context</mat-checkbox>
1569
+ </div>
1517
1570
  </div>
1518
- </div>
1519
- <div class="shell-available-list">
1520
- <div class="shell-available-item" *ngFor="let action of filteredAvailableActions()">
1521
- <div class="shell-available-main">
1522
- <div class="shell-available-title">
1523
- <mat-icon *ngIf="action.icon" [praxisIcon]="action.icon"></mat-icon>
1524
- <div class="shell-available-text">
1525
- <div class="shell-available-label">{{ action.label }}</div>
1526
- <div class="shell-available-meta">
1527
- <span class="shell-badge">{{ action.kind === 'command' ? 'Comando' : 'Ação' }}</span>
1528
- <span class="shell-badge">{{ scopeLabel(action.scope) }}</span>
1529
- <span class="shell-code">id: {{ action.id }}</span>
1530
- <span *ngIf="action.emit" class="shell-code">emit: {{ action.emit }}</span>
1531
- <span *ngIf="action.command" class="shell-code">command: {{ action.command }}</span>
1571
+ <div class="shell-available-list">
1572
+ @for (action of filteredAvailableActions(); track action) {
1573
+ <div class="shell-available-item">
1574
+ <div class="shell-available-main">
1575
+ <div class="shell-available-title">
1576
+ @if (action.icon) {
1577
+ <mat-icon [praxisIcon]="action.icon"></mat-icon>
1578
+ }
1579
+ <div class="shell-available-text">
1580
+ <div class="shell-available-label">{{ action.label }}</div>
1581
+ <div class="shell-available-meta">
1582
+ <span class="shell-badge">{{ action.kind === 'command' ? 'Comando' : 'Ação' }}</span>
1583
+ <span class="shell-badge">{{ scopeLabel(action.scope) }}</span>
1584
+ <span class="shell-code">id: {{ action.id }}</span>
1585
+ @if (action.emit) {
1586
+ <span class="shell-code">emit: {{ action.emit }}</span>
1587
+ }
1588
+ @if (action.command) {
1589
+ <span class="shell-code">command: {{ action.command }}</span>
1590
+ }
1591
+ </div>
1592
+ </div>
1532
1593
  </div>
1594
+ @if (action.description) {
1595
+ <div class="shell-available-desc">{{ action.description }}</div>
1596
+ }
1597
+ @if (action.payloadExample !== undefined) {
1598
+ <div class="shell-available-payload">
1599
+ <span class="shell-code">payload: {{ stringifyPayload(action.payloadExample) }}</span>
1600
+ </div>
1601
+ }
1602
+ @if (action.scope === 'context') {
1603
+ <div class="shell-available-warning">
1604
+ Essa ação depende de item/linha selecionado; payload fixo pode não funcionar.
1605
+ </div>
1606
+ }
1607
+ </div>
1608
+ <div class="shell-available-actions">
1609
+ <button
1610
+ mat-stroked-button
1611
+ type="button"
1612
+ [color]="isActionSelected(action) ? 'warn' : 'primary'"
1613
+ (click)="toggleAvailableAction(action)"
1614
+ >
1615
+ {{ isActionSelected(action) ? 'Remover' : 'Adicionar' }}
1616
+ </button>
1533
1617
  </div>
1534
1618
  </div>
1535
- <div class="shell-available-desc" *ngIf="action.description">{{ action.description }}</div>
1536
- <div class="shell-available-payload" *ngIf="action.payloadExample !== undefined">
1537
- <span class="shell-code">payload: {{ stringifyPayload(action.payloadExample) }}</span>
1538
- </div>
1539
- <div class="shell-available-warning" *ngIf="action.scope === 'context'">
1540
- Essa ação depende de item/linha selecionado; payload fixo pode não funcionar.
1541
- </div>
1542
- </div>
1543
- <div class="shell-available-actions">
1544
- <button
1545
- mat-stroked-button
1546
- type="button"
1547
- [color]="isActionSelected(action) ? 'warn' : 'primary'"
1548
- (click)="toggleAvailableAction(action)"
1549
- >
1550
- {{ isActionSelected(action) ? 'Remover' : 'Adicionar' }}
1551
- </button>
1552
- </div>
1619
+ }
1553
1620
  </div>
1554
1621
  </div>
1555
- </div>
1556
- <ng-template #noAvailableActions>
1622
+ } @else {
1557
1623
  <div class="shell-empty">Nenhuma ação registrada para este componente.</div>
1558
- </ng-template>
1559
-
1560
- <mat-divider *ngIf="hasAvailableActions"></mat-divider>
1561
-
1562
- <div class="shell-section" *ngIf="setInputPresets.length">Ações rápidas (inputs)</div>
1563
- <div class="shell-quick-inputs" *ngIf="setInputPresets.length">
1564
- <mat-form-field appearance="outline">
1565
- <mat-label>Input</mat-label>
1566
- <mat-select [formControl]="setInputTarget">
1567
- <mat-option *ngFor="let preset of setInputPresets" [value]="preset.input">
1568
- <mat-icon *ngIf="preset.icon" [praxisIcon]="preset.icon"></mat-icon>
1569
- {{ preset.label }}
1570
- </mat-option>
1571
- </mat-select>
1572
- </mat-form-field>
1573
- <div class="shell-input-path" *ngIf="setInputTarget.value">
1574
- Input: {{ displayInputPath(setInputTarget.value) }}
1575
- </div>
1576
- <mat-form-field appearance="outline">
1577
- <mat-label>Valor</mat-label>
1578
- <mat-select [formControl]="setInputValue">
1579
- <mat-option *ngFor="let option of currentSetInputValues()" [value]="option.value">
1580
- <mat-icon *ngIf="option.icon" [praxisIcon]="option.icon"></mat-icon>
1581
- {{ option.label }}
1582
- </mat-option>
1583
- </mat-select>
1584
- </mat-form-field>
1585
- <button mat-flat-button color="primary" type="button" (click)="addSetInputAction()">
1586
- Adicionar ação
1587
- </button>
1588
- </div>
1589
-
1590
- <div class="shell-section shell-actions-head">
1591
- <div>Ações do cabeçalho</div>
1592
- <button mat-flat-button color="primary" type="button" (click)="addAction()">Adicionar ação</button>
1593
- </div>
1594
-
1595
- <div class="shell-actions" *ngIf="actions.controls.length; else emptyActions">
1596
- <div class="shell-action" *ngFor="let action of actions.controls; let i = index" [formGroup]="action">
1597
- <div class="shell-action-row">
1598
- <mat-form-field appearance="outline">
1599
- <mat-label>ID</mat-label>
1600
- <input matInput formControlName="id" />
1601
- </mat-form-field>
1602
- <mat-form-field appearance="outline">
1603
- <mat-label>Label</mat-label>
1604
- <input matInput formControlName="label" />
1605
- </mat-form-field>
1606
- <mat-form-field appearance="outline">
1607
- <mat-label>Ícone</mat-label>
1608
- <input matInput formControlName="icon" />
1609
- </mat-form-field>
1610
- </div>
1611
- <div class="shell-action-row">
1612
- <mat-form-field appearance="outline">
1613
- <mat-label>Variante</mat-label>
1614
- <mat-select formControlName="variant">
1615
- <mat-option value="text">Texto</mat-option>
1616
- <mat-option value="outlined">Outlined</mat-option>
1617
- <mat-option value="icon">Ícone</mat-option>
1624
+ }
1625
+
1626
+ @if (hasAvailableActions) {
1627
+ <mat-divider></mat-divider>
1628
+ }
1629
+
1630
+ @if (setInputPresets.length) {
1631
+ <div class="shell-section">Ações rápidas (inputs)</div>
1632
+ }
1633
+ @if (setInputPresets.length) {
1634
+ <div class="shell-quick-inputs">
1635
+ <mat-form-field appearance="outline">
1636
+ <mat-label>Input</mat-label>
1637
+ <mat-select [formControl]="setInputTarget">
1638
+ @for (preset of setInputPresets; track preset) {
1639
+ <mat-option [value]="preset.input">
1640
+ @if (preset.icon) {
1641
+ <mat-icon [praxisIcon]="preset.icon"></mat-icon>
1642
+ }
1643
+ {{ preset.label }}
1644
+ </mat-option>
1645
+ }
1618
1646
  </mat-select>
1619
1647
  </mat-form-field>
1648
+ @if (setInputTarget.value) {
1649
+ <div class="shell-input-path">
1650
+ Input: {{ displayInputPath(setInputTarget.value) }}
1651
+ </div>
1652
+ }
1620
1653
  <mat-form-field appearance="outline">
1621
- <mat-label>Posição</mat-label>
1622
- <mat-select formControlName="placement">
1623
- <mat-option value="header">Cabeçalho</mat-option>
1624
- <mat-option value="window">Janela</mat-option>
1654
+ <mat-label>Valor</mat-label>
1655
+ <mat-select [formControl]="setInputValue">
1656
+ @for (option of currentSetInputValues(); track option) {
1657
+ <mat-option [value]="option.value">
1658
+ @if (option.icon) {
1659
+ <mat-icon [praxisIcon]="option.icon"></mat-icon>
1660
+ }
1661
+ {{ option.label }}
1662
+ </mat-option>
1663
+ }
1625
1664
  </mat-select>
1626
1665
  </mat-form-field>
1627
- <mat-form-field appearance="outline">
1628
- <mat-label>Emit</mat-label>
1629
- <input matInput formControlName="emit" placeholder="ex: editar" />
1630
- </mat-form-field>
1631
- <mat-form-field appearance="outline">
1632
- <mat-label>Tooltip</mat-label>
1633
- <input matInput formControlName="tooltip" />
1634
- </mat-form-field>
1635
- </div>
1636
- <div class="shell-action-row">
1637
- <mat-form-field appearance="outline">
1638
- <mat-label>Command</mat-label>
1639
- <input matInput formControlName="command" placeholder="ex: add-item" />
1640
- </mat-form-field>
1641
- <mat-form-field appearance="outline">
1642
- <mat-label>Payload (JSON)</mat-label>
1643
- <textarea matInput rows="2" formControlName="payload" placeholder='ex: {"foo":"bar"}'></textarea>
1644
- </mat-form-field>
1645
- <mat-checkbox formControlName="visible">Visível</mat-checkbox>
1646
- <mat-checkbox formControlName="disabled">Desabilitado</mat-checkbox>
1647
- </div>
1648
- <div class="shell-action-hint" *ngIf="showActionInputPath(action.value)">
1649
- Input: {{ displayInputPath(extractActionInput(action.value)) }}
1650
- </div>
1651
- <div class="shell-action-actions">
1652
- <button mat-stroked-button color="warn" type="button" (click)="removeAction(i)">Remover</button>
1653
- </div>
1654
- </div>
1655
- </div>
1656
-
1657
- <ng-template #emptyActions>
1658
- <div class="shell-empty">Nenhuma ação configurada.</div>
1659
- </ng-template>
1660
- </div>
1661
- `, isInline: true, styles: [".shell-editor{display:grid;gap:12px;padding:16px;background:var(--md-sys-color-surface-container-lowest, var(--md-sys-color-surface));border:1px solid var(--md-sys-color-outline-variant);border-radius:12px}.shell-head{display:flex;align-items:center;gap:12px}.shell-title{font-weight:600}.shell-subtitle{font-size:12px;color:var(--md-sys-color-on-surface-variant)}.shell-section{font-weight:600;margin-top:8px}.shell-grid{display:grid;gap:12px;grid-template-columns:repeat(auto-fit,minmax(180px,1fr))}.shell-flags{display:flex;gap:16px;align-items:center}.shell-actions-head{display:flex;align-items:center;justify-content:space-between;gap:12px}.shell-available{display:grid;gap:12px}.shell-available-toolbar{display:grid;gap:12px;grid-template-columns:minmax(200px,1fr)}.shell-available-filters{display:flex;gap:12px;align-items:center;flex-wrap:wrap}.shell-available-list{display:grid;gap:10px}.shell-available-item{display:grid;gap:8px;grid-template-columns:1fr auto;border:1px solid var(--md-sys-color-outline-variant);border-radius:12px;padding:12px;background:var(--md-sys-color-surface-container-low)}.shell-available-title{display:flex;align-items:center;gap:10px}.shell-available-text{display:grid;gap:4px}.shell-available-label{font-weight:600}.shell-available-meta{display:flex;gap:8px;flex-wrap:wrap;font-size:11px;color:var(--md-sys-color-on-surface-variant)}.shell-available-desc{font-size:12px;color:var(--md-sys-color-on-surface-variant)}.shell-available-payload{font-size:11px;color:var(--md-sys-color-on-surface-variant)}.shell-available-warning{font-size:11px;color:var(--md-sys-color-error)}.shell-available-actions{display:flex;align-items:flex-start;justify-content:flex-end}.shell-badge{padding:2px 6px;border-radius:999px;border:1px solid var(--md-sys-color-outline-variant);font-size:10px}.shell-code{font-family:ui-monospace,SFMono-Regular,Menlo,Monaco,Consolas,Liberation Mono,Courier New,monospace}.shell-actions{display:grid;gap:12px}.shell-action{border:1px solid var(--md-sys-color-outline-variant);border-radius:12px;padding:12px;display:grid;gap:8px}.shell-action-row{display:grid;gap:12px;grid-template-columns:repeat(auto-fit,minmax(160px,1fr))}.shell-action-actions{display:flex;justify-content:flex-end}.shell-action-hint,.shell-empty{font-size:12px;color:var(--md-sys-color-on-surface-variant)}.shell-hint{align-self:center;font-size:12px;color:var(--md-sys-color-on-surface-variant)}.shell-quick-inputs{display:grid;gap:12px;grid-template-columns:repeat(auto-fit,minmax(180px,1fr));align-items:end}.shell-input-path{font-size:12px;color:var(--md-sys-color-on-surface-variant);align-self:center}.shell-editor .mat-mdc-form-field{width:100%}.shell-preview{border:1px dashed var(--md-sys-color-outline-variant);border-radius:12px;padding:12px}.shell-preview-card{background:var(--pdx-shell-card-bg, var(--md-sys-color-surface));border:1px solid var(--pdx-shell-card-border, var(--md-sys-color-outline-variant));border-radius:var(--pdx-shell-card-radius, 14px);box-shadow:var(--pdx-shell-card-shadow, var(--mat-elevation-level2));overflow:hidden}.shell-preview-card.no-shell{background:transparent;border:none;box-shadow:none}.shell-preview-card.expanded{box-shadow:var(--pdx-shell-card-shadow, 0 16px 34px rgba(0,0,0,.32));transform:scale(1.01)}.shell-preview-header{display:flex;align-items:center;gap:12px;padding:10px 12px 8px;border-bottom:1px solid var(--pdx-shell-header-border, var(--md-sys-color-outline-variant));background:var(--pdx-shell-header-bg, var(--md-sys-color-surface-container))}.shell-preview-title{display:flex;align-items:center;gap:10px;min-width:0;flex:1;color:var(--pdx-shell-title-color, inherit)}.shell-preview-title mat-icon{color:var(--pdx-shell-icon-color, currentColor)}.shell-preview-text{min-width:0}.shell-preview-title-text{font-weight:var(--pdx-shell-title-weight, 600);font-size:var(--pdx-shell-title-size, 14px);line-height:1.2;white-space:nowrap;overflow:hidden;text-overflow:ellipsis}.shell-preview-subtitle{font-size:var(--pdx-shell-subtitle-size, 12px);opacity:.75;color:var(--pdx-shell-subtitle-color, currentColor);white-space:nowrap;overflow:hidden;text-overflow:ellipsis}.shell-preview-actions{display:flex;align-items:center;gap:6px}.pdx-preview-text{padding:0 8px}.pdx-preview-outlined{border:1px solid var(--md-sys-color-outline-variant);border-radius:999px;padding:0 10px}.pdx-preview-label{font-size:12px;font-weight:500}.shell-preview-body{padding:var(--pdx-shell-body-padding, 10px 12px 12px 12px);background:var(--pdx-shell-body-bg, transparent);color:var(--pdx-shell-body-color, inherit);font-size:12px}.shell-preview-body.hidden{display:none}\n"], dependencies: [{ kind: "ngmodule", type: CommonModule }, { kind: "directive", type: i2$1.NgClass, selector: "[ngClass]", inputs: ["class", "ngClass"] }, { kind: "directive", type: i2$1.NgForOf, selector: "[ngFor][ngForOf]", inputs: ["ngForOf", "ngForTrackBy", "ngForTemplate"] }, { kind: "directive", type: i2$1.NgIf, selector: "[ngIf]", inputs: ["ngIf", "ngIfThen", "ngIfElse"] }, { kind: "directive", type: i2$1.NgStyle, selector: "[ngStyle]", inputs: ["ngStyle"] }, { kind: "ngmodule", type: FormsModule }, { kind: "directive", type: i1$1.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$1.NgControlStatus, selector: "[formControlName],[ngModel],[formControl]" }, { kind: "directive", type: i1$1.NgControlStatusGroup, selector: "[formGroupName],[formArrayName],[ngModelGroup],[formGroup],form:not([ngNoForm]),[ngForm]" }, { kind: "directive", type: i1$1.NgModel, selector: "[ngModel]:not([formControlName]):not([formControl])", inputs: ["name", "disabled", "ngModel", "ngModelOptions"], outputs: ["ngModelChange"], exportAs: ["ngModel"] }, { kind: "ngmodule", type: ReactiveFormsModule }, { kind: "directive", type: i1$1.FormControlDirective, selector: "[formControl]", inputs: ["formControl", "disabled", "ngModel"], outputs: ["ngModelChange"], exportAs: ["ngForm"] }, { kind: "directive", type: i1$1.FormGroupDirective, selector: "[formGroup]", inputs: ["formGroup"], outputs: ["ngSubmit"], exportAs: ["ngForm"] }, { kind: "directive", type: i1$1.FormControlName, selector: "[formControlName]", inputs: ["formControlName", "disabled", "ngModel"], outputs: ["ngModelChange"] }, { kind: "ngmodule", type: MatButtonModule }, { kind: "component", type: i2.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: i2.MatIconButton, selector: "button[mat-icon-button], a[mat-icon-button], button[matIconButton], a[matIconButton]", exportAs: ["matButton", "matAnchor"] }, { kind: "ngmodule", type: MatCheckboxModule }, { kind: "component", type: i5.MatCheckbox, selector: "mat-checkbox", inputs: ["aria-label", "aria-labelledby", "aria-describedby", "aria-expanded", "aria-controls", "aria-owns", "id", "required", "labelPosition", "name", "value", "disableRipple", "tabIndex", "color", "disabledInteractive", "checked", "disabled", "indeterminate"], outputs: ["change", "indeterminateChange"], exportAs: ["matCheckbox"] }, { kind: "ngmodule", type: MatDividerModule }, { kind: "component", type: i6$1.MatDivider, selector: "mat-divider", inputs: ["vertical", "inset"] }, { kind: "ngmodule", type: MatFormFieldModule }, { kind: "component", type: i3$2.MatFormField, selector: "mat-form-field", inputs: ["hideRequiredMarker", "color", "floatLabel", "appearance", "subscriptSizing", "hintLabel"], exportAs: ["matFormField"] }, { kind: "directive", type: i3$2.MatLabel, selector: "mat-label" }, { kind: "ngmodule", type: MatIconModule }, { kind: "component", type: i3.MatIcon, selector: "mat-icon", inputs: ["color", "inline", "svgIcon", "fontSet", "fontIcon"], exportAs: ["matIcon"] }, { kind: "ngmodule", type: MatInputModule }, { kind: "directive", type: i6.MatInput, selector: "input[matInput], textarea[matInput], select[matNativeControl], input[matNativeControl], textarea[matNativeControl]", inputs: ["disabled", "id", "placeholder", "name", "required", "type", "errorStateMatcher", "aria-describedby", "value", "readonly", "disabledInteractive"], exportAs: ["matInput"] }, { kind: "ngmodule", type: MatSelectModule }, { kind: "component", type: i6$2.MatSelect, selector: "mat-select", inputs: ["aria-describedby", "panelClass", "disabled", "disableRipple", "tabIndex", "hideSingleSelectionIndicator", "placeholder", "required", "multiple", "disableOptionCentering", "compareWith", "value", "aria-label", "aria-labelledby", "errorStateMatcher", "typeaheadDebounceInterval", "sortComparator", "id", "panelWidth", "canSelectNullableOptions"], outputs: ["openedChange", "opened", "closed", "selectionChange", "valueChange"], exportAs: ["matSelect"] }, { kind: "component", type: i6$2.MatOption, selector: "mat-option", inputs: ["value", "id", "disabled"], outputs: ["onSelectionChange"], exportAs: ["matOption"] }, { kind: "directive", type: PraxisIconDirective, selector: "mat-icon[praxisIcon]", inputs: ["praxisIcon"] }], changeDetection: i0.ChangeDetectionStrategy.OnPush });
1662
- }
1663
- i0.ɵɵngDeclareClassMetadata({ minVersion: "12.0.0", version: "20.3.17", ngImport: i0, type: WidgetShellEditorComponent, decorators: [{
1664
- type: Component,
1665
- args: [{ selector: 'praxis-widget-shell-editor', standalone: true, imports: [
1666
- CommonModule,
1667
- FormsModule,
1668
- ReactiveFormsModule,
1669
- MatButtonModule,
1670
- MatCheckboxModule,
1671
- MatDividerModule,
1672
- MatFormFieldModule,
1673
- MatIconModule,
1674
- MatInputModule,
1675
- MatSelectModule,
1676
- PraxisIconDirective,
1677
- ], template: `
1678
- <div class="shell-editor">
1679
- <div class="shell-head">
1680
- <div>
1681
- <div class="shell-title">Configurar Card</div>
1682
- <div class="shell-subtitle">Defina título, ícone e ações do cabeçalho.</div>
1666
+ <button mat-flat-button color="primary" type="button" (click)="addSetInputAction()">
1667
+ Adicionar ação
1668
+ </button>
1683
1669
  </div>
1684
- <button mat-stroked-button type="button" (click)="reset()">Recarregar</button>
1670
+ }
1671
+
1672
+ <div class="shell-section shell-actions-head">
1673
+ <div>Ações do cabeçalho</div>
1674
+ <button mat-flat-button color="primary" type="button" (click)="addAction()">Adicionar ação</button>
1685
1675
  </div>
1686
-
1687
- <div class="shell-section">Geral</div>
1688
- <div class="shell-grid">
1689
- <mat-form-field appearance="outline">
1690
- <mat-label>Tipo de card</mat-label>
1676
+
1677
+ @if (actions.controls.length) {
1678
+ <div class="shell-actions">
1679
+ @for (action of actions.controls; track action; let i = $index) {
1680
+ <div class="shell-action" [formGroup]="action">
1681
+ <div class="shell-action-row">
1682
+ <mat-form-field appearance="outline">
1683
+ <mat-label>ID</mat-label>
1684
+ <input matInput formControlName="id" />
1685
+ </mat-form-field>
1686
+ <mat-form-field appearance="outline">
1687
+ <mat-label>Label</mat-label>
1688
+ <input matInput formControlName="label" />
1689
+ </mat-form-field>
1690
+ <mat-form-field appearance="outline">
1691
+ <mat-label>Ícone</mat-label>
1692
+ <input matInput formControlName="icon" />
1693
+ </mat-form-field>
1694
+ </div>
1695
+ <div class="shell-action-row">
1696
+ <mat-form-field appearance="outline">
1697
+ <mat-label>Variante</mat-label>
1698
+ <mat-select formControlName="variant">
1699
+ <mat-option value="text">Texto</mat-option>
1700
+ <mat-option value="outlined">Outlined</mat-option>
1701
+ <mat-option value="icon">Ícone</mat-option>
1702
+ </mat-select>
1703
+ </mat-form-field>
1704
+ <mat-form-field appearance="outline">
1705
+ <mat-label>Posição</mat-label>
1706
+ <mat-select formControlName="placement">
1707
+ <mat-option value="header">Cabeçalho</mat-option>
1708
+ <mat-option value="window">Janela</mat-option>
1709
+ </mat-select>
1710
+ </mat-form-field>
1711
+ <mat-form-field appearance="outline">
1712
+ <mat-label>Emit</mat-label>
1713
+ <input matInput formControlName="emit" placeholder="ex: editar" />
1714
+ </mat-form-field>
1715
+ <mat-form-field appearance="outline">
1716
+ <mat-label>Tooltip</mat-label>
1717
+ <input matInput formControlName="tooltip" />
1718
+ </mat-form-field>
1719
+ </div>
1720
+ <div class="shell-action-row">
1721
+ <mat-form-field appearance="outline">
1722
+ <mat-label>Command</mat-label>
1723
+ <input matInput formControlName="command" placeholder="ex: add-item" />
1724
+ </mat-form-field>
1725
+ <mat-form-field appearance="outline">
1726
+ <mat-label>Payload (JSON)</mat-label>
1727
+ <textarea matInput rows="2" formControlName="payload" placeholder='ex: {"foo":"bar"}'></textarea>
1728
+ </mat-form-field>
1729
+ <mat-checkbox formControlName="visible">Visível</mat-checkbox>
1730
+ <mat-checkbox formControlName="disabled">Desabilitado</mat-checkbox>
1731
+ </div>
1732
+ @if (showActionInputPath(action.value)) {
1733
+ <div class="shell-action-hint">
1734
+ Input: {{ displayInputPath(extractActionInput(action.value)) }}
1735
+ </div>
1736
+ }
1737
+ <div class="shell-action-actions">
1738
+ <button mat-stroked-button color="warn" type="button" (click)="removeAction(i)">Remover</button>
1739
+ </div>
1740
+ </div>
1741
+ }
1742
+ </div>
1743
+ } @else {
1744
+ <div class="shell-empty">Nenhuma ação configurada.</div>
1745
+ }
1746
+
1747
+ </div>
1748
+ `, isInline: true, styles: [".shell-editor{display:grid;gap:12px;padding:16px;background:var(--md-sys-color-surface-container-lowest, var(--md-sys-color-surface));border:1px solid var(--md-sys-color-outline-variant);border-radius:12px}.shell-head{display:flex;align-items:center;gap:12px}.shell-title{font-weight:600}.shell-subtitle{font-size:12px;color:var(--md-sys-color-on-surface-variant)}.shell-section{font-weight:600;margin-top:8px}.shell-grid{display:grid;gap:12px;grid-template-columns:repeat(auto-fit,minmax(180px,1fr))}.shell-flags{display:flex;gap:16px;align-items:center}.shell-actions-head{display:flex;align-items:center;justify-content:space-between;gap:12px}.shell-available{display:grid;gap:12px}.shell-available-toolbar{display:grid;gap:12px;grid-template-columns:minmax(200px,1fr)}.shell-available-filters{display:flex;gap:12px;align-items:center;flex-wrap:wrap}.shell-available-list{display:grid;gap:10px}.shell-available-item{display:grid;gap:8px;grid-template-columns:1fr auto;border:1px solid var(--md-sys-color-outline-variant);border-radius:12px;padding:12px;background:var(--md-sys-color-surface-container-low)}.shell-available-title{display:flex;align-items:center;gap:10px}.shell-available-text{display:grid;gap:4px}.shell-available-label{font-weight:600}.shell-available-meta{display:flex;gap:8px;flex-wrap:wrap;font-size:11px;color:var(--md-sys-color-on-surface-variant)}.shell-available-desc{font-size:12px;color:var(--md-sys-color-on-surface-variant)}.shell-available-payload{font-size:11px;color:var(--md-sys-color-on-surface-variant)}.shell-available-warning{font-size:11px;color:var(--md-sys-color-error)}.shell-available-actions{display:flex;align-items:flex-start;justify-content:flex-end}.shell-badge{padding:2px 6px;border-radius:999px;border:1px solid var(--md-sys-color-outline-variant);font-size:10px}.shell-code{font-family:ui-monospace,SFMono-Regular,Menlo,Monaco,Consolas,Liberation Mono,Courier New,monospace}.shell-actions{display:grid;gap:12px}.shell-action{border:1px solid var(--md-sys-color-outline-variant);border-radius:12px;padding:12px;display:grid;gap:8px}.shell-action-row{display:grid;gap:12px;grid-template-columns:repeat(auto-fit,minmax(160px,1fr))}.shell-action-actions{display:flex;justify-content:flex-end}.shell-action-hint,.shell-empty{font-size:12px;color:var(--md-sys-color-on-surface-variant)}.shell-hint{align-self:center;font-size:12px;color:var(--md-sys-color-on-surface-variant)}.shell-quick-inputs{display:grid;gap:12px;grid-template-columns:repeat(auto-fit,minmax(180px,1fr));align-items:end}.shell-input-path{font-size:12px;color:var(--md-sys-color-on-surface-variant);align-self:center}.shell-editor .mat-mdc-form-field{width:100%}.shell-preview{border:1px dashed var(--md-sys-color-outline-variant);border-radius:12px;padding:12px}.shell-preview-card{background:var(--pdx-shell-card-bg, var(--md-sys-color-surface));border:1px solid var(--pdx-shell-card-border, var(--md-sys-color-outline-variant));border-radius:var(--pdx-shell-card-radius, 14px);box-shadow:var(--pdx-shell-card-shadow, var(--mat-elevation-level2));overflow:hidden}.shell-preview-card.no-shell{background:transparent;border:none;box-shadow:none}.shell-preview-card.expanded{box-shadow:var(--pdx-shell-card-shadow, 0 16px 34px rgba(0,0,0,.32));transform:scale(1.01)}.shell-preview-header{display:flex;align-items:center;gap:12px;padding:10px 12px 8px;border-bottom:1px solid var(--pdx-shell-header-border, var(--md-sys-color-outline-variant));background:var(--pdx-shell-header-bg, var(--md-sys-color-surface-container))}.shell-preview-title{display:flex;align-items:center;gap:10px;min-width:0;flex:1;color:var(--pdx-shell-title-color, inherit)}.shell-preview-title mat-icon{color:var(--pdx-shell-icon-color, currentColor)}.shell-preview-text{min-width:0}.shell-preview-title-text{font-weight:var(--pdx-shell-title-weight, 600);font-size:var(--pdx-shell-title-size, 14px);line-height:1.2;white-space:nowrap;overflow:hidden;text-overflow:ellipsis}.shell-preview-subtitle{font-size:var(--pdx-shell-subtitle-size, 12px);opacity:.75;color:var(--pdx-shell-subtitle-color, currentColor);white-space:nowrap;overflow:hidden;text-overflow:ellipsis}.shell-preview-actions{display:flex;align-items:center;gap:6px}.pdx-preview-text{padding:0 8px}.pdx-preview-outlined{border:1px solid var(--md-sys-color-outline-variant);border-radius:999px;padding:0 10px}.pdx-preview-label{font-size:12px;font-weight:500}.shell-preview-body{padding:var(--pdx-shell-body-padding, 10px 12px 12px 12px);background:var(--pdx-shell-body-bg, transparent);color:var(--pdx-shell-body-color, inherit);font-size:12px}.shell-preview-body.hidden{display:none}\n"], dependencies: [{ kind: "ngmodule", type: CommonModule }, { kind: "directive", type: i2$3.NgClass, selector: "[ngClass]", inputs: ["class", "ngClass"] }, { kind: "directive", type: i2$3.NgStyle, selector: "[ngStyle]", inputs: ["ngStyle"] }, { kind: "ngmodule", type: FormsModule }, { kind: "directive", type: i1$1.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$1.NgControlStatus, selector: "[formControlName],[ngModel],[formControl]" }, { kind: "directive", type: i1$1.NgControlStatusGroup, selector: "[formGroupName],[formArrayName],[ngModelGroup],[formGroup],[formArray],form:not([ngNoForm]),[ngForm]" }, { kind: "directive", type: i1$1.NgModel, selector: "[ngModel]:not([formControlName]):not([formControl])", inputs: ["name", "disabled", "ngModel", "ngModelOptions"], outputs: ["ngModelChange"], exportAs: ["ngModel"] }, { kind: "ngmodule", type: ReactiveFormsModule }, { kind: "directive", type: i1$1.FormControlDirective, selector: "[formControl]", inputs: ["formControl", "disabled", "ngModel"], outputs: ["ngModelChange"], exportAs: ["ngForm"] }, { kind: "directive", type: i1$1.FormGroupDirective, selector: "[formGroup]", inputs: ["formGroup"], outputs: ["ngSubmit"], exportAs: ["ngForm"] }, { kind: "directive", type: i1$1.FormControlName, selector: "[formControlName]", inputs: ["formControlName", "disabled", "ngModel"], outputs: ["ngModelChange"] }, { kind: "ngmodule", type: MatButtonModule }, { kind: "component", type: i2.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: i2.MatIconButton, selector: "button[mat-icon-button], a[mat-icon-button], button[matIconButton], a[matIconButton]", exportAs: ["matButton", "matAnchor"] }, { kind: "ngmodule", type: MatCheckboxModule }, { kind: "component", type: i5$1.MatCheckbox, selector: "mat-checkbox", inputs: ["aria-label", "aria-labelledby", "aria-describedby", "aria-expanded", "aria-controls", "aria-owns", "id", "required", "labelPosition", "name", "value", "disableRipple", "tabIndex", "color", "disabledInteractive", "checked", "disabled", "indeterminate"], outputs: ["change", "indeterminateChange"], exportAs: ["matCheckbox"] }, { kind: "ngmodule", type: MatDividerModule }, { kind: "component", type: i6.MatDivider, selector: "mat-divider", inputs: ["vertical", "inset"] }, { kind: "ngmodule", type: MatFormFieldModule }, { kind: "component", type: i3$1.MatFormField, selector: "mat-form-field", inputs: ["hideRequiredMarker", "color", "floatLabel", "appearance", "subscriptSizing", "hintLabel"], exportAs: ["matFormField"] }, { kind: "directive", type: i3$1.MatLabel, selector: "mat-label" }, { kind: "ngmodule", type: MatIconModule }, { kind: "component", type: i2$1.MatIcon, selector: "mat-icon", inputs: ["color", "inline", "svgIcon", "fontSet", "fontIcon"], exportAs: ["matIcon"] }, { kind: "ngmodule", type: MatInputModule }, { kind: "directive", type: i5.MatInput, selector: "input[matInput], textarea[matInput], select[matNativeControl], input[matNativeControl], textarea[matNativeControl]", inputs: ["disabled", "id", "placeholder", "name", "required", "type", "errorStateMatcher", "aria-describedby", "value", "readonly", "disabledInteractive"], exportAs: ["matInput"] }, { kind: "ngmodule", type: MatSelectModule }, { kind: "component", type: i6$1.MatSelect, selector: "mat-select", inputs: ["aria-describedby", "panelClass", "disabled", "disableRipple", "tabIndex", "hideSingleSelectionIndicator", "placeholder", "required", "multiple", "disableOptionCentering", "compareWith", "value", "aria-label", "aria-labelledby", "errorStateMatcher", "typeaheadDebounceInterval", "sortComparator", "id", "panelWidth", "canSelectNullableOptions"], outputs: ["openedChange", "opened", "closed", "selectionChange", "valueChange"], exportAs: ["matSelect"] }, { kind: "component", type: i6$1.MatOption, selector: "mat-option", inputs: ["value", "id", "disabled"], outputs: ["onSelectionChange"], exportAs: ["matOption"] }, { kind: "directive", type: PraxisIconDirective, selector: "mat-icon[praxisIcon]", inputs: ["praxisIcon"] }], changeDetection: i0.ChangeDetectionStrategy.OnPush });
1749
+ }
1750
+ i0.ɵɵngDeclareClassMetadata({ minVersion: "12.0.0", version: "21.2.14", ngImport: i0, type: WidgetShellEditorComponent, decorators: [{
1751
+ type: Component,
1752
+ args: [{ selector: 'praxis-widget-shell-editor', standalone: true, imports: [
1753
+ CommonModule,
1754
+ FormsModule,
1755
+ ReactiveFormsModule,
1756
+ MatButtonModule,
1757
+ MatCheckboxModule,
1758
+ MatDividerModule,
1759
+ MatFormFieldModule,
1760
+ MatIconModule,
1761
+ MatInputModule,
1762
+ MatSelectModule,
1763
+ PraxisIconDirective,
1764
+ ], template: `
1765
+ <div class="shell-editor">
1766
+ <div class="shell-head">
1767
+ <div>
1768
+ <div class="shell-title">Configurar Card</div>
1769
+ <div class="shell-subtitle">Defina título, ícone e ações do cabeçalho.</div>
1770
+ </div>
1771
+ <button mat-stroked-button type="button" (click)="reset()">Recarregar</button>
1772
+ </div>
1773
+
1774
+ <div class="shell-section">Geral</div>
1775
+ <div class="shell-grid">
1776
+ <mat-form-field appearance="outline">
1777
+ <mat-label>Tipo de card</mat-label>
1691
1778
  <mat-select [formControl]="form.controls.kind">
1692
1779
  <mat-option value="dashboard-card">Dashboard Card</mat-option>
1693
1780
  <mat-option value="none">Sem shell</mat-option>
@@ -1697,16 +1784,24 @@ i0.ɵɵngDeclareClassMetadata({ minVersion: "12.0.0", version: "20.3.17", ngImpo
1697
1784
  <mat-label>Preset</mat-label>
1698
1785
  <mat-select [formControl]="form.controls.preset">
1699
1786
  <mat-option value="">Nenhum</mat-option>
1700
- <mat-option *ngIf="pagePreset" [value]="pagePreset">Usar preset da página ({{ pagePreset }})</mat-option>
1701
- <mat-option *ngFor="let p of presetOptions" [value]="p.id">{{ p.label }}</mat-option>
1787
+ @if (pagePreset) {
1788
+ <mat-option [value]="pagePreset">Usar preset da página ({{ pagePreset }})</mat-option>
1789
+ }
1790
+ @for (p of presetOptions; track p) {
1791
+ <mat-option [value]="p.id">{{ p.label }}</mat-option>
1792
+ }
1702
1793
  </mat-select>
1703
1794
  </mat-form-field>
1704
- <div class="shell-hint" *ngIf="!form.controls.preset.value && pagePreset">
1705
- Preset da página: {{ pagePreset }}
1706
- </div>
1707
- <mat-checkbox [formControl]="form.controls.applyToAll" *ngIf="form.controls.preset.value">
1708
- Aplicar preset como padrão da página
1709
- </mat-checkbox>
1795
+ @if (!form.controls.preset.value && pagePreset) {
1796
+ <div class="shell-hint">
1797
+ Preset da página: {{ pagePreset }}
1798
+ </div>
1799
+ }
1800
+ @if (form.controls.preset.value) {
1801
+ <mat-checkbox [formControl]="form.controls.applyToAll">
1802
+ Aplicar preset como padrão da página
1803
+ </mat-checkbox>
1804
+ }
1710
1805
  <mat-form-field appearance="outline">
1711
1806
  <mat-label>Ícone</mat-label>
1712
1807
  <input matInput [formControl]="form.controls.icon" placeholder="ex: badge" />
@@ -1728,14 +1823,14 @@ i0.ɵɵngDeclareClassMetadata({ minVersion: "12.0.0", version: "20.3.17", ngImpo
1728
1823
  </mat-select>
1729
1824
  </mat-form-field>
1730
1825
  </div>
1731
-
1826
+
1732
1827
  <div class="shell-section">Controles de janela</div>
1733
1828
  <div class="shell-flags">
1734
1829
  <mat-checkbox [formControl]="form.controls.collapsible">Permitir recolher</mat-checkbox>
1735
1830
  </div>
1736
-
1831
+
1737
1832
  <mat-divider></mat-divider>
1738
-
1833
+
1739
1834
  <div class="shell-section">Aparência</div>
1740
1835
  <div class="shell-grid">
1741
1836
  <mat-form-field appearance="outline">
@@ -1799,216 +1894,265 @@ i0.ɵɵngDeclareClassMetadata({ minVersion: "12.0.0", version: "20.3.17", ngImpo
1799
1894
  <input matInput [formControl]="form.controls.subtitleSize" placeholder="ex: 12px" />
1800
1895
  </mat-form-field>
1801
1896
  </div>
1802
-
1897
+
1803
1898
  <div class="shell-preview" [ngStyle]="previewVars()">
1804
1899
  <div class="shell-preview-card" [class.no-shell]="form.controls.kind.value === 'none'" [class.expanded]="previewExpanded">
1805
- <div class="shell-preview-header" *ngIf="previewShowHeader()">
1806
- <div class="shell-preview-title">
1807
- <mat-icon *ngIf="form.controls.icon.value" [praxisIcon]="form.controls.icon.value"></mat-icon>
1808
- <div class="shell-preview-text">
1809
- <div class="shell-preview-title-text">{{ previewTitle() }}</div>
1810
- <div class="shell-preview-subtitle">{{ previewSubtitle() }}</div>
1900
+ @if (previewShowHeader()) {
1901
+ <div class="shell-preview-header">
1902
+ <div class="shell-preview-title">
1903
+ @if (form.controls.icon.value) {
1904
+ <mat-icon [praxisIcon]="form.controls.icon.value"></mat-icon>
1905
+ }
1906
+ <div class="shell-preview-text">
1907
+ <div class="shell-preview-title-text">{{ previewTitle() }}</div>
1908
+ <div class="shell-preview-subtitle">{{ previewSubtitle() }}</div>
1909
+ </div>
1910
+ </div>
1911
+ <div class="shell-preview-actions">
1912
+ @for (action of previewHeaderActions(); track action) {
1913
+ <button
1914
+ type="button"
1915
+ [disabled]="action.disabled"
1916
+ [ngClass]="action.variant === 'outlined' ? 'pdx-preview-outlined' : 'pdx-preview-text'"
1917
+ mat-button
1918
+ >
1919
+ @if (action.icon) {
1920
+ <mat-icon [praxisIcon]="action.icon"></mat-icon>
1921
+ }
1922
+ <span class="pdx-preview-label">{{ action.label || action.id }}</span>
1923
+ </button>
1924
+ }
1925
+ @if (previewOverflowCount()) {
1926
+ <button
1927
+ mat-icon-button
1928
+ type="button"
1929
+ aria-label="Mais ações"
1930
+ >
1931
+ <mat-icon>more_horiz</mat-icon>
1932
+ </button>
1933
+ }
1934
+ @for (action of previewWindowActions(); track action) {
1935
+ <button
1936
+ mat-icon-button
1937
+ type="button"
1938
+ [disabled]="action.disabled"
1939
+ [attr.aria-label]="action.label || action.id"
1940
+ >
1941
+ @if (action.icon) {
1942
+ <mat-icon [praxisIcon]="action.icon"></mat-icon>
1943
+ }
1944
+ </button>
1945
+ }
1946
+ <button mat-icon-button type="button" (click)="togglePreviewCollapse()" aria-label="Recolher">
1947
+ <mat-icon>{{ previewCollapsed ? 'unfold_more' : 'unfold_less' }}</mat-icon>
1948
+ </button>
1949
+ <button mat-icon-button type="button" (click)="togglePreviewExpand()" aria-label="Expandir">
1950
+ <mat-icon>{{ previewExpanded ? 'close_fullscreen' : 'open_in_full' }}</mat-icon>
1951
+ </button>
1811
1952
  </div>
1812
1953
  </div>
1813
- <div class="shell-preview-actions">
1814
- <button
1815
- *ngFor="let action of previewHeaderActions()"
1816
- type="button"
1817
- [disabled]="action.disabled"
1818
- [ngClass]="action.variant === 'outlined' ? 'pdx-preview-outlined' : 'pdx-preview-text'"
1819
- mat-button
1820
- >
1821
- <mat-icon *ngIf="action.icon" [praxisIcon]="action.icon"></mat-icon>
1822
- <span class="pdx-preview-label">{{ action.label || action.id }}</span>
1823
- </button>
1824
- <button
1825
- *ngIf="previewOverflowCount()"
1826
- mat-icon-button
1827
- type="button"
1828
- aria-label="Mais ações"
1829
- >
1830
- <mat-icon>more_horiz</mat-icon>
1831
- </button>
1832
- <button
1833
- *ngFor="let action of previewWindowActions()"
1834
- mat-icon-button
1835
- type="button"
1836
- [disabled]="action.disabled"
1837
- [attr.aria-label]="action.label || action.id"
1838
- >
1839
- <mat-icon *ngIf="action.icon" [praxisIcon]="action.icon"></mat-icon>
1840
- </button>
1841
- <button mat-icon-button type="button" (click)="togglePreviewCollapse()" aria-label="Recolher">
1842
- <mat-icon>{{ previewCollapsed ? 'unfold_more' : 'unfold_less' }}</mat-icon>
1843
- </button>
1844
- <button mat-icon-button type="button" (click)="togglePreviewExpand()" aria-label="Expandir">
1845
- <mat-icon>{{ previewExpanded ? 'close_fullscreen' : 'open_in_full' }}</mat-icon>
1846
- </button>
1847
- </div>
1848
- </div>
1954
+ }
1849
1955
  <div class="shell-preview-body" [class.hidden]="previewCollapsed">Conteudo do widget</div>
1850
1956
  </div>
1851
1957
  </div>
1852
-
1958
+
1853
1959
  <mat-divider></mat-divider>
1854
-
1855
- <div class="shell-section" *ngIf="hasAvailableActions">Ações disponíveis</div>
1856
- <div class="shell-available" *ngIf="hasAvailableActions; else noAvailableActions">
1857
- <div class="shell-available-toolbar">
1858
- <mat-form-field appearance="outline">
1859
- <mat-label>Buscar ação</mat-label>
1860
- <input matInput [formControl]="actionQuery" placeholder="ex: export, editar, submit" />
1861
- </mat-form-field>
1862
- <div class="shell-available-filters">
1863
- <mat-checkbox [(ngModel)]="showScopeShell">Shell</mat-checkbox>
1864
- <mat-checkbox [(ngModel)]="showScopeAny">Any</mat-checkbox>
1865
- <mat-checkbox [(ngModel)]="showScopeToolbar">Toolbar</mat-checkbox>
1866
- <mat-checkbox [(ngModel)]="showScopeContext">Context</mat-checkbox>
1960
+
1961
+ @if (hasAvailableActions) {
1962
+ <div class="shell-section">Ações disponíveis</div>
1963
+ }
1964
+ @if (hasAvailableActions) {
1965
+ <div class="shell-available">
1966
+ <div class="shell-available-toolbar">
1967
+ <mat-form-field appearance="outline">
1968
+ <mat-label>Buscar ação</mat-label>
1969
+ <input matInput [formControl]="actionQuery" placeholder="ex: export, editar, submit" />
1970
+ </mat-form-field>
1971
+ <div class="shell-available-filters">
1972
+ <mat-checkbox [(ngModel)]="showScopeShell">Shell</mat-checkbox>
1973
+ <mat-checkbox [(ngModel)]="showScopeAny">Any</mat-checkbox>
1974
+ <mat-checkbox [(ngModel)]="showScopeToolbar">Toolbar</mat-checkbox>
1975
+ <mat-checkbox [(ngModel)]="showScopeContext">Context</mat-checkbox>
1976
+ </div>
1867
1977
  </div>
1868
- </div>
1869
- <div class="shell-available-list">
1870
- <div class="shell-available-item" *ngFor="let action of filteredAvailableActions()">
1871
- <div class="shell-available-main">
1872
- <div class="shell-available-title">
1873
- <mat-icon *ngIf="action.icon" [praxisIcon]="action.icon"></mat-icon>
1874
- <div class="shell-available-text">
1875
- <div class="shell-available-label">{{ action.label }}</div>
1876
- <div class="shell-available-meta">
1877
- <span class="shell-badge">{{ action.kind === 'command' ? 'Comando' : 'Ação' }}</span>
1878
- <span class="shell-badge">{{ scopeLabel(action.scope) }}</span>
1879
- <span class="shell-code">id: {{ action.id }}</span>
1880
- <span *ngIf="action.emit" class="shell-code">emit: {{ action.emit }}</span>
1881
- <span *ngIf="action.command" class="shell-code">command: {{ action.command }}</span>
1978
+ <div class="shell-available-list">
1979
+ @for (action of filteredAvailableActions(); track action) {
1980
+ <div class="shell-available-item">
1981
+ <div class="shell-available-main">
1982
+ <div class="shell-available-title">
1983
+ @if (action.icon) {
1984
+ <mat-icon [praxisIcon]="action.icon"></mat-icon>
1985
+ }
1986
+ <div class="shell-available-text">
1987
+ <div class="shell-available-label">{{ action.label }}</div>
1988
+ <div class="shell-available-meta">
1989
+ <span class="shell-badge">{{ action.kind === 'command' ? 'Comando' : 'Ação' }}</span>
1990
+ <span class="shell-badge">{{ scopeLabel(action.scope) }}</span>
1991
+ <span class="shell-code">id: {{ action.id }}</span>
1992
+ @if (action.emit) {
1993
+ <span class="shell-code">emit: {{ action.emit }}</span>
1994
+ }
1995
+ @if (action.command) {
1996
+ <span class="shell-code">command: {{ action.command }}</span>
1997
+ }
1998
+ </div>
1999
+ </div>
1882
2000
  </div>
2001
+ @if (action.description) {
2002
+ <div class="shell-available-desc">{{ action.description }}</div>
2003
+ }
2004
+ @if (action.payloadExample !== undefined) {
2005
+ <div class="shell-available-payload">
2006
+ <span class="shell-code">payload: {{ stringifyPayload(action.payloadExample) }}</span>
2007
+ </div>
2008
+ }
2009
+ @if (action.scope === 'context') {
2010
+ <div class="shell-available-warning">
2011
+ Essa ação depende de item/linha selecionado; payload fixo pode não funcionar.
2012
+ </div>
2013
+ }
2014
+ </div>
2015
+ <div class="shell-available-actions">
2016
+ <button
2017
+ mat-stroked-button
2018
+ type="button"
2019
+ [color]="isActionSelected(action) ? 'warn' : 'primary'"
2020
+ (click)="toggleAvailableAction(action)"
2021
+ >
2022
+ {{ isActionSelected(action) ? 'Remover' : 'Adicionar' }}
2023
+ </button>
1883
2024
  </div>
1884
2025
  </div>
1885
- <div class="shell-available-desc" *ngIf="action.description">{{ action.description }}</div>
1886
- <div class="shell-available-payload" *ngIf="action.payloadExample !== undefined">
1887
- <span class="shell-code">payload: {{ stringifyPayload(action.payloadExample) }}</span>
1888
- </div>
1889
- <div class="shell-available-warning" *ngIf="action.scope === 'context'">
1890
- Essa ação depende de item/linha selecionado; payload fixo pode não funcionar.
1891
- </div>
1892
- </div>
1893
- <div class="shell-available-actions">
1894
- <button
1895
- mat-stroked-button
1896
- type="button"
1897
- [color]="isActionSelected(action) ? 'warn' : 'primary'"
1898
- (click)="toggleAvailableAction(action)"
1899
- >
1900
- {{ isActionSelected(action) ? 'Remover' : 'Adicionar' }}
1901
- </button>
1902
- </div>
2026
+ }
1903
2027
  </div>
1904
2028
  </div>
1905
- </div>
1906
- <ng-template #noAvailableActions>
2029
+ } @else {
1907
2030
  <div class="shell-empty">Nenhuma ação registrada para este componente.</div>
1908
- </ng-template>
1909
-
1910
- <mat-divider *ngIf="hasAvailableActions"></mat-divider>
1911
-
1912
- <div class="shell-section" *ngIf="setInputPresets.length">Ações rápidas (inputs)</div>
1913
- <div class="shell-quick-inputs" *ngIf="setInputPresets.length">
1914
- <mat-form-field appearance="outline">
1915
- <mat-label>Input</mat-label>
1916
- <mat-select [formControl]="setInputTarget">
1917
- <mat-option *ngFor="let preset of setInputPresets" [value]="preset.input">
1918
- <mat-icon *ngIf="preset.icon" [praxisIcon]="preset.icon"></mat-icon>
1919
- {{ preset.label }}
1920
- </mat-option>
1921
- </mat-select>
1922
- </mat-form-field>
1923
- <div class="shell-input-path" *ngIf="setInputTarget.value">
1924
- Input: {{ displayInputPath(setInputTarget.value) }}
1925
- </div>
1926
- <mat-form-field appearance="outline">
1927
- <mat-label>Valor</mat-label>
1928
- <mat-select [formControl]="setInputValue">
1929
- <mat-option *ngFor="let option of currentSetInputValues()" [value]="option.value">
1930
- <mat-icon *ngIf="option.icon" [praxisIcon]="option.icon"></mat-icon>
1931
- {{ option.label }}
1932
- </mat-option>
1933
- </mat-select>
1934
- </mat-form-field>
1935
- <button mat-flat-button color="primary" type="button" (click)="addSetInputAction()">
1936
- Adicionar ação
1937
- </button>
1938
- </div>
1939
-
1940
- <div class="shell-section shell-actions-head">
1941
- <div>Ações do cabeçalho</div>
1942
- <button mat-flat-button color="primary" type="button" (click)="addAction()">Adicionar ação</button>
1943
- </div>
1944
-
1945
- <div class="shell-actions" *ngIf="actions.controls.length; else emptyActions">
1946
- <div class="shell-action" *ngFor="let action of actions.controls; let i = index" [formGroup]="action">
1947
- <div class="shell-action-row">
1948
- <mat-form-field appearance="outline">
1949
- <mat-label>ID</mat-label>
1950
- <input matInput formControlName="id" />
1951
- </mat-form-field>
1952
- <mat-form-field appearance="outline">
1953
- <mat-label>Label</mat-label>
1954
- <input matInput formControlName="label" />
1955
- </mat-form-field>
1956
- <mat-form-field appearance="outline">
1957
- <mat-label>Ícone</mat-label>
1958
- <input matInput formControlName="icon" />
1959
- </mat-form-field>
1960
- </div>
1961
- <div class="shell-action-row">
1962
- <mat-form-field appearance="outline">
1963
- <mat-label>Variante</mat-label>
1964
- <mat-select formControlName="variant">
1965
- <mat-option value="text">Texto</mat-option>
1966
- <mat-option value="outlined">Outlined</mat-option>
1967
- <mat-option value="icon">Ícone</mat-option>
2031
+ }
2032
+
2033
+ @if (hasAvailableActions) {
2034
+ <mat-divider></mat-divider>
2035
+ }
2036
+
2037
+ @if (setInputPresets.length) {
2038
+ <div class="shell-section">Ações rápidas (inputs)</div>
2039
+ }
2040
+ @if (setInputPresets.length) {
2041
+ <div class="shell-quick-inputs">
2042
+ <mat-form-field appearance="outline">
2043
+ <mat-label>Input</mat-label>
2044
+ <mat-select [formControl]="setInputTarget">
2045
+ @for (preset of setInputPresets; track preset) {
2046
+ <mat-option [value]="preset.input">
2047
+ @if (preset.icon) {
2048
+ <mat-icon [praxisIcon]="preset.icon"></mat-icon>
2049
+ }
2050
+ {{ preset.label }}
2051
+ </mat-option>
2052
+ }
1968
2053
  </mat-select>
1969
2054
  </mat-form-field>
2055
+ @if (setInputTarget.value) {
2056
+ <div class="shell-input-path">
2057
+ Input: {{ displayInputPath(setInputTarget.value) }}
2058
+ </div>
2059
+ }
1970
2060
  <mat-form-field appearance="outline">
1971
- <mat-label>Posição</mat-label>
1972
- <mat-select formControlName="placement">
1973
- <mat-option value="header">Cabeçalho</mat-option>
1974
- <mat-option value="window">Janela</mat-option>
2061
+ <mat-label>Valor</mat-label>
2062
+ <mat-select [formControl]="setInputValue">
2063
+ @for (option of currentSetInputValues(); track option) {
2064
+ <mat-option [value]="option.value">
2065
+ @if (option.icon) {
2066
+ <mat-icon [praxisIcon]="option.icon"></mat-icon>
2067
+ }
2068
+ {{ option.label }}
2069
+ </mat-option>
2070
+ }
1975
2071
  </mat-select>
1976
2072
  </mat-form-field>
1977
- <mat-form-field appearance="outline">
1978
- <mat-label>Emit</mat-label>
1979
- <input matInput formControlName="emit" placeholder="ex: editar" />
1980
- </mat-form-field>
1981
- <mat-form-field appearance="outline">
1982
- <mat-label>Tooltip</mat-label>
1983
- <input matInput formControlName="tooltip" />
1984
- </mat-form-field>
1985
- </div>
1986
- <div class="shell-action-row">
1987
- <mat-form-field appearance="outline">
1988
- <mat-label>Command</mat-label>
1989
- <input matInput formControlName="command" placeholder="ex: add-item" />
1990
- </mat-form-field>
1991
- <mat-form-field appearance="outline">
1992
- <mat-label>Payload (JSON)</mat-label>
1993
- <textarea matInput rows="2" formControlName="payload" placeholder='ex: {"foo":"bar"}'></textarea>
1994
- </mat-form-field>
1995
- <mat-checkbox formControlName="visible">Visível</mat-checkbox>
1996
- <mat-checkbox formControlName="disabled">Desabilitado</mat-checkbox>
1997
- </div>
1998
- <div class="shell-action-hint" *ngIf="showActionInputPath(action.value)">
1999
- Input: {{ displayInputPath(extractActionInput(action.value)) }}
2000
- </div>
2001
- <div class="shell-action-actions">
2002
- <button mat-stroked-button color="warn" type="button" (click)="removeAction(i)">Remover</button>
2003
- </div>
2073
+ <button mat-flat-button color="primary" type="button" (click)="addSetInputAction()">
2074
+ Adicionar ação
2075
+ </button>
2004
2076
  </div>
2077
+ }
2078
+
2079
+ <div class="shell-section shell-actions-head">
2080
+ <div>Ações do cabeçalho</div>
2081
+ <button mat-flat-button color="primary" type="button" (click)="addAction()">Adicionar ação</button>
2005
2082
  </div>
2006
-
2007
- <ng-template #emptyActions>
2083
+
2084
+ @if (actions.controls.length) {
2085
+ <div class="shell-actions">
2086
+ @for (action of actions.controls; track action; let i = $index) {
2087
+ <div class="shell-action" [formGroup]="action">
2088
+ <div class="shell-action-row">
2089
+ <mat-form-field appearance="outline">
2090
+ <mat-label>ID</mat-label>
2091
+ <input matInput formControlName="id" />
2092
+ </mat-form-field>
2093
+ <mat-form-field appearance="outline">
2094
+ <mat-label>Label</mat-label>
2095
+ <input matInput formControlName="label" />
2096
+ </mat-form-field>
2097
+ <mat-form-field appearance="outline">
2098
+ <mat-label>Ícone</mat-label>
2099
+ <input matInput formControlName="icon" />
2100
+ </mat-form-field>
2101
+ </div>
2102
+ <div class="shell-action-row">
2103
+ <mat-form-field appearance="outline">
2104
+ <mat-label>Variante</mat-label>
2105
+ <mat-select formControlName="variant">
2106
+ <mat-option value="text">Texto</mat-option>
2107
+ <mat-option value="outlined">Outlined</mat-option>
2108
+ <mat-option value="icon">Ícone</mat-option>
2109
+ </mat-select>
2110
+ </mat-form-field>
2111
+ <mat-form-field appearance="outline">
2112
+ <mat-label>Posição</mat-label>
2113
+ <mat-select formControlName="placement">
2114
+ <mat-option value="header">Cabeçalho</mat-option>
2115
+ <mat-option value="window">Janela</mat-option>
2116
+ </mat-select>
2117
+ </mat-form-field>
2118
+ <mat-form-field appearance="outline">
2119
+ <mat-label>Emit</mat-label>
2120
+ <input matInput formControlName="emit" placeholder="ex: editar" />
2121
+ </mat-form-field>
2122
+ <mat-form-field appearance="outline">
2123
+ <mat-label>Tooltip</mat-label>
2124
+ <input matInput formControlName="tooltip" />
2125
+ </mat-form-field>
2126
+ </div>
2127
+ <div class="shell-action-row">
2128
+ <mat-form-field appearance="outline">
2129
+ <mat-label>Command</mat-label>
2130
+ <input matInput formControlName="command" placeholder="ex: add-item" />
2131
+ </mat-form-field>
2132
+ <mat-form-field appearance="outline">
2133
+ <mat-label>Payload (JSON)</mat-label>
2134
+ <textarea matInput rows="2" formControlName="payload" placeholder='ex: {"foo":"bar"}'></textarea>
2135
+ </mat-form-field>
2136
+ <mat-checkbox formControlName="visible">Visível</mat-checkbox>
2137
+ <mat-checkbox formControlName="disabled">Desabilitado</mat-checkbox>
2138
+ </div>
2139
+ @if (showActionInputPath(action.value)) {
2140
+ <div class="shell-action-hint">
2141
+ Input: {{ displayInputPath(extractActionInput(action.value)) }}
2142
+ </div>
2143
+ }
2144
+ <div class="shell-action-actions">
2145
+ <button mat-stroked-button color="warn" type="button" (click)="removeAction(i)">Remover</button>
2146
+ </div>
2147
+ </div>
2148
+ }
2149
+ </div>
2150
+ } @else {
2008
2151
  <div class="shell-empty">Nenhuma ação configurada.</div>
2009
- </ng-template>
2152
+ }
2153
+
2010
2154
  </div>
2011
- `, changeDetection: ChangeDetectionStrategy.OnPush, styles: [".shell-editor{display:grid;gap:12px;padding:16px;background:var(--md-sys-color-surface-container-lowest, var(--md-sys-color-surface));border:1px solid var(--md-sys-color-outline-variant);border-radius:12px}.shell-head{display:flex;align-items:center;gap:12px}.shell-title{font-weight:600}.shell-subtitle{font-size:12px;color:var(--md-sys-color-on-surface-variant)}.shell-section{font-weight:600;margin-top:8px}.shell-grid{display:grid;gap:12px;grid-template-columns:repeat(auto-fit,minmax(180px,1fr))}.shell-flags{display:flex;gap:16px;align-items:center}.shell-actions-head{display:flex;align-items:center;justify-content:space-between;gap:12px}.shell-available{display:grid;gap:12px}.shell-available-toolbar{display:grid;gap:12px;grid-template-columns:minmax(200px,1fr)}.shell-available-filters{display:flex;gap:12px;align-items:center;flex-wrap:wrap}.shell-available-list{display:grid;gap:10px}.shell-available-item{display:grid;gap:8px;grid-template-columns:1fr auto;border:1px solid var(--md-sys-color-outline-variant);border-radius:12px;padding:12px;background:var(--md-sys-color-surface-container-low)}.shell-available-title{display:flex;align-items:center;gap:10px}.shell-available-text{display:grid;gap:4px}.shell-available-label{font-weight:600}.shell-available-meta{display:flex;gap:8px;flex-wrap:wrap;font-size:11px;color:var(--md-sys-color-on-surface-variant)}.shell-available-desc{font-size:12px;color:var(--md-sys-color-on-surface-variant)}.shell-available-payload{font-size:11px;color:var(--md-sys-color-on-surface-variant)}.shell-available-warning{font-size:11px;color:var(--md-sys-color-error)}.shell-available-actions{display:flex;align-items:flex-start;justify-content:flex-end}.shell-badge{padding:2px 6px;border-radius:999px;border:1px solid var(--md-sys-color-outline-variant);font-size:10px}.shell-code{font-family:ui-monospace,SFMono-Regular,Menlo,Monaco,Consolas,Liberation Mono,Courier New,monospace}.shell-actions{display:grid;gap:12px}.shell-action{border:1px solid var(--md-sys-color-outline-variant);border-radius:12px;padding:12px;display:grid;gap:8px}.shell-action-row{display:grid;gap:12px;grid-template-columns:repeat(auto-fit,minmax(160px,1fr))}.shell-action-actions{display:flex;justify-content:flex-end}.shell-action-hint,.shell-empty{font-size:12px;color:var(--md-sys-color-on-surface-variant)}.shell-hint{align-self:center;font-size:12px;color:var(--md-sys-color-on-surface-variant)}.shell-quick-inputs{display:grid;gap:12px;grid-template-columns:repeat(auto-fit,minmax(180px,1fr));align-items:end}.shell-input-path{font-size:12px;color:var(--md-sys-color-on-surface-variant);align-self:center}.shell-editor .mat-mdc-form-field{width:100%}.shell-preview{border:1px dashed var(--md-sys-color-outline-variant);border-radius:12px;padding:12px}.shell-preview-card{background:var(--pdx-shell-card-bg, var(--md-sys-color-surface));border:1px solid var(--pdx-shell-card-border, var(--md-sys-color-outline-variant));border-radius:var(--pdx-shell-card-radius, 14px);box-shadow:var(--pdx-shell-card-shadow, var(--mat-elevation-level2));overflow:hidden}.shell-preview-card.no-shell{background:transparent;border:none;box-shadow:none}.shell-preview-card.expanded{box-shadow:var(--pdx-shell-card-shadow, 0 16px 34px rgba(0,0,0,.32));transform:scale(1.01)}.shell-preview-header{display:flex;align-items:center;gap:12px;padding:10px 12px 8px;border-bottom:1px solid var(--pdx-shell-header-border, var(--md-sys-color-outline-variant));background:var(--pdx-shell-header-bg, var(--md-sys-color-surface-container))}.shell-preview-title{display:flex;align-items:center;gap:10px;min-width:0;flex:1;color:var(--pdx-shell-title-color, inherit)}.shell-preview-title mat-icon{color:var(--pdx-shell-icon-color, currentColor)}.shell-preview-text{min-width:0}.shell-preview-title-text{font-weight:var(--pdx-shell-title-weight, 600);font-size:var(--pdx-shell-title-size, 14px);line-height:1.2;white-space:nowrap;overflow:hidden;text-overflow:ellipsis}.shell-preview-subtitle{font-size:var(--pdx-shell-subtitle-size, 12px);opacity:.75;color:var(--pdx-shell-subtitle-color, currentColor);white-space:nowrap;overflow:hidden;text-overflow:ellipsis}.shell-preview-actions{display:flex;align-items:center;gap:6px}.pdx-preview-text{padding:0 8px}.pdx-preview-outlined{border:1px solid var(--md-sys-color-outline-variant);border-radius:999px;padding:0 10px}.pdx-preview-label{font-size:12px;font-weight:500}.shell-preview-body{padding:var(--pdx-shell-body-padding, 10px 12px 12px 12px);background:var(--pdx-shell-body-bg, transparent);color:var(--pdx-shell-body-color, inherit);font-size:12px}.shell-preview-body.hidden{display:none}\n"] }]
2155
+ `, changeDetection: ChangeDetectionStrategy.OnPush, styles: [".shell-editor{display:grid;gap:12px;padding:16px;background:var(--md-sys-color-surface-container-lowest, var(--md-sys-color-surface));border:1px solid var(--md-sys-color-outline-variant);border-radius:12px}.shell-head{display:flex;align-items:center;gap:12px}.shell-title{font-weight:600}.shell-subtitle{font-size:12px;color:var(--md-sys-color-on-surface-variant)}.shell-section{font-weight:600;margin-top:8px}.shell-grid{display:grid;gap:12px;grid-template-columns:repeat(auto-fit,minmax(180px,1fr))}.shell-flags{display:flex;gap:16px;align-items:center}.shell-actions-head{display:flex;align-items:center;justify-content:space-between;gap:12px}.shell-available{display:grid;gap:12px}.shell-available-toolbar{display:grid;gap:12px;grid-template-columns:minmax(200px,1fr)}.shell-available-filters{display:flex;gap:12px;align-items:center;flex-wrap:wrap}.shell-available-list{display:grid;gap:10px}.shell-available-item{display:grid;gap:8px;grid-template-columns:1fr auto;border:1px solid var(--md-sys-color-outline-variant);border-radius:12px;padding:12px;background:var(--md-sys-color-surface-container-low)}.shell-available-title{display:flex;align-items:center;gap:10px}.shell-available-text{display:grid;gap:4px}.shell-available-label{font-weight:600}.shell-available-meta{display:flex;gap:8px;flex-wrap:wrap;font-size:11px;color:var(--md-sys-color-on-surface-variant)}.shell-available-desc{font-size:12px;color:var(--md-sys-color-on-surface-variant)}.shell-available-payload{font-size:11px;color:var(--md-sys-color-on-surface-variant)}.shell-available-warning{font-size:11px;color:var(--md-sys-color-error)}.shell-available-actions{display:flex;align-items:flex-start;justify-content:flex-end}.shell-badge{padding:2px 6px;border-radius:999px;border:1px solid var(--md-sys-color-outline-variant);font-size:10px}.shell-code{font-family:ui-monospace,SFMono-Regular,Menlo,Monaco,Consolas,Liberation Mono,Courier New,monospace}.shell-actions{display:grid;gap:12px}.shell-action{border:1px solid var(--md-sys-color-outline-variant);border-radius:12px;padding:12px;display:grid;gap:8px}.shell-action-row{display:grid;gap:12px;grid-template-columns:repeat(auto-fit,minmax(160px,1fr))}.shell-action-actions{display:flex;justify-content:flex-end}.shell-action-hint,.shell-empty{font-size:12px;color:var(--md-sys-color-on-surface-variant)}.shell-hint{align-self:center;font-size:12px;color:var(--md-sys-color-on-surface-variant)}.shell-quick-inputs{display:grid;gap:12px;grid-template-columns:repeat(auto-fit,minmax(180px,1fr));align-items:end}.shell-input-path{font-size:12px;color:var(--md-sys-color-on-surface-variant);align-self:center}.shell-editor .mat-mdc-form-field{width:100%}.shell-preview{border:1px dashed var(--md-sys-color-outline-variant);border-radius:12px;padding:12px}.shell-preview-card{background:var(--pdx-shell-card-bg, var(--md-sys-color-surface));border:1px solid var(--pdx-shell-card-border, var(--md-sys-color-outline-variant));border-radius:var(--pdx-shell-card-radius, 14px);box-shadow:var(--pdx-shell-card-shadow, var(--mat-elevation-level2));overflow:hidden}.shell-preview-card.no-shell{background:transparent;border:none;box-shadow:none}.shell-preview-card.expanded{box-shadow:var(--pdx-shell-card-shadow, 0 16px 34px rgba(0,0,0,.32));transform:scale(1.01)}.shell-preview-header{display:flex;align-items:center;gap:12px;padding:10px 12px 8px;border-bottom:1px solid var(--pdx-shell-header-border, var(--md-sys-color-outline-variant));background:var(--pdx-shell-header-bg, var(--md-sys-color-surface-container))}.shell-preview-title{display:flex;align-items:center;gap:10px;min-width:0;flex:1;color:var(--pdx-shell-title-color, inherit)}.shell-preview-title mat-icon{color:var(--pdx-shell-icon-color, currentColor)}.shell-preview-text{min-width:0}.shell-preview-title-text{font-weight:var(--pdx-shell-title-weight, 600);font-size:var(--pdx-shell-title-size, 14px);line-height:1.2;white-space:nowrap;overflow:hidden;text-overflow:ellipsis}.shell-preview-subtitle{font-size:var(--pdx-shell-subtitle-size, 12px);opacity:.75;color:var(--pdx-shell-subtitle-color, currentColor);white-space:nowrap;overflow:hidden;text-overflow:ellipsis}.shell-preview-actions{display:flex;align-items:center;gap:6px}.pdx-preview-text{padding:0 8px}.pdx-preview-outlined{border:1px solid var(--md-sys-color-outline-variant);border-radius:999px;padding:0 10px}.pdx-preview-label{font-size:12px;font-weight:500}.shell-preview-body{padding:var(--pdx-shell-body-padding, 10px 12px 12px 12px);background:var(--pdx-shell-body-bg, transparent);color:var(--pdx-shell-body-color, inherit);font-size:12px}.shell-preview-body.hidden{display:none}\n"] }]
2012
2156
  }], ctorParameters: () => [{ type: undefined, decorators: [{
2013
2157
  type: Optional
2014
2158
  }, {
@@ -4165,37 +4309,37 @@ class ConnectionEditorComponent {
4165
4309
  ];
4166
4310
  i18n = inject(PraxisI18nService);
4167
4311
  hostElement = inject(ElementRef);
4168
- open = input(false, ...(ngDevMode ? [{ debugName: "open" }] : []));
4169
- page = input(undefined, ...(ngDevMode ? [{ debugName: "page" }] : []));
4312
+ open = input(false, ...(ngDevMode ? [{ debugName: "open" }] : /* istanbul ignore next */ []));
4313
+ page = input(undefined, ...(ngDevMode ? [{ debugName: "page" }] : /* istanbul ignore next */ []));
4170
4314
  pageChange = output();
4171
4315
  focusWidget = output();
4172
4316
  openPageSettings = output();
4173
- activeMode = signal('all', ...(ngDevMode ? [{ debugName: "activeMode" }] : []));
4174
- activeFilter = signal('all', ...(ngDevMode ? [{ debugName: "activeFilter" }] : []));
4175
- selectedWidgetId = signal(null, ...(ngDevMode ? [{ debugName: "selectedWidgetId" }] : []));
4176
- selectedLinkId = signal(null, ...(ngDevMode ? [{ debugName: "selectedLinkId" }] : []));
4177
- recentLinkId = signal(null, ...(ngDevMode ? [{ debugName: "recentLinkId" }] : []));
4178
- hoveredLinkId = signal(null, ...(ngDevMode ? [{ debugName: "hoveredLinkId" }] : []));
4179
- expandedNodeId = signal(null, ...(ngDevMode ? [{ debugName: "expandedNodeId" }] : []));
4180
- activeDockTab = signal('links', ...(ngDevMode ? [{ debugName: "activeDockTab" }] : []));
4181
- dockCollapsed = signal(false, ...(ngDevMode ? [{ debugName: "dockCollapsed" }] : []));
4182
- traceEnabled = signal(false, ...(ngDevMode ? [{ debugName: "traceEnabled" }] : []));
4183
- traceStepIndex = signal(0, ...(ngDevMode ? [{ debugName: "traceStepIndex" }] : []));
4184
- traceSourceNodeId = signal(null, ...(ngDevMode ? [{ debugName: "traceSourceNodeId" }] : []));
4185
- selectedPort = signal(null, ...(ngDevMode ? [{ debugName: "selectedPort" }] : []));
4186
- pendingSegmentState = signal(null, ...(ngDevMode ? [{ debugName: "pendingSegmentState" }] : []));
4187
- dragState = signal(null, ...(ngDevMode ? [{ debugName: "dragState" }] : []));
4188
- nodeDragState = signal(null, ...(ngDevMode ? [{ debugName: "nodeDragState" }] : []));
4189
- invalidDropFeedback = signal(null, ...(ngDevMode ? [{ debugName: "invalidDropFeedback" }] : []));
4190
- panState = signal(null, ...(ngDevMode ? [{ debugName: "panState" }] : []));
4191
- minimapPanState = signal(null, ...(ngDevMode ? [{ debugName: "minimapPanState" }] : []));
4192
- rotationState = signal(null, ...(ngDevMode ? [{ debugName: "rotationState" }] : []));
4193
- viewport = signal({ x: 160, y: 4, scale: 0.76 }, ...(ngDevMode ? [{ debugName: "viewport" }] : []));
4194
- portOrder = signal({}, ...(ngDevMode ? [{ debugName: "portOrder" }] : []));
4195
- nodeRotations = signal({}, ...(ngDevMode ? [{ debugName: "nodeRotations" }] : []));
4196
- nodeOffsets = signal({}, ...(ngDevMode ? [{ debugName: "nodeOffsets" }] : []));
4197
- undoStack = signal([], ...(ngDevMode ? [{ debugName: "undoStack" }] : []));
4198
- redoStack = signal([], ...(ngDevMode ? [{ debugName: "redoStack" }] : []));
4317
+ activeMode = signal('all', ...(ngDevMode ? [{ debugName: "activeMode" }] : /* istanbul ignore next */ []));
4318
+ activeFilter = signal('all', ...(ngDevMode ? [{ debugName: "activeFilter" }] : /* istanbul ignore next */ []));
4319
+ selectedWidgetId = signal(null, ...(ngDevMode ? [{ debugName: "selectedWidgetId" }] : /* istanbul ignore next */ []));
4320
+ selectedLinkId = signal(null, ...(ngDevMode ? [{ debugName: "selectedLinkId" }] : /* istanbul ignore next */ []));
4321
+ recentLinkId = signal(null, ...(ngDevMode ? [{ debugName: "recentLinkId" }] : /* istanbul ignore next */ []));
4322
+ hoveredLinkId = signal(null, ...(ngDevMode ? [{ debugName: "hoveredLinkId" }] : /* istanbul ignore next */ []));
4323
+ expandedNodeId = signal(null, ...(ngDevMode ? [{ debugName: "expandedNodeId" }] : /* istanbul ignore next */ []));
4324
+ activeDockTab = signal('links', ...(ngDevMode ? [{ debugName: "activeDockTab" }] : /* istanbul ignore next */ []));
4325
+ dockCollapsed = signal(false, ...(ngDevMode ? [{ debugName: "dockCollapsed" }] : /* istanbul ignore next */ []));
4326
+ traceEnabled = signal(false, ...(ngDevMode ? [{ debugName: "traceEnabled" }] : /* istanbul ignore next */ []));
4327
+ traceStepIndex = signal(0, ...(ngDevMode ? [{ debugName: "traceStepIndex" }] : /* istanbul ignore next */ []));
4328
+ traceSourceNodeId = signal(null, ...(ngDevMode ? [{ debugName: "traceSourceNodeId" }] : /* istanbul ignore next */ []));
4329
+ selectedPort = signal(null, ...(ngDevMode ? [{ debugName: "selectedPort" }] : /* istanbul ignore next */ []));
4330
+ pendingSegmentState = signal(null, ...(ngDevMode ? [{ debugName: "pendingSegmentState" }] : /* istanbul ignore next */ []));
4331
+ dragState = signal(null, ...(ngDevMode ? [{ debugName: "dragState" }] : /* istanbul ignore next */ []));
4332
+ nodeDragState = signal(null, ...(ngDevMode ? [{ debugName: "nodeDragState" }] : /* istanbul ignore next */ []));
4333
+ invalidDropFeedback = signal(null, ...(ngDevMode ? [{ debugName: "invalidDropFeedback" }] : /* istanbul ignore next */ []));
4334
+ panState = signal(null, ...(ngDevMode ? [{ debugName: "panState" }] : /* istanbul ignore next */ []));
4335
+ minimapPanState = signal(null, ...(ngDevMode ? [{ debugName: "minimapPanState" }] : /* istanbul ignore next */ []));
4336
+ rotationState = signal(null, ...(ngDevMode ? [{ debugName: "rotationState" }] : /* istanbul ignore next */ []));
4337
+ viewport = signal({ x: 160, y: 4, scale: 0.76 }, ...(ngDevMode ? [{ debugName: "viewport" }] : /* istanbul ignore next */ []));
4338
+ portOrder = signal({}, ...(ngDevMode ? [{ debugName: "portOrder" }] : /* istanbul ignore next */ []));
4339
+ nodeRotations = signal({}, ...(ngDevMode ? [{ debugName: "nodeRotations" }] : /* istanbul ignore next */ []));
4340
+ nodeOffsets = signal({}, ...(ngDevMode ? [{ debugName: "nodeOffsets" }] : /* istanbul ignore next */ []));
4341
+ undoStack = signal([], ...(ngDevMode ? [{ debugName: "undoStack" }] : /* istanbul ignore next */ []));
4342
+ redoStack = signal([], ...(ngDevMode ? [{ debugName: "redoStack" }] : /* istanbul ignore next */ []));
4199
4343
  invalidDropFeedbackId = 0;
4200
4344
  invalidDropFeedbackTimer = null;
4201
4345
  recentLinkFeedbackTimer = null;
@@ -4205,7 +4349,7 @@ class ConnectionEditorComponent {
4205
4349
  if (!this.open())
4206
4350
  return;
4207
4351
  window.setTimeout(() => this.resetViewport(), 0);
4208
- }, ...(ngDevMode ? [{ debugName: "fitViewportOnOpen" }] : []));
4352
+ }, ...(ngDevMode ? [{ debugName: "fitViewportOnOpen" }] : /* istanbul ignore next */ []));
4209
4353
  filters = [
4210
4354
  { id: 'all', label: this.tx('connections.filters.all', 'All') },
4211
4355
  { id: 'condition', label: this.tx('connections.filters.condition', 'Condition') },
@@ -4226,8 +4370,8 @@ class ConnectionEditorComponent {
4226
4370
  { id: 'derived', label: this.tx('connections.dock.derived', 'Derived'), glyph: '⌘' },
4227
4371
  { id: 'export', label: this.tx('connections.dock.export', 'Export'), glyph: '⇩' },
4228
4372
  ];
4229
- model = computed(() => buildConnectionsViewerModel(this.page()), ...(ngDevMode ? [{ debugName: "model" }] : []));
4230
- selectedNode = computed(() => this.model().nodes.find((node) => node.widgetId === this.selectedWidgetId()) ?? null, ...(ngDevMode ? [{ debugName: "selectedNode" }] : []));
4373
+ model = computed(() => buildConnectionsViewerModel(this.page()), ...(ngDevMode ? [{ debugName: "model" }] : /* istanbul ignore next */ []));
4374
+ selectedNode = computed(() => this.model().nodes.find((node) => node.widgetId === this.selectedWidgetId()) ?? null, ...(ngDevMode ? [{ debugName: "selectedNode" }] : /* istanbul ignore next */ []));
4231
4375
  visibleEdges = computed(() => {
4232
4376
  const widgetId = this.selectedWidgetId();
4233
4377
  const filter = this.activeFilter();
@@ -4249,21 +4393,21 @@ class ConnectionEditorComponent {
4249
4393
  edges = edges.filter((edge) => this.edgeHasDiagnostics(edge));
4250
4394
  }
4251
4395
  return edges;
4252
- }, ...(ngDevMode ? [{ debugName: "visibleEdges" }] : []));
4253
- selectedEdge = computed(() => this.model().edges.find((edge) => edge.id === this.selectedLinkId()) ?? null, ...(ngDevMode ? [{ debugName: "selectedEdge" }] : []));
4396
+ }, ...(ngDevMode ? [{ debugName: "visibleEdges" }] : /* istanbul ignore next */ []));
4397
+ selectedEdge = computed(() => this.model().edges.find((edge) => edge.id === this.selectedLinkId()) ?? null, ...(ngDevMode ? [{ debugName: "selectedEdge" }] : /* istanbul ignore next */ []));
4254
4398
  editorGraph = computed(() => deriveConnectionEditorGraph(this.page(), {
4255
4399
  stateNodeTitle: this.tx('connections.editor.stateNode', 'Page state'),
4256
- }), ...(ngDevMode ? [{ debugName: "editorGraph" }] : []));
4257
- editorNodes = computed(() => autoArrangeConnectionEditorGraph(this.editorGraph()).nodes.map((node) => this.applyNodeOffset(this.applyNodeRotation(applyConnectionEditorPortOrder(node, this.portOrder())))), ...(ngDevMode ? [{ debugName: "editorNodes" }] : []));
4258
- navigationBounds = computed(() => this.connectionEditorNavigationBounds(), ...(ngDevMode ? [{ debugName: "navigationBounds" }] : []));
4400
+ }), ...(ngDevMode ? [{ debugName: "editorGraph" }] : /* istanbul ignore next */ []));
4401
+ editorNodes = computed(() => autoArrangeConnectionEditorGraph(this.editorGraph()).nodes.map((node) => this.applyNodeOffset(this.applyNodeRotation(applyConnectionEditorPortOrder(node, this.portOrder())))), ...(ngDevMode ? [{ debugName: "editorNodes" }] : /* istanbul ignore next */ []));
4402
+ navigationBounds = computed(() => this.connectionEditorNavigationBounds(), ...(ngDevMode ? [{ debugName: "navigationBounds" }] : /* istanbul ignore next */ []));
4259
4403
  minimapViewBox = computed(() => {
4260
4404
  const bounds = this.navigationBounds();
4261
4405
  return `${bounds.x} ${bounds.y} ${bounds.width} ${bounds.height}`;
4262
- }, ...(ngDevMode ? [{ debugName: "minimapViewBox" }] : []));
4263
- editorConnections = computed(() => this.editorGraph().connections, ...(ngDevMode ? [{ debugName: "editorConnections" }] : []));
4264
- canvasEditorConnections = computed(() => this.editorConnections(), ...(ngDevMode ? [{ debugName: "canvasEditorConnections" }] : []));
4265
- visibleEditorConnections = computed(() => this.editorConnections().filter((connection) => this.connectionMatchesMode(connection)), ...(ngDevMode ? [{ debugName: "visibleEditorConnections" }] : []));
4266
- modeMatchedConnectionIds = computed(() => new Set(this.editorConnections().filter((connection) => this.connectionMatchesMode(connection)).map((connection) => connection.id)), ...(ngDevMode ? [{ debugName: "modeMatchedConnectionIds" }] : []));
4406
+ }, ...(ngDevMode ? [{ debugName: "minimapViewBox" }] : /* istanbul ignore next */ []));
4407
+ editorConnections = computed(() => this.editorGraph().connections, ...(ngDevMode ? [{ debugName: "editorConnections" }] : /* istanbul ignore next */ []));
4408
+ canvasEditorConnections = computed(() => this.editorConnections(), ...(ngDevMode ? [{ debugName: "canvasEditorConnections" }] : /* istanbul ignore next */ []));
4409
+ visibleEditorConnections = computed(() => this.editorConnections().filter((connection) => this.connectionMatchesMode(connection)), ...(ngDevMode ? [{ debugName: "visibleEditorConnections" }] : /* istanbul ignore next */ []));
4410
+ modeMatchedConnectionIds = computed(() => new Set(this.editorConnections().filter((connection) => this.connectionMatchesMode(connection)).map((connection) => connection.id)), ...(ngDevMode ? [{ debugName: "modeMatchedConnectionIds" }] : /* istanbul ignore next */ []));
4267
4411
  modeMatchedNodeIds = computed(() => {
4268
4412
  const ids = new Set();
4269
4413
  if (!this.hasModeFocus())
@@ -4277,7 +4421,7 @@ class ConnectionEditorComponent {
4277
4421
  ids.add(connection.toNode);
4278
4422
  }
4279
4423
  return ids;
4280
- }, ...(ngDevMode ? [{ debugName: "modeMatchedNodeIds" }] : []));
4424
+ }, ...(ngDevMode ? [{ debugName: "modeMatchedNodeIds" }] : /* istanbul ignore next */ []));
4281
4425
  modeMatchedPortIds = computed(() => {
4282
4426
  const ids = new Set();
4283
4427
  if (!this.hasModeFocus())
@@ -4291,8 +4435,8 @@ class ConnectionEditorComponent {
4291
4435
  ids.add(connection.toPort.id);
4292
4436
  }
4293
4437
  return ids;
4294
- }, ...(ngDevMode ? [{ debugName: "modeMatchedPortIds" }] : []));
4295
- smartSuggestions = computed(() => deriveConnectionEditorSuggestions(this.editorGraph(), 5), ...(ngDevMode ? [{ debugName: "smartSuggestions" }] : []));
4438
+ }, ...(ngDevMode ? [{ debugName: "modeMatchedPortIds" }] : /* istanbul ignore next */ []));
4439
+ smartSuggestions = computed(() => deriveConnectionEditorSuggestions(this.editorGraph(), 5), ...(ngDevMode ? [{ debugName: "smartSuggestions" }] : /* istanbul ignore next */ []));
4296
4440
  traceSteps = computed(() => {
4297
4441
  const selectedLinkId = this.selectedLinkId();
4298
4442
  if (selectedLinkId)
@@ -4304,27 +4448,27 @@ class ConnectionEditorComponent {
4304
4448
  ...this.editorGraph(),
4305
4449
  connections: this.editorGraph().connections.filter((connection) => connection.fromNode === sourceNodeId || connection.toNode === sourceNodeId),
4306
4450
  }, null);
4307
- }, ...(ngDevMode ? [{ debugName: "traceSteps" }] : []));
4451
+ }, ...(ngDevMode ? [{ debugName: "traceSteps" }] : /* istanbul ignore next */ []));
4308
4452
  activeTraceStepIndex = computed(() => {
4309
4453
  const total = this.traceSteps().length;
4310
4454
  if (!total)
4311
4455
  return 0;
4312
4456
  return this.clamp(this.traceStepIndex(), 0, total - 1);
4313
- }, ...(ngDevMode ? [{ debugName: "activeTraceStepIndex" }] : []));
4314
- traceActiveStep = computed(() => this.traceSteps()[this.activeTraceStepIndex()] ?? null, ...(ngDevMode ? [{ debugName: "traceActiveStep" }] : []));
4315
- tracedConnectionIds = computed(() => new Set([this.traceActiveStep()?.connectionId].filter(Boolean)), ...(ngDevMode ? [{ debugName: "tracedConnectionIds" }] : []));
4457
+ }, ...(ngDevMode ? [{ debugName: "activeTraceStepIndex" }] : /* istanbul ignore next */ []));
4458
+ traceActiveStep = computed(() => this.traceSteps()[this.activeTraceStepIndex()] ?? null, ...(ngDevMode ? [{ debugName: "traceActiveStep" }] : /* istanbul ignore next */ []));
4459
+ tracedConnectionIds = computed(() => new Set([this.traceActiveStep()?.connectionId].filter(Boolean)), ...(ngDevMode ? [{ debugName: "tracedConnectionIds" }] : /* istanbul ignore next */ []));
4316
4460
  traceProgressPercent = computed(() => {
4317
4461
  const total = this.traceSteps().length;
4318
4462
  if (!total)
4319
4463
  return 0;
4320
4464
  return Math.round(((this.activeTraceStepIndex() + 1) / total) * 100);
4321
- }, ...(ngDevMode ? [{ debugName: "traceProgressPercent" }] : []));
4465
+ }, ...(ngDevMode ? [{ debugName: "traceProgressPercent" }] : /* istanbul ignore next */ []));
4322
4466
  traceProgressLabel = computed(() => {
4323
4467
  const total = this.traceSteps().length;
4324
4468
  if (!total)
4325
4469
  return '0/0';
4326
4470
  return `${this.activeTraceStepIndex() + 1}/${total}`;
4327
- }, ...(ngDevMode ? [{ debugName: "traceProgressLabel" }] : []));
4471
+ }, ...(ngDevMode ? [{ debugName: "traceProgressLabel" }] : /* istanbul ignore next */ []));
4328
4472
  traceSourceNodeIds = computed(() => {
4329
4473
  if (!this.traceEnabled())
4330
4474
  return new Set();
@@ -4332,7 +4476,7 @@ class ConnectionEditorComponent {
4332
4476
  return new Set(this.editorConnections()
4333
4477
  .filter((connection) => traced.has(connection.id) && connection.fromNode)
4334
4478
  .map((connection) => connection.fromNode));
4335
- }, ...(ngDevMode ? [{ debugName: "traceSourceNodeIds" }] : []));
4479
+ }, ...(ngDevMode ? [{ debugName: "traceSourceNodeIds" }] : /* istanbul ignore next */ []));
4336
4480
  traceReactingNodeIds = computed(() => {
4337
4481
  if (!this.traceEnabled())
4338
4482
  return new Set();
@@ -4340,51 +4484,51 @@ class ConnectionEditorComponent {
4340
4484
  return new Set(this.editorConnections()
4341
4485
  .filter((connection) => traced.has(connection.id) && connection.toNode)
4342
4486
  .map((connection) => connection.toNode));
4343
- }, ...(ngDevMode ? [{ debugName: "traceReactingNodeIds" }] : []));
4487
+ }, ...(ngDevMode ? [{ debugName: "traceReactingNodeIds" }] : /* istanbul ignore next */ []));
4344
4488
  focusedConnectionNodeIds = computed(() => {
4345
4489
  const connection = this.selectedConnection();
4346
4490
  return new Set([connection?.fromNode, connection?.toNode].filter(Boolean));
4347
- }, ...(ngDevMode ? [{ debugName: "focusedConnectionNodeIds" }] : []));
4491
+ }, ...(ngDevMode ? [{ debugName: "focusedConnectionNodeIds" }] : /* istanbul ignore next */ []));
4348
4492
  focusedConnectionPortIds = computed(() => {
4349
4493
  const connection = this.selectedConnection();
4350
4494
  return new Set([connection?.fromPort?.id, connection?.toPort?.id].filter(Boolean));
4351
- }, ...(ngDevMode ? [{ debugName: "focusedConnectionPortIds" }] : []));
4352
- diagnosticConnectionIds = computed(() => new Set(this.editorConnections().filter((connection) => connection.diagnostics.length).map((connection) => connection.id)), ...(ngDevMode ? [{ debugName: "diagnosticConnectionIds" }] : []));
4495
+ }, ...(ngDevMode ? [{ debugName: "focusedConnectionPortIds" }] : /* istanbul ignore next */ []));
4496
+ diagnosticConnectionIds = computed(() => new Set(this.editorConnections().filter((connection) => connection.diagnostics.length).map((connection) => connection.id)), ...(ngDevMode ? [{ debugName: "diagnosticConnectionIds" }] : /* istanbul ignore next */ []));
4353
4497
  diagnosticLinkCount = computed(() => {
4354
4498
  const ids = new Set(this.model().edges.filter((edge) => edge.hasDiagnostics).map((edge) => edge.id));
4355
4499
  for (const id of this.diagnosticConnectionIds())
4356
4500
  ids.add(id);
4357
4501
  return ids.size;
4358
- }, ...(ngDevMode ? [{ debugName: "diagnosticLinkCount" }] : []));
4359
- selectedEditorNode = computed(() => this.editorNodes().find((node) => node.id === this.selectedWidgetId()) ?? null, ...(ngDevMode ? [{ debugName: "selectedEditorNode" }] : []));
4360
- selectedConnection = computed(() => this.editorConnections().find((connection) => connection.id === this.selectedLinkId()) ?? null, ...(ngDevMode ? [{ debugName: "selectedConnection" }] : []));
4502
+ }, ...(ngDevMode ? [{ debugName: "diagnosticLinkCount" }] : /* istanbul ignore next */ []));
4503
+ selectedEditorNode = computed(() => this.editorNodes().find((node) => node.id === this.selectedWidgetId()) ?? null, ...(ngDevMode ? [{ debugName: "selectedEditorNode" }] : /* istanbul ignore next */ []));
4504
+ selectedConnection = computed(() => this.editorConnections().find((connection) => connection.id === this.selectedLinkId()) ?? null, ...(ngDevMode ? [{ debugName: "selectedConnection" }] : /* istanbul ignore next */ []));
4361
4505
  connectionTooltip = computed(() => this.selectedConnection()
4362
4506
  ?? this.visibleEditorConnections().find((connection) => connection.id === this.hoveredLinkId())
4363
- ?? null, ...(ngDevMode ? [{ debugName: "connectionTooltip" }] : []));
4507
+ ?? null, ...(ngDevMode ? [{ debugName: "connectionTooltip" }] : /* istanbul ignore next */ []));
4364
4508
  canvasInteractionActive = computed(() => !!(this.pendingSegmentState()
4365
4509
  || this.dragState()
4366
4510
  || this.nodeDragState()
4367
4511
  || this.panState()
4368
4512
  || this.minimapPanState()
4369
- || this.rotationState()), ...(ngDevMode ? [{ debugName: "canvasInteractionActive" }] : []));
4370
- visibleConnectionTooltip = computed(() => (this.canvasInteractionActive() ? null : this.connectionTooltip()), ...(ngDevMode ? [{ debugName: "visibleConnectionTooltip" }] : []));
4371
- visibleExpandedNodeId = computed(() => (this.canvasInteractionActive() ? null : this.expandedNodeId()), ...(ngDevMode ? [{ debugName: "visibleExpandedNodeId" }] : []));
4372
- canUndo = computed(() => this.undoStack().length > 0, ...(ngDevMode ? [{ debugName: "canUndo" }] : []));
4373
- canRedo = computed(() => this.redoStack().length > 0, ...(ngDevMode ? [{ debugName: "canRedo" }] : []));
4374
- hasVisualPortOrder = computed(() => Object.keys(this.portOrder()).length > 0, ...(ngDevMode ? [{ debugName: "hasVisualPortOrder" }] : []));
4513
+ || this.rotationState()), ...(ngDevMode ? [{ debugName: "canvasInteractionActive" }] : /* istanbul ignore next */ []));
4514
+ visibleConnectionTooltip = computed(() => (this.canvasInteractionActive() ? null : this.connectionTooltip()), ...(ngDevMode ? [{ debugName: "visibleConnectionTooltip" }] : /* istanbul ignore next */ []));
4515
+ visibleExpandedNodeId = computed(() => (this.canvasInteractionActive() ? null : this.expandedNodeId()), ...(ngDevMode ? [{ debugName: "visibleExpandedNodeId" }] : /* istanbul ignore next */ []));
4516
+ canUndo = computed(() => this.undoStack().length > 0, ...(ngDevMode ? [{ debugName: "canUndo" }] : /* istanbul ignore next */ []));
4517
+ canRedo = computed(() => this.redoStack().length > 0, ...(ngDevMode ? [{ debugName: "canRedo" }] : /* istanbul ignore next */ []));
4518
+ hasVisualPortOrder = computed(() => Object.keys(this.portOrder()).length > 0, ...(ngDevMode ? [{ debugName: "hasVisualPortOrder" }] : /* istanbul ignore next */ []));
4375
4519
  dragPreviewPath = computed(() => {
4376
4520
  const drag = this.dragState();
4377
4521
  if (!drag)
4378
4522
  return '';
4379
4523
  const target = drag.candidate ? this.anchorForPort(drag.candidate) : null;
4380
4524
  return this.previewWirePath(drag.source, target ?? drag.pointer, !!target);
4381
- }, ...(ngDevMode ? [{ debugName: "dragPreviewPath" }] : []));
4525
+ }, ...(ngDevMode ? [{ debugName: "dragPreviewPath" }] : /* istanbul ignore next */ []));
4382
4526
  dragTargetPoint = computed(() => {
4383
4527
  const drag = this.dragState();
4384
4528
  if (!drag)
4385
4529
  return { x: 0, y: 0 };
4386
4530
  return drag.candidate ? this.anchorForPort(drag.candidate) ?? drag.pointer : drag.pointer;
4387
- }, ...(ngDevMode ? [{ debugName: "dragTargetPoint" }] : []));
4531
+ }, ...(ngDevMode ? [{ debugName: "dragTargetPoint" }] : /* istanbul ignore next */ []));
4388
4532
  dragTipPosition = computed(() => {
4389
4533
  const point = this.dragTargetPoint();
4390
4534
  const viewport = this.viewport();
@@ -4393,7 +4537,7 @@ class ConnectionEditorComponent {
4393
4537
  x: this.clamp((point.x * viewport.scale) + viewport.x + 18, 14, Math.max(14, stage.width - 344)),
4394
4538
  y: this.clamp((point.y * viewport.scale) + viewport.y - 72, 14, Math.max(14, stage.height - 92)),
4395
4539
  };
4396
- }, ...(ngDevMode ? [{ debugName: "dragTipPosition" }] : []));
4540
+ }, ...(ngDevMode ? [{ debugName: "dragTipPosition" }] : /* istanbul ignore next */ []));
4397
4541
  invalidDropPosition = computed(() => {
4398
4542
  const feedback = this.invalidDropFeedback();
4399
4543
  const viewport = this.viewport();
@@ -4403,7 +4547,7 @@ class ConnectionEditorComponent {
4403
4547
  x: (feedback.point.x * viewport.scale) + viewport.x,
4404
4548
  y: (feedback.point.y * viewport.scale) + viewport.y,
4405
4549
  };
4406
- }, ...(ngDevMode ? [{ debugName: "invalidDropPosition" }] : []));
4550
+ }, ...(ngDevMode ? [{ debugName: "invalidDropPosition" }] : /* istanbul ignore next */ []));
4407
4551
  invalidDropTipPosition = computed(() => {
4408
4552
  const point = this.invalidDropFeedback()?.point ?? { x: 0, y: 0 };
4409
4553
  const viewport = this.viewport();
@@ -4412,7 +4556,7 @@ class ConnectionEditorComponent {
4412
4556
  x: this.clamp((point.x * viewport.scale) + viewport.x + 18, 14, Math.max(14, stage.width - 344)),
4413
4557
  y: this.clamp((point.y * viewport.scale) + viewport.y - 72, 14, Math.max(14, stage.height - 92)),
4414
4558
  };
4415
- }, ...(ngDevMode ? [{ debugName: "invalidDropTipPosition" }] : []));
4559
+ }, ...(ngDevMode ? [{ debugName: "invalidDropTipPosition" }] : /* istanbul ignore next */ []));
4416
4560
  dragEndpointText = computed(() => {
4417
4561
  const drag = this.dragState();
4418
4562
  if (!drag)
@@ -4422,7 +4566,7 @@ class ConnectionEditorComponent {
4422
4566
  ? this.portQualifiedLabel(drag.candidate)
4423
4567
  : this.tx('connections.editor.dropHint', 'drop on a compatible target');
4424
4568
  return `${source} -> ${target}`;
4425
- }, ...(ngDevMode ? [{ debugName: "dragEndpointText" }] : []));
4569
+ }, ...(ngDevMode ? [{ debugName: "dragEndpointText" }] : /* istanbul ignore next */ []));
4426
4570
  invalidDropEndpointText = computed(() => {
4427
4571
  const feedback = this.invalidDropFeedback();
4428
4572
  if (!feedback)
@@ -4431,25 +4575,25 @@ class ConnectionEditorComponent {
4431
4575
  ? this.portQualifiedLabel(feedback.target)
4432
4576
  : this.tx('connections.editor.invalidDropCanvasTarget', 'no target');
4433
4577
  return `${this.portQualifiedLabel(feedback.source)} -> ${target}`;
4434
- }, ...(ngDevMode ? [{ debugName: "invalidDropEndpointText" }] : []));
4578
+ }, ...(ngDevMode ? [{ debugName: "invalidDropEndpointText" }] : /* istanbul ignore next */ []));
4435
4579
  dragStatusText = computed(() => {
4436
4580
  const drag = this.dragState();
4437
4581
  if (!drag?.candidate) {
4438
4582
  return this.tx('connections.editor.searchingHint', 'Hover a compatible segment');
4439
4583
  }
4440
4584
  return this.tx('connections.editor.releaseHint', 'Release to connect');
4441
- }, ...(ngDevMode ? [{ debugName: "dragStatusText" }] : []));
4585
+ }, ...(ngDevMode ? [{ debugName: "dragStatusText" }] : /* istanbul ignore next */ []));
4442
4586
  invalidDropStatusText = computed(() => {
4443
4587
  const target = this.invalidDropFeedback()?.target;
4444
4588
  if (target) {
4445
4589
  return this.tx('connections.editor.invalidDropIncompatibleHint', 'These segments cannot be connected');
4446
4590
  }
4447
4591
  return this.tx('connections.editor.invalidDropCanvasHint', 'Release on a compatible input or state segment');
4448
- }, ...(ngDevMode ? [{ debugName: "invalidDropStatusText" }] : []));
4592
+ }, ...(ngDevMode ? [{ debugName: "invalidDropStatusText" }] : /* istanbul ignore next */ []));
4449
4593
  viewportTransform = computed(() => {
4450
4594
  const viewport = this.viewport();
4451
4595
  return `translate(${viewport.x.toFixed(2)}px, ${viewport.y.toFixed(2)}px) scale(${viewport.scale.toFixed(3)})`;
4452
- }, ...(ngDevMode ? [{ debugName: "viewportTransform" }] : []));
4596
+ }, ...(ngDevMode ? [{ debugName: "viewportTransform" }] : /* istanbul ignore next */ []));
4453
4597
  minimapViewport = computed(() => {
4454
4598
  const viewport = this.viewport();
4455
4599
  const stage = this.stageClientSize();
@@ -4462,7 +4606,7 @@ class ConnectionEditorComponent {
4462
4606
  width,
4463
4607
  height,
4464
4608
  };
4465
- }, ...(ngDevMode ? [{ debugName: "minimapViewport" }] : []));
4609
+ }, ...(ngDevMode ? [{ debugName: "minimapViewport" }] : /* istanbul ignore next */ []));
4466
4610
  selectNode(nodeId) {
4467
4611
  if (this.suppressedNodeClickId === nodeId) {
4468
4612
  this.suppressedNodeClickId = null;
@@ -5894,8 +6038,8 @@ class ConnectionEditorComponent {
5894
6038
  clamp(value, min, max) {
5895
6039
  return Math.min(max, Math.max(min, value));
5896
6040
  }
5897
- static ɵfac = i0.ɵɵngDeclareFactory({ minVersion: "12.0.0", version: "20.3.17", ngImport: i0, type: ConnectionEditorComponent, deps: [], target: i0.ɵɵFactoryTarget.Component });
5898
- static ɵcmp = i0.ɵɵngDeclareComponent({ minVersion: "17.0.0", version: "20.3.17", type: ConnectionEditorComponent, isStandalone: true, selector: "praxis-connection-editor", inputs: { open: { classPropertyName: "open", publicName: "open", isSignal: true, isRequired: false, transformFunction: null }, page: { classPropertyName: "page", publicName: "page", isSignal: true, isRequired: false, transformFunction: null } }, outputs: { pageChange: "pageChange", focusWidget: "focusWidget", openPageSettings: "openPageSettings" }, host: { listeners: { "document:pointerdown": "closeFloatingPanelsOnOutsidePointerDown($event)", "document:pointermove": "updatePendingSegment($event); updateDrag($event); updateNodeDrag($event); updatePan($event); updateMinimapPan($event); updateRotation($event)", "document:pointerup": "cancelPendingSegment(); cancelDrag($event); stopNodeDrag(); stopPan(); stopMinimapPan(); stopRotation()", "document:keydown": "handleEditorKeydown($event)" } }, providers: [providePraxisPageBuilderI18n()], ngImport: i0, template: `
6041
+ static ɵfac = i0.ɵɵngDeclareFactory({ minVersion: "12.0.0", version: "21.2.14", ngImport: i0, type: ConnectionEditorComponent, deps: [], target: i0.ɵɵFactoryTarget.Component });
6042
+ static ɵcmp = i0.ɵɵngDeclareComponent({ minVersion: "17.0.0", version: "21.2.14", type: ConnectionEditorComponent, isStandalone: true, selector: "praxis-connection-editor", inputs: { open: { classPropertyName: "open", publicName: "open", isSignal: true, isRequired: false, transformFunction: null }, page: { classPropertyName: "page", publicName: "page", isSignal: true, isRequired: false, transformFunction: null } }, outputs: { pageChange: "pageChange", focusWidget: "focusWidget", openPageSettings: "openPageSettings" }, host: { listeners: { "document:pointerdown": "closeFloatingPanelsOnOutsidePointerDown($event)", "document:pointermove": "updatePendingSegment($event); updateDrag($event); updateNodeDrag($event); updatePan($event); updateMinimapPan($event); updateRotation($event)", "document:pointerup": "cancelPendingSegment(); cancelDrag($event); stopNodeDrag(); stopPan(); stopMinimapPan(); stopRotation()", "document:keydown": "handleEditorKeydown($event)" } }, providers: [providePraxisPageBuilderI18n()], ngImport: i0, template: `
5899
6043
  @if (open()) {
5900
6044
  <aside
5901
6045
  class="connection-editor"
@@ -7213,9 +7357,9 @@ class ConnectionEditorComponent {
7213
7357
  </section>
7214
7358
  </aside>
7215
7359
  }
7216
- `, isInline: true, styles: [":host{position:fixed;inset:0;z-index:1000;pointer-events:none}.connection-editor{--pce-fg: var(--md-sys-color-on-surface, #dce6f4);--pce-strong: var(--md-sys-color-on-surface, #f8fafc);--pce-muted: var(--md-sys-color-on-surface-variant, #94a3b8);--pce-primary: var(--md-sys-color-primary, #19c8e8);--pce-secondary: var(--md-sys-color-secondary, #b46cff);--pce-tertiary: var(--md-sys-color-tertiary, #ff9f2f);--pce-success: var(--md-sys-color-tertiary, #10b981);--pce-warning: var(--md-sys-color-error, #ff9f2f);--pce-error: var(--md-sys-color-error, #ef4444);--pce-surface-base: color-mix(in srgb, var(--md-sys-color-surface, #07111f) 80%, #020617);--pce-surface: color-mix(in srgb, var(--md-sys-color-surface-container, #08101d) 78%, transparent);--pce-surface-strong: color-mix(in srgb, var(--md-sys-color-surface-container-high, #0f172a) 88%, transparent);--pce-surface-soft: color-mix(in srgb, var(--md-sys-color-surface-container-low, #080d18) 64%, transparent);--pce-outline: color-mix(in srgb, var(--md-sys-color-outline-variant, #899ab7) 46%, transparent);--pce-outline-strong: color-mix(in srgb, var(--md-sys-color-outline, #94a3b8) 58%, transparent);--pce-grid: color-mix(in srgb, var(--md-sys-color-outline-variant, #7d8fa9) 24%, transparent);--pce-glass-highlight: color-mix(in srgb, var(--md-sys-color-on-surface, #ffffff) 8%, transparent);--pce-shadow: color-mix(in srgb, #000 56%, transparent);--pce-shadow-soft: color-mix(in srgb, #000 30%, transparent);--pce-stage-bg: color-mix(in srgb, var(--md-sys-color-surface-container-lowest, #040a13) 42%, transparent);--pce-dock-bg: color-mix(in srgb, var(--md-sys-color-surface-container-high, #050912) 94%, transparent);position:absolute;inset:12px;height:calc(100vh - 24px);box-sizing:border-box;overflow:hidden;padding:16px;border-radius:18px;color:var(--pce-fg);background:radial-gradient(circle at 72% 20%,color-mix(in srgb,var(--pce-secondary) 16%,transparent),transparent 28%),radial-gradient(circle at 26% 74%,color-mix(in srgb,var(--pce-primary) 10%,transparent),transparent 34%),radial-gradient(circle at 48% 52%,color-mix(in srgb,var(--pce-tertiary) 5%,transparent),transparent 35%),linear-gradient(var(--pce-grid) 1px,transparent 1px),linear-gradient(90deg,var(--pce-grid) 1px,transparent 1px),var(--pce-surface-base);background-size:auto,auto,auto,38px 38px,38px 38px,auto;border:1px solid var(--pce-outline);box-shadow:0 28px 90px var(--pce-shadow);pointer-events:auto;display:grid;grid-template-columns:minmax(0,1fr) minmax(300px,380px);grid-template-rows:auto minmax(0,1fr) auto minmax(48px,140px);gap:14px}:host-context(.theme-light) .connection-editor{--pce-surface-base: color-mix(in srgb, var(--md-sys-color-surface, #ffffff) 94%, var(--md-sys-color-primary, #2563eb) 6%);--pce-surface: color-mix(in srgb, var(--md-sys-color-surface-container, #f8fafc) 82%, transparent);--pce-surface-strong: color-mix(in srgb, var(--md-sys-color-surface-container-high, #eef2ff) 88%, transparent);--pce-surface-soft: color-mix(in srgb, var(--md-sys-color-surface-container-low, #f8fafc) 70%, transparent);--pce-outline: color-mix(in srgb, var(--md-sys-color-outline-variant, #cbd5e1) 68%, transparent);--pce-outline-strong: color-mix(in srgb, var(--md-sys-color-outline, #64748b) 62%, transparent);--pce-grid: color-mix(in srgb, var(--md-sys-color-outline-variant, #cbd5e1) 34%, transparent);--pce-glass-highlight: color-mix(in srgb, #fff 64%, transparent);--pce-shadow: color-mix(in srgb, var(--md-sys-color-shadow, #64748b) 22%, transparent);--pce-shadow-soft: color-mix(in srgb, var(--md-sys-color-shadow, #64748b) 14%, transparent);--pce-stage-bg: color-mix(in srgb, var(--md-sys-color-surface-container-lowest, #ffffff) 58%, transparent);--pce-dock-bg: color-mix(in srgb, var(--md-sys-color-surface-container, #f8fafc) 92%, transparent)}.connection-editor__header{grid-column:1 / -1;display:flex;align-items:center;justify-content:space-between;gap:16px;min-height:42px;padding:8px 14px;border-radius:999px;background:var(--pce-surface);border:1px solid var(--pce-outline);box-shadow:inset 0 1px var(--pce-glass-highlight);-webkit-backdrop-filter:blur(18px);backdrop-filter:blur(18px)}.connection-editor__mode-frame{position:relative;min-width:0}.connection-editor__mode-shell{display:inline-flex;align-items:center;gap:4px;min-width:0;padding:4px;border-radius:999px;border:1px solid var(--pce-outline);background:linear-gradient(180deg,var(--pce-surface-strong),var(--pce-surface));box-shadow:inset 0 1px var(--pce-glass-highlight),0 10px 26px var(--pce-shadow-soft);scrollbar-width:none}.connection-editor__mode-shell::-webkit-scrollbar{display:none}.connection-editor__mode{min-height:30px;display:inline-flex;align-items:center;gap:7px;padding:0 12px;border:1px solid transparent;border-radius:999px;background:transparent;color:var(--pce-muted);cursor:pointer;font-size:.76rem;font-weight:800;white-space:nowrap;transition:background .16s ease,border-color .16s ease,color .16s ease,box-shadow .16s ease}.connection-editor__mode:hover,.connection-editor__mode--active{color:var(--pce-strong);border-color:color-mix(in srgb,var(--pce-primary) 28%,transparent);background:color-mix(in srgb,var(--pce-surface-strong) 82%,transparent);box-shadow:0 0 18px color-mix(in srgb,var(--pce-primary) 12%,transparent)}.connection-editor__mode-glyph{color:var(--pce-muted);font-family:ui-monospace,SFMono-Regular,Menlo,Monaco,Consolas,Liberation Mono,monospace;font-size:.72rem;font-weight:900}.connection-editor__mode--active .connection-editor__mode-glyph{color:var(--pce-primary)}.connection-editor__mode-dot{width:6px;height:6px;border-radius:999px;background:var(--pce-success);box-shadow:0 0 12px color-mix(in srgb,var(--pce-success) 70%,transparent)}.connection-editor__status-pill{display:inline-flex;align-items:center;gap:8px;min-height:24px;padding:0 12px;border-radius:999px;border:1px solid color-mix(in srgb,var(--pce-primary) 36%,transparent);background:var(--pce-surface-soft);color:var(--pce-muted);font-size:.72rem;font-weight:800;white-space:nowrap}.connection-editor__status-pill span{width:6px;height:6px;border-radius:999px;background:var(--pce-primary);box-shadow:0 0 12px color-mix(in srgb,var(--pce-primary) 70%,transparent)}.connection-editor__section{display:grid;gap:10px}.connection-editor__dock{grid-column:1 / -1;grid-row:4;position:relative;z-index:4;min-height:0;display:grid;border-radius:14px;border:1px solid var(--pce-outline);background:radial-gradient(circle at 16% 0%,color-mix(in srgb,var(--pce-primary) 22%,transparent),transparent 34%),radial-gradient(circle at 78% 0%,color-mix(in srgb,var(--pce-secondary) 25%,transparent),transparent 38%),linear-gradient(90deg,var(--pce-dock-bg),var(--pce-surface-strong) 46%,color-mix(in srgb,var(--pce-secondary) 14%,var(--pce-dock-bg))),var(--pce-dock-bg);box-shadow:0 18px 58px var(--pce-shadow-soft),inset 0 1px var(--pce-glass-highlight);overflow:hidden;-webkit-backdrop-filter:blur(18px);backdrop-filter:blur(18px)}.connection-editor__dock--collapsed .connection-editor__dock-tabs{border-block-end:0}.connection-editor__dock-tabs{display:flex;align-items:center;gap:10px;min-height:52px;padding:9px 14px;border-block-end:1px solid var(--pce-outline);background:linear-gradient(180deg,var(--pce-glass-highlight),transparent),color-mix(in srgb,var(--pce-surface-soft) 34%,transparent)}.connection-editor__dock-tab,.connection-editor__dock-toggle{min-height:30px;border-radius:999px;border:1px solid transparent;background:transparent;color:var(--pce-muted);cursor:pointer;font-size:.72rem;font-weight:900;letter-spacing:.14em;text-transform:uppercase;transition:border-color .15s ease,background .15s ease,color .15s ease,box-shadow .15s ease,transform .15s ease}.connection-editor__dock-tab{display:inline-flex;align-items:center;gap:8px;padding:0 13px;white-space:nowrap}.connection-editor__dock-tab-glyph{color:var(--pce-muted);font-family:ui-monospace,SFMono-Regular,Consolas,Liberation Mono,monospace;font-size:.8rem;letter-spacing:0;text-transform:none}.connection-editor__dock-tab--active{color:var(--pce-strong);border-color:var(--pce-outline-strong);background:linear-gradient(180deg,color-mix(in srgb,var(--pce-strong) 14%,transparent),color-mix(in srgb,var(--pce-strong) 6%,transparent));box-shadow:0 0 0 1px color-mix(in srgb,var(--pce-shadow) 72%,transparent),0 0 22px color-mix(in srgb,var(--pce-strong) 8%,transparent),inset 0 1px var(--pce-glass-highlight)}.connection-editor__dock-tab--active .connection-editor__dock-tab-glyph{color:var(--pce-strong)}.connection-editor__dock-count{margin-inline-start:auto;color:color-mix(in srgb,var(--pce-muted) 62%,transparent);font-size:.7rem;font-weight:800;letter-spacing:.16em;text-transform:uppercase;white-space:nowrap}.connection-editor__dock-toggle{width:32px;padding:0;border-color:var(--pce-outline);background:var(--pce-surface-soft);color:var(--pce-muted);font-size:.88rem;letter-spacing:0}.connection-editor__dock-body{max-height:154px;overflow:auto;padding:12px 12px 14px;border-block-start:1px solid var(--pce-outline);background:linear-gradient(90deg,color-mix(in srgb,var(--pce-primary) 9%,transparent),color-mix(in srgb,var(--pce-secondary) 10%,transparent) 62%,color-mix(in srgb,var(--pce-surface-strong) 18%,transparent)),color-mix(in srgb,var(--pce-surface-soft) 30%,transparent)}.connection-editor__dock-body pre{max-height:60px}.connection-editor__dock-links{display:grid;gap:8px}.connection-editor__dock-link-row{display:grid;grid-template-columns:minmax(0,1fr) auto;align-items:center;gap:10px;width:100%;padding:7px 10px;border-radius:10px;border:1px solid var(--pce-outline);background:linear-gradient(90deg,var(--pce-surface-soft),color-mix(in srgb,var(--pce-secondary) 10%,var(--pce-surface-soft)) 72%,var(--pce-surface-soft)),var(--pce-surface-soft);color:var(--pce-fg);transition:border-color .15s ease,background .15s ease,box-shadow .15s ease,transform .15s ease}.connection-editor__dock-link{display:grid;grid-template-columns:minmax(116px,.52fr) minmax(300px,1.72fr) minmax(160px,.9fr) auto;align-items:center;gap:12px;width:100%;min-height:42px;padding:0;border:0;border-radius:8px;background:transparent;color:inherit;cursor:pointer;text-align:start}.connection-editor__dock-link-row:hover,.connection-editor__dock-link--active{transform:translateY(-1px);border-color:color-mix(in srgb,var(--pce-primary) 42%,transparent);background:linear-gradient(90deg,color-mix(in srgb,var(--pce-primary) 13%,transparent),color-mix(in srgb,var(--pce-secondary) 16%,transparent),var(--pce-surface-strong)),var(--pce-surface-strong);box-shadow:0 12px 32px var(--pce-shadow-soft),inset 0 0 18px color-mix(in srgb,var(--pce-primary) 6%,transparent)}.connection-editor__dock-link--active{border-color:#facc1575;box-shadow:0 12px 32px var(--pce-shadow-soft),0 0 24px #facc151f}.connection-editor__dock-link--new{border-color:#fb923ca3;background:linear-gradient(90deg,#fb923c2e,#a855f729,#0ea5e91f),#0f172ac2;box-shadow:0 12px 34px #02061752,0 0 30px #fb923c2e;animation:new-dock-link-flash 1.35s ease-out forwards}.connection-editor__dock-link--error{border-color:#ef444461}.connection-editor__dock-jump{min-width:62px;min-height:30px;padding:0 10px;border-radius:999px;border:1px solid color-mix(in srgb,var(--pce-primary) 28%,transparent);background:color-mix(in srgb,var(--pce-surface-soft) 54%,transparent);color:var(--pce-primary);cursor:pointer;font-size:.66rem;font-weight:900;letter-spacing:.06em;text-transform:uppercase;transition:border-color .15s ease,background .15s ease,color .15s ease,box-shadow .15s ease}.connection-editor__dock-jump:hover,.connection-editor__dock-jump:focus-visible{border-color:color-mix(in srgb,var(--pce-primary) 56%,transparent);background:color-mix(in srgb,var(--pce-primary) 16%,transparent);color:var(--pce-strong);box-shadow:0 0 18px color-mix(in srgb,var(--pce-primary) 18%,transparent);outline:none}.connection-editor__dock-link-kind{display:inline-flex;align-items:center;gap:7px;min-width:0;color:var(--pce-muted);font-size:.66rem;font-weight:900;letter-spacing:.1em;text-transform:uppercase;white-space:nowrap}.connection-editor__dock-link-kind span{width:8px;height:8px;border-radius:999px;background:#b46cff;box-shadow:0 0 14px #b46cff7a}.connection-editor__dock-link--state .connection-editor__dock-link-kind span{background:#ff9f2f;box-shadow:0 0 16px #ff9f2f94}.connection-editor__dock-link--state-read .connection-editor__dock-link-kind span{background:#8b7dff;box-shadow:0 0 13px #8b7dff75}.connection-editor__dock-link--projection .connection-editor__dock-link-kind span{background:#19c8e8;box-shadow:0 0 10px #19c8e857}.connection-editor__dock-link--event-propagation .connection-editor__dock-link-kind span{background:#ffb454;box-shadow:0 0 15px #ffb45485}.connection-editor__dock-link--policy .connection-editor__dock-link-kind span{outline:1px solid rgba(34,197,94,.76);outline-offset:2px;box-shadow:0 0 16px #22c55e61}.connection-editor__dock-link--policy:not(.connection-editor__dock-link--state,.connection-editor__dock-link--state-read,.connection-editor__dock-link--projection,.connection-editor__dock-link--event-propagation) .connection-editor__dock-link-kind span{background:#22c55e}.connection-editor__dock-link-route{display:inline-flex;align-items:center;gap:8px;min-width:0}.connection-editor__dock-link-chip{min-width:0;overflow:hidden;padding:4px 8px;border-radius:999px;border:1px solid var(--pce-outline);background:color-mix(in srgb,var(--pce-surface-soft) 72%,transparent);color:var(--pce-fg);font-size:.72rem;font-weight:900;text-overflow:ellipsis;white-space:nowrap}.connection-editor__dock-link-chip--from{border-color:#ff9f2f66;color:#ffbd62}.connection-editor__dock-link-chip--to{border-color:#19c8e83d;color:#7dddeb}:host-context(.theme-light) .connection-editor__dock-link-chip--from{border-color:color-mix(in srgb,var(--pce-tertiary) 46%,transparent);color:#8a4600}:host-context(.theme-light) .connection-editor__dock-link-chip--to{border-color:color-mix(in srgb,var(--pce-primary) 34%,transparent);color:#075f73}.connection-editor__dock-link-arrow{flex:0 0 auto;color:var(--pce-muted);font-weight:900}.connection-editor__dock-link-id{min-width:0;overflow:hidden;color:var(--pce-muted);font-size:.66rem;font-weight:800;font-family:ui-monospace,SFMono-Regular,Consolas,Liberation Mono,monospace;text-overflow:ellipsis;white-space:nowrap}.connection-editor__dock-link-badges{display:inline-flex;justify-content:flex-end;gap:5px;min-width:70px}.connection-editor__dock-link-badges span{padding:3px 7px;border-radius:999px;background:#a855f724;color:#d8b4fe;font-size:.62rem;font-weight:900;text-transform:uppercase;white-space:nowrap}:host-context(.theme-light) .connection-editor__dock-link-badges span{background:color-mix(in srgb,var(--pce-secondary) 14%,var(--pce-surface-soft));color:#6d2a9f}.connection-editor__dock-empty{padding:12px;border-radius:12px;border:1px dashed var(--pce-outline);color:var(--pce-muted);font-size:.76rem;font-weight:700}.connection-editor__inspector{border-color:color-mix(in srgb,var(--pce-primary) 26%,transparent);background:linear-gradient(135deg,color-mix(in srgb,var(--pce-primary) 10%,transparent),color-mix(in srgb,var(--pce-secondary) 8%,transparent)),var(--pce-surface)}.connection-editor__eyebrow,.connection-editor__section-title{font-size:.72rem;text-transform:uppercase;letter-spacing:.16em;color:var(--pce-muted);font-weight:700}.connection-editor__title{font-size:1.02rem;font-weight:800}.connection-editor__subtitle,.connection-editor__item-copy,.connection-editor__item-meta,.connection-editor__details-row span,.connection-editor__details-label,.connection-editor__empty{color:var(--pce-muted);font-size:.84rem}.connection-editor__inspector-heading{display:grid;gap:4px;padding:10px 12px;border-radius:14px;background:var(--pce-surface-soft);border:1px solid var(--pce-outline)}.connection-editor__inspector-heading strong{color:var(--pce-strong);font-size:.96rem;overflow-wrap:anywhere}.connection-editor__inspector-heading span{color:var(--pce-primary);font-size:.76rem;font-weight:800;text-transform:uppercase;letter-spacing:.1em}.connection-editor__inspector-ports{display:flex;flex-wrap:wrap;gap:6px}.connection-editor__inspector-port{max-width:100%;padding:4px 8px;border-radius:999px;border:1px solid rgba(148,163,184,.16);background:#0f172a94;color:#cbd5e1;font-size:.68rem;font-weight:800;overflow:hidden;text-overflow:ellipsis;white-space:nowrap}.connection-editor__inspector-port--input{border-color:#22d3ee57;color:#67e8f9}.connection-editor__inspector-port--output{border-color:#f59e0b57;color:#fbbf24}.connection-editor__inspector-port--state{border-color:#a855f761;color:#d8b4fe}.connection-editor__segment-kind-legend{display:grid;gap:10px;padding:12px;border-radius:16px;border:1px solid rgba(148,163,184,.14);background:linear-gradient(135deg,#0f172aa8,#080d1885),#02061757}.connection-editor__segment-kind-grid{display:grid;grid-template-columns:repeat(3,minmax(0,1fr));gap:8px}.connection-editor__segment-kind-pill{min-width:0;display:inline-flex;align-items:center;justify-content:center;gap:6px;min-height:28px;padding:0 8px;border-radius:999px;border:1px solid rgba(148,163,184,.14);background:#0f172a94;color:#cbd5e1;font-size:.68rem;font-weight:900;overflow:hidden;white-space:nowrap}.connection-editor__segment-kind-pill span{width:8px;height:8px;flex:0 0 auto;border-radius:999px;background:currentColor;box-shadow:0 0 12px currentColor}.connection-editor__segment-kind-pill--input{border-color:#19c8e83d;color:#7dddeb}.connection-editor__segment-kind-pill--output{border-color:#ff9f2f61;color:#ffbd62}.connection-editor__segment-kind-pill--state{border-color:#b46cff61;color:#d9b8ff}:host-context(.theme-light) .connection-editor__segment-kind-pill{border-color:var(--pce-outline);background:color-mix(in srgb,var(--pce-surface-strong) 88%,transparent)}:host-context(.theme-light) .connection-editor__segment-kind-pill--input{color:#075f73}:host-context(.theme-light) .connection-editor__segment-kind-pill--output{color:#8a4600}:host-context(.theme-light) .connection-editor__segment-kind-pill--state{color:#6d2a9f}.connection-editor__stage{grid-column:1;grid-row:2;position:relative;min-height:0;height:100%;overflow:visible;border-radius:16px;border:1px solid var(--pce-outline);background:radial-gradient(circle at center,color-mix(in srgb,var(--pce-secondary) 7%,transparent),transparent 38%),radial-gradient(circle,var(--pce-grid) 1px,transparent 1.5px),var(--pce-stage-bg);background-size:auto,31px 31px,auto;box-shadow:inset 0 0 0 1px var(--pce-glass-highlight);cursor:grab;touch-action:none}.connection-editor__stage--panning,.connection-editor__stage:active{cursor:grabbing}.connection-editor__stage--dragging{cursor:crosshair}.connection-editor__stage--rotating{cursor:grabbing}.connection-editor__viewport{position:absolute;inset-block-start:0;inset-inline-start:0;width:900px;height:540px;overflow:visible;transform-origin:0 0;transition:transform .14s ease}.connection-editor__wires{position:absolute;inset:0;width:100%;height:100%;overflow:visible}.connection-editor__wire,.connection-editor__wire-hit{fill:none;stroke-linecap:round}.connection-editor__wire{stroke:#b46cff;stroke-width:1.45;stroke-opacity:.48;pointer-events:none;filter:url(#connection-glow);stroke-dasharray:10 8;animation:connection-flow 1.65s linear infinite}.connection-editor__wire-hit{stroke:transparent;stroke-width:18;cursor:pointer;pointer-events:stroke}.connection-editor__wire-hit--active{stroke-width:28}.connection-editor__wire--halo{stroke:#b46cff1f;stroke-width:7;stroke-dasharray:none;animation:none}.connection-editor__wire--state{stroke:#ff9f2f;stroke-width:2.25;stroke-dasharray:8 7;animation:connection-flow .92s linear infinite}.connection-editor__wire--state.connection-editor__wire--halo{stroke:#ff9f2f29;stroke-width:11}.connection-editor__wire--projection{stroke:#15b8d8;stroke-width:1.75;stroke-dasharray:20 8;animation:connection-flow 1.9s linear infinite}.connection-editor__wire--projection.connection-editor__wire--halo{stroke:#15b8d81a;stroke-width:7}.connection-editor__wire--state-read{stroke:#8b7dff;stroke-width:1.65;stroke-dasharray:3 11;animation:connection-flow 2.25s linear infinite reverse}.connection-editor__wire--state-read.connection-editor__wire--halo{stroke:#8b7dff21;stroke-width:8}.connection-editor__wire--event-propagation{stroke:#ffb454;stroke-width:2.05;stroke-dasharray:5 7;animation:connection-flow .78s linear infinite}.connection-editor__wire--event-propagation.connection-editor__wire--halo{stroke:#ffb4542e;stroke-width:10}.connection-editor__wire--policy{filter:drop-shadow(0 0 6px rgba(34,197,94,.2)) url(#connection-glow)}.connection-editor__wire--policy.connection-editor__wire--halo{stroke:#22c55e1f;stroke-width:13}.connection-editor__wire--warning{stroke:#ff9f2f}.connection-editor__wire--warning.connection-editor__wire--halo{stroke:#ff9f2f2e}.connection-editor__wire--error{stroke:#ef4444}.connection-editor__wire--error.connection-editor__wire--halo{stroke:#ef44442e}.connection-editor__wire--active{stroke:#d9b8ff;stroke-width:3;stroke-opacity:1;stroke-dasharray:5 7;animation-duration:.58s}.connection-editor__wire--halo.connection-editor__wire--active{stroke-width:16;stroke-opacity:.8;animation:selected-wire-aura 1.35s ease-in-out infinite}.connection-editor__wire--new{stroke-width:3.4;stroke-opacity:1;stroke-dasharray:640;stroke-dashoffset:640;animation:wire-draw-in .62s cubic-bezier(.16,1,.3,1) forwards,connection-flow 1.05s linear .62s infinite}.connection-editor__wire--halo.connection-editor__wire--new{stroke-width:22;stroke-opacity:0;animation:new-wire-halo 1.45s ease-out forwards}.connection-editor__wire--trace{stroke:#9b5cff;stroke-width:3.2;stroke-opacity:1;stroke-dasharray:7 6;animation:connection-flow .72s linear infinite,trace-wire-pulse 1.18s ease-in-out infinite}.connection-editor__wire--halo.connection-editor__wire--trace{stroke:#9b5cff57;stroke-width:18;stroke-opacity:.86;animation:trace-halo-pulse 1.18s ease-in-out infinite}.connection-editor__wire--mode-dimmed{stroke-opacity:.14;stroke-width:1.05;filter:none;animation-duration:2.6s}.connection-editor__wire--halo.connection-editor__wire--mode-dimmed{stroke-opacity:.05;stroke-width:5;animation:none}.connection-editor__wire-hit--mode-dimmed{stroke-width:12}.connection-editor__wire-endpoint{fill:#f8fafc;stroke:#0f172ae6;stroke-width:1.5;filter:drop-shadow(0 0 8px rgba(216,180,254,.8));pointer-events:none;animation:endpoint-pulse 1.2s ease-in-out infinite}.connection-editor__wire-endpoint--source{fill:#ff9f2f}.connection-editor__wire-endpoint--target{fill:#19c8e8}.connection-editor__connection-tooltip{position:absolute;z-index:6;width:min(312px,calc(100% - 24px));display:grid;gap:8px;padding:12px 14px;border-radius:14px;border:1px solid var(--pce-outline);background:linear-gradient(135deg,var(--pce-surface-strong),var(--pce-surface)),var(--pce-surface-strong);box-shadow:0 18px 44px var(--pce-shadow-soft),inset 0 1px var(--pce-glass-highlight);color:var(--pce-fg);pointer-events:none;-webkit-backdrop-filter:blur(18px);backdrop-filter:blur(18px);animation:tooltip-rise .14s ease-out}.connection-editor__connection-tooltip-callout{position:absolute;inset-block-start:100%;inset-inline-start:var(--connection-tooltip-callout-x, 42px);width:2px;height:28px;border-radius:999px;background:linear-gradient(180deg,#e2e8f0bd,#19c8e800);box-shadow:0 0 12px #19c8e852;transform:translate(-1px);pointer-events:none}.connection-editor__connection-tooltip-callout:before,.connection-editor__connection-tooltip-callout:after{content:\"\";position:absolute;border-radius:999px;pointer-events:none}.connection-editor__connection-tooltip-callout:before{inset-block-start:-5px;inset-inline-start:-5px;width:12px;height:12px;border:1px solid rgba(148,163,184,.24);background:#080d18f5;box-shadow:inset 0 1px #ffffff14}.connection-editor__connection-tooltip-callout:after{inset-block-end:-3px;inset-inline-start:-4px;width:10px;height:10px;background:#19c8e8;box-shadow:0 0 16px #19c8e88f}.connection-editor__connection-tooltip--projection{border-color:#19c8e833;background:linear-gradient(135deg,#15b8d81f,#0f172ae0),#070c16eb}.connection-editor__connection-tooltip--state{border-color:#ff9f2f66;background:linear-gradient(135deg,#ff9f2f3d,#0f172ae0),#070c16eb}.connection-editor__connection-tooltip--state .connection-editor__connection-tooltip-callout{background:linear-gradient(180deg,#ffbd62d1,#ff9f2f00);box-shadow:0 0 14px #ff9f2f61}.connection-editor__connection-tooltip--state .connection-editor__connection-tooltip-callout:after{background:#ff9f2f;box-shadow:0 0 18px #ff9f2fad}.connection-editor__connection-tooltip--error{border-color:#f871716b}.connection-editor__connection-tooltip--error .connection-editor__connection-tooltip-callout:after{background:#fb7185;box-shadow:0 0 18px #fb7185ad}.connection-editor__connection-tooltip-kind{display:inline-flex;align-items:center;gap:8px;color:#94a3b8;font-size:.62rem;font-weight:900;letter-spacing:.16em;text-transform:uppercase}.connection-editor__connection-tooltip-kind span{width:8px;height:8px;border-radius:999px;background:#19c8e8;box-shadow:0 0 12px #19c8e880}.connection-editor__connection-tooltip--state .connection-editor__connection-tooltip-kind span{background:#ff9f2f;box-shadow:0 0 16px #ff9f2fc7}.connection-editor__connection-tooltip-row{min-width:0;display:grid;grid-template-columns:54px minmax(0,1fr);align-items:center;gap:8px;min-height:28px;padding:0 10px;border-radius:999px;background:#0f172a94}.connection-editor__connection-tooltip-row span{color:#8d9bb0;font-size:.62rem;font-weight:900;letter-spacing:.12em;text-transform:uppercase}.connection-editor__connection-tooltip-row strong{min-width:0;overflow:hidden;color:#e2e8f0;font-size:.75rem;font-weight:900;text-overflow:ellipsis;white-space:nowrap}.connection-editor__connection-tooltip-badges{display:flex;flex-wrap:wrap;gap:6px}.connection-editor__connection-tooltip-badges span{padding:3px 8px;border-radius:999px;background:#02061799;color:#fbbf24;font-size:.66rem;font-weight:900}.connection-editor__trace-overlay{position:absolute;z-index:6;inset-block-start:16px;inset-inline-start:50%;width:min(560px,calc(100% - 360px));min-width:320px;padding:12px 14px;border-radius:16px;border:1px solid rgba(34,197,94,.26);background:linear-gradient(135deg,#22c55e1f,#0ea5e91a),#080d18f0;box-shadow:0 22px 56px #02061775,0 0 42px #22c55e1f;transform:translate(-50%);pointer-events:auto;-webkit-backdrop-filter:blur(18px);backdrop-filter:blur(18px);animation:tooltip-rise .16s ease-out}.connection-editor__trace-overlay-head,.connection-editor__trace-overlay-route{display:flex;align-items:center;justify-content:space-between;gap:12px;min-width:0}.connection-editor__trace-overlay-head span,.connection-editor__trace-overlay-route span{color:#86efac;font-size:.66rem;font-weight:900;letter-spacing:.12em;text-transform:uppercase;white-space:nowrap}.connection-editor__trace-overlay-head strong{color:#cbd5e1;font-size:.7rem;font-weight:900;font-family:ui-monospace,SFMono-Regular,Consolas,Liberation Mono,monospace}.connection-editor__trace-overlay-route{margin-top:6px}.connection-editor__trace-overlay-controls{display:grid;grid-template-columns:28px minmax(0,1fr) 28px;align-items:center;gap:8px;margin-top:10px}.connection-editor__trace-overlay-button{width:28px;height:24px;display:inline-grid;place-items:center;border:1px solid rgba(148,163,184,.18);border-radius:999px;background:#0206176b;color:#e2e8f0;cursor:pointer;font-size:1rem;font-weight:900;line-height:1;transition:border-color .15s ease,background .15s ease,color .15s ease,opacity .15s ease}.connection-editor__trace-overlay-button:hover:not(:disabled){border-color:#22d3ee6b;background:#0ea5e929;color:#f8fafc}.connection-editor__trace-overlay-button:disabled{cursor:default;opacity:.36}.connection-editor__trace-overlay-steps{min-width:0;display:flex;align-items:center;gap:6px;overflow-x:auto;padding:2px;scrollbar-width:none}.connection-editor__trace-overlay-steps::-webkit-scrollbar{display:none}.connection-editor__trace-overlay-step{position:relative;flex:1 0 28px;min-width:28px;height:22px;border:1px solid rgba(148,163,184,.16);border-radius:999px;background:#0f172a9e;color:#94a3b8;cursor:pointer;font-size:.62rem;font-weight:900;font-family:ui-monospace,SFMono-Regular,Consolas,Liberation Mono,monospace;transition:border-color .15s ease,background .15s ease,color .15s ease,box-shadow .15s ease}.connection-editor__trace-overlay-step--active{border-color:#22d3eea3;background:linear-gradient(90deg,#22d3ee3d,#9b5cff33);color:#f8fafc;box-shadow:0 0 18px #22d3ee33}.connection-editor__trace-overlay-step--blocked{border-color:#fb71855c;color:#fecdd3}.connection-editor__trace-overlay-route strong{min-width:0;overflow:hidden;color:#f8fafc;font-size:.82rem;font-weight:900;text-overflow:ellipsis;white-space:nowrap}.connection-editor__trace-overlay-bar{position:relative;height:5px;margin-top:10px;overflow:hidden;border-radius:999px;background:#94a3b829}.connection-editor__trace-overlay-bar span{position:absolute;inset-block:0;inset-inline-start:0;border-radius:inherit;background:linear-gradient(90deg,#22c55e,#22d3ee);box-shadow:0 0 18px #22c55e61;min-width:8%}.connection-editor__drag-wire{fill:none;stroke:#94a3b8;stroke-width:2.4;stroke-linecap:round;stroke-dasharray:6 7;pointer-events:none;filter:url(#connection-glow);animation:connection-flow 1.05s linear infinite,drag-wire-pulse 1.2s ease-in-out infinite}.connection-editor__drag-wire--halo{stroke:#94a3b829;stroke-width:14;stroke-dasharray:none;animation:drag-halo-pulse 1.2s ease-in-out infinite}.connection-editor__drag-wire--valid{stroke:#22c55e}.connection-editor__drag-wire--halo.connection-editor__drag-wire--valid{stroke:#22c55e47}.connection-editor__drag-endpoint{fill:#94a3b8;stroke:#020617eb;stroke-width:2;pointer-events:none;filter:url(#connection-glow);transform-box:fill-box;transform-origin:center;animation:endpoint-pulse 1s ease-in-out infinite}.connection-editor__drag-endpoint--source{fill:#ff9f2f}.connection-editor__drag-endpoint--target{fill:#7dddeb}.connection-editor__drag-endpoint--valid{fill:#22c55e;stroke:#bbf7d0e0}.connection-editor__wire-handle-line{stroke-width:2;stroke-linecap:round;stroke-dasharray:4 5;pointer-events:none;opacity:.88;filter:url(#connection-glow)}.connection-editor__wire-handle-line--source{stroke:#ff9f2ff0}.connection-editor__wire-handle-line--target{stroke:#19c8e8c2}.connection-editor__wire-control{fill:#0f172af5;stroke:#cbd5e1c7;stroke-width:1.8;pointer-events:none;filter:url(#connection-glow)}.connection-editor__wire-label{pointer-events:none;filter:drop-shadow(0 0 10px rgba(2,6,23,.44));animation:tooltip-rise .14s ease-out}.connection-editor__wire-label rect{fill:#080d18eb;stroke-width:1}.connection-editor__wire-label text{fill:#e2e8f0;font-family:ui-monospace,SFMono-Regular,Consolas,Liberation Mono,monospace;font-size:8px;font-weight:900;letter-spacing:.08em;text-transform:uppercase}.connection-editor__wire-label--source rect{stroke:#ff9f2fad}.connection-editor__wire-label--target rect{stroke:#19c8e86b}.connection-editor__zoom-controls{position:absolute;inset-inline-start:14px;inset-block-start:14px;z-index:4;display:grid;gap:8px;width:210px;pointer-events:auto}.connection-editor__tool-group,.connection-editor__trace-source{display:grid;gap:8px;padding:10px;border-radius:14px;border:1px solid var(--pce-outline);background:linear-gradient(180deg,var(--pce-surface-strong),var(--pce-surface));box-shadow:0 16px 36px var(--pce-shadow-soft),inset 0 1px var(--pce-glass-highlight);-webkit-backdrop-filter:blur(16px);backdrop-filter:blur(16px)}.connection-editor__tool-group{grid-template-columns:repeat(3,30px);width:max-content}.connection-editor__tool-group:nth-of-type(2){grid-template-columns:repeat(2,30px)}.connection-editor__arrange-button{width:100%;min-height:32px;display:inline-flex;align-items:center;justify-content:center;gap:8px;border-radius:999px;border:1px solid rgba(168,85,247,.34);background:linear-gradient(90deg,#a855f72e,#22d3ee1f);color:#e9d5ff;font-size:.74rem;font-weight:800;letter-spacing:.02em;cursor:pointer}.connection-editor__arrange-button span{color:#c084fc;font-family:ui-monospace,SFMono-Regular,Menlo,Monaco,Consolas,Liberation Mono,monospace;font-weight:900}.connection-editor__tool-button{width:30px;height:30px;border-radius:999px;border:1px solid var(--pce-outline);background:var(--pce-surface-soft);color:var(--pce-fg);font-size:.9rem;font-weight:800;letter-spacing:.02em;cursor:pointer;line-height:1}.connection-editor__tool-button:hover:not(:disabled){border-color:color-mix(in srgb,var(--pce-primary) 42%,transparent);color:var(--pce-primary);box-shadow:0 0 18px color-mix(in srgb,var(--pce-primary) 16%,transparent)}.connection-editor__history-button:disabled{cursor:not-allowed;opacity:.42}.connection-editor__arrange-button--active{border-color:#22d3ee94;background:linear-gradient(90deg,#0ea5e93d,#22d3ee2e);color:#cffafe}.connection-editor__trace-source{gap:4px;max-height:230px;overflow:auto}.connection-editor__trace-source-title{padding:2px 4px 6px;color:var(--pce-muted);font-size:.64rem;font-weight:900;letter-spacing:.18em;text-transform:uppercase}.connection-editor__trace-source-item{min-width:0;min-height:30px;display:flex;align-items:center;gap:8px;padding:0 8px;border:0;border-radius:8px;background:transparent;color:var(--pce-fg);cursor:pointer;font-size:.74rem;font-weight:800;text-align:start}.connection-editor__trace-source-item span{color:#f59e0b;font-family:ui-monospace,SFMono-Regular,Menlo,Monaco,Consolas,Liberation Mono,monospace;font-size:.72rem;font-weight:900}.connection-editor__trace-source-item:hover,.connection-editor__trace-source-item--active{background:var(--pce-surface-strong);color:var(--pce-strong);box-shadow:inset 3px 0 #f59e0bd1}.connection-editor__minimap{position:absolute;inset-inline-end:14px;inset-block-end:14px;z-index:4;width:184px;height:124px;padding:18px 10px 10px;overflow:hidden;border-radius:16px;border:1px solid color-mix(in srgb,var(--pce-primary) 30%,transparent);background:linear-gradient(135deg,color-mix(in srgb,var(--pce-primary) 12%,transparent),var(--pce-surface-strong)),var(--pce-surface);box-shadow:0 20px 48px var(--pce-shadow-soft),inset 0 1px var(--pce-glass-highlight);cursor:pointer;-webkit-backdrop-filter:blur(16px);backdrop-filter:blur(16px)}.connection-editor__minimap:hover,.connection-editor__minimap--panning{border-color:#22d3ee75;box-shadow:0 20px 48px var(--pce-shadow-soft),0 0 24px color-mix(in srgb,var(--pce-primary) 14%,transparent),inset 0 1px var(--pce-glass-highlight)}.connection-editor__minimap--panning{cursor:grabbing}.connection-editor__minimap:before{content:\"\";position:absolute;inset:22px 10px 10px;border-radius:10px;background-image:radial-gradient(circle,rgba(125,211,252,.18) 1px,transparent 1px);background-size:22px 22px;opacity:.58;pointer-events:none}.connection-editor__minimap-title{position:absolute;inset-block-start:7px;inset-inline-start:12px;color:var(--pce-muted);font-size:.6rem;font-weight:900;letter-spacing:.16em;text-transform:uppercase}.connection-editor__minimap svg{position:relative;width:100%;height:100%;display:block;overflow:visible}.connection-editor__minimap-wire{fill:none;stroke:#b46cff8f;stroke-width:4;stroke-linecap:round;opacity:.86}.connection-editor__minimap-wire--state{stroke:#ff9f2fdb}.connection-editor__minimap-wire--state-read{stroke:#8b7dffb8;stroke-dasharray:4 9}.connection-editor__minimap-wire--projection{stroke:#19c8e88a;stroke-dasharray:18 8}.connection-editor__minimap-wire--event-propagation{stroke:#ffb454cc;stroke-dasharray:6 7}.connection-editor__minimap-wire--policy{filter:drop-shadow(0 0 6px rgba(34,197,94,.28))}.connection-editor__minimap-wire--trace{stroke:#9b5cffe0;stroke-width:5;stroke-dasharray:12 9;animation:connection-flow 1s linear infinite}.connection-editor__minimap-wire--active{stroke:#facc15eb;stroke-width:6;filter:drop-shadow(0 0 8px rgba(250,204,21,.38))}.connection-editor__minimap-wire--mode-dimmed{opacity:.2;stroke-width:2.6;filter:none}.connection-editor__minimap-node{fill:#f59e0be0;stroke:#020617db;stroke-width:4;filter:drop-shadow(0 0 7px rgba(245,158,11,.24))}.connection-editor__minimap-node--state{fill:#a855f7e6;filter:drop-shadow(0 0 8px rgba(168,85,247,.34))}.connection-editor__minimap-node--selected{fill:#facc15f5;stroke:#fef08aeb;filter:drop-shadow(0 0 10px rgba(250,204,21,.42))}.connection-editor__minimap-node--trace-source{fill:#facc15f5;filter:drop-shadow(0 0 10px rgba(250,204,21,.44))}.connection-editor__minimap-node--trace-reacting{fill:#22c55eeb;filter:drop-shadow(0 0 10px rgba(34,197,94,.42))}.connection-editor__minimap-node--mode-dimmed{opacity:.28;filter:none}.connection-editor__minimap-viewport{fill:#7dd3fc1f;stroke:#7dd3fce6;stroke-width:5;stroke-dasharray:18 10;filter:drop-shadow(0 0 10px rgba(125,211,252,.3));transition:x .12s ease,y .12s ease,width .12s ease,height .12s ease}.connection-editor__minimap--panning .connection-editor__minimap-viewport{fill:#22d3ee2e;stroke:#22d3eef5;stroke-dasharray:none}.connection-editor__node{position:absolute;width:168px;height:168px;transform:translate(-84px,-84px);border:0;padding:0;background:transparent;color:inherit;cursor:pointer;transition:filter .16s ease}.connection-editor__node--dragging{cursor:grabbing;filter:drop-shadow(0 0 22px rgba(34,211,238,.26));z-index:12}.connection-editor__node--connection-focus{filter:drop-shadow(0 0 16px rgba(34,211,238,.2))}.connection-editor__node--compat-target .connection-editor__node-ring{box-shadow:0 0 0 2px #22c55e66,0 0 0 18px #22c55e0b,0 0 32px #22c55e29}.connection-editor__node--mode-dimmed{opacity:.42;filter:grayscale(.22) saturate(.56)}.connection-editor__node--mode-dimmed .connection-editor__node-ring{animation:none;box-shadow:0 0 0 1px #2dd4bf14,0 0 14px #0ea5e90f}.connection-editor__node--mode-dimmed .connection-editor__node-halo{stroke-opacity:.28}.connection-editor__node-ring,.connection-editor__node-core,.connection-editor__node-svg{position:absolute;inset:0}.connection-editor__node-ring,.connection-editor__node-core{display:grid;place-items:center;clip-path:polygon(30% 0,70% 0,100% 30%,100% 70%,70% 100%,30% 100%,0 70%,0 30%)}.connection-editor__node-ring{background:radial-gradient(circle at center,transparent 0 44%,rgba(7,17,31,.96) 45% 57%,transparent 58%),conic-gradient(from -28deg,#06b6d4b3 0 28%,#f59e0b9e 28% 48%,#a855f780 48% 68%,#06b6d4a3 68% 100%);box-shadow:0 0 0 1px #2dd4bf2e,0 0 26px #0ea5e929;animation:node-breathe 2.8s ease-in-out infinite}.connection-editor__node-svg{overflow:visible;filter:drop-shadow(0 0 16px rgba(14,165,233,.16))}.connection-editor__node-halo{fill:transparent;stroke:#38bdf838;stroke-width:1;stroke-dasharray:0;pointer-events:none}.connection-editor__node-halo:nth-child(2){stroke:#38bdf824}.connection-editor__node-halo:nth-child(3){stroke:#94a3b81a}.connection-editor__node-segment{fill-opacity:.28;stroke-opacity:.72;stroke-width:1.15;transition:fill-opacity .16s ease,stroke-opacity .16s ease,stroke-width .16s ease;cursor:grab}.connection-editor__node:hover .connection-editor__node-segment,.connection-editor__node--selected .connection-editor__node-segment,.connection-editor__node--connection-focus .connection-editor__node-segment{fill-opacity:.54;stroke-opacity:.95;stroke-width:1.55}.connection-editor__node-segment--connection-focus{fill-opacity:.76;stroke-opacity:1;stroke-width:2;filter:drop-shadow(0 0 8px rgba(34,211,238,.76));animation:segment-focus-sweep 1.45s ease-in-out infinite}.connection-editor__node-segment--source{fill-opacity:.86;stroke-opacity:1;stroke-width:2.45;filter:drop-shadow(0 0 12px rgba(251,146,60,.82))}.connection-editor__node-segment--compatible{fill-opacity:.74;stroke-opacity:1;stroke-width:2;filter:drop-shadow(0 0 10px rgba(34,197,94,.72));animation:snap-pulse 1s ease-in-out infinite}.connection-editor__node-segment--compat-preview{fill-opacity:.86;stroke-opacity:1;stroke-width:2.45;filter:drop-shadow(0 0 13px rgba(245,158,11,.78))}.connection-editor__node-segment--candidate{fill-opacity:.92;stroke-opacity:1;stroke-width:2.8;filter:drop-shadow(0 0 16px rgba(34,197,94,.86))}.connection-editor__node-segment--incompatible{fill-opacity:.12;stroke-opacity:.28;cursor:not-allowed}.connection-editor__node-segment--invalid-drop{fill-opacity:.72;stroke:#fb7185;stroke-opacity:1;stroke-width:3;filter:drop-shadow(0 0 16px rgba(244,63,94,.84));animation:invalid-drop-jolt .36s ease-out}.connection-editor__node-segment--state{fill-opacity:.44;filter:drop-shadow(0 0 8px rgba(180,108,255,.2))}.connection-editor__node-segment--mode-dimmed{fill-opacity:.08;stroke-opacity:.2;stroke-width:.9;filter:none}.connection-editor__node-anchor{opacity:.95;filter:drop-shadow(0 0 6px currentColor)}.connection-editor__node-rotate-handle{cursor:grab;opacity:0;pointer-events:none;transition:opacity .16s ease,filter .16s ease;filter:drop-shadow(0 0 8px rgba(34,211,238,.28))}.connection-editor__node:hover .connection-editor__node-rotate-handle,.connection-editor__node--selected .connection-editor__node-rotate-handle,.connection-editor__node--rotating .connection-editor__node-rotate-handle{opacity:1;pointer-events:auto}.connection-editor__node--rotating .connection-editor__node-rotate-handle{cursor:grabbing;filter:drop-shadow(0 0 12px rgba(34,211,238,.54))}.connection-editor__node-rotate-hit{fill:transparent}.connection-editor__node-rotate-dot{fill:var(--pce-surface-strong);stroke:var(--pce-primary);stroke-opacity:.88;stroke-width:1.4}.connection-editor__node-rotate-arc,.connection-editor__node-rotate-arrow{fill:none;stroke:var(--pce-primary);stroke-linecap:round;stroke-linejoin:round;stroke-opacity:.96;stroke-width:1.2;pointer-events:none}.connection-editor__segment-icon,.connection-editor__segment-label{pointer-events:none;fill:#cbd5e1;font-family:ui-monospace,SFMono-Regular,Menlo,Monaco,Consolas,Liberation Mono,monospace;font-weight:800;paint-order:stroke;stroke:#020617c2;stroke-width:3px;stroke-linejoin:round}.connection-editor__segment-icon{font-size:12px;fill:#19c8e8}.connection-editor__segment-icon--output{fill:#ff9f2f}.connection-editor__segment-label{font-size:9.5px;letter-spacing:0;fill:#e2e8f0e0}.connection-editor__node-core{inset:43px;padding:12px;border-radius:999px;clip-path:none;display:flex;flex-direction:column;align-items:center;justify-content:center;background:radial-gradient(circle at center,#111827 0 58%,#060b14);border:1px solid rgba(226,232,240,.1);box-shadow:0 12px 28px #00000073,inset 0 1px #ffffff0d;color:#f8fafc;text-shadow:0 1px 2px rgba(0,0,0,.62)}.connection-editor__node-icon{display:block;max-width:44px;overflow:hidden;color:#f8fafc;font-family:Material Symbols Outlined,Material Icons,sans-serif;font-size:1.22rem;font-weight:400;line-height:1;text-align:center;text-transform:none;letter-spacing:0;white-space:nowrap;filter:drop-shadow(0 0 10px rgba(226,232,240,.18))}.connection-editor__node--state .connection-editor__node-ring{background:radial-gradient(circle at center,transparent 0 44%,rgba(7,17,31,.96) 45% 57%,transparent 58%),conic-gradient(from 14deg,#a855f7c7 0 42%,#7e3af26b 42% 78%,#f59e0b47 78% 100%);box-shadow:0 0 0 1px #a855f738,0 0 30px #a855f733}.connection-editor__node--selected .connection-editor__node-ring{box-shadow:0 0 0 2px #facc15bd,0 0 34px #facc153d}.connection-editor__node--connection-focus .connection-editor__node-ring{box-shadow:0 0 0 2px #22d3eead,0 0 38px #22d3ee42;animation:node-focus-breathe 1.7s ease-in-out infinite}.connection-editor__node--trace-source .connection-editor__node-ring{box-shadow:0 0 0 2px #facc15c7,0 0 0 18px #facc150f,0 0 54px #facc154d;animation:trace-source-pulse 1.38s ease-in-out infinite}.connection-editor__node--trace-source:before{content:\"\";position:absolute;z-index:0;inset:-44px;border-radius:999px;border:2px solid rgba(250,204,21,.36);background:radial-gradient(circle at center,transparent 0 64%,rgba(250,204,21,.05) 65% 66%,transparent 67%),conic-gradient(from -20deg,#facc1500,#facc1552,#facc1500);box-shadow:0 0 36px #facc151f;opacity:.92;pointer-events:none;animation:trace-source-orbit 2.8s linear infinite}.connection-editor__node--trace-reacting .connection-editor__node-ring{box-shadow:0 0 0 2px #22c55e94,0 0 46px #22c55e38;animation:trace-reacting-pulse 1.38s ease-in-out infinite}.connection-editor__node--trace-source:after,.connection-editor__node--trace-reacting:after{position:absolute;z-index:3;inset-inline-start:50%;inset-block-start:-42px;padding:0;border:0;background:transparent;color:#facc15;font-family:ui-monospace,SFMono-Regular,Menlo,Monaco,Consolas,Liberation Mono,monospace;font-size:.68rem;font-weight:900;letter-spacing:.18em;text-transform:uppercase;transform:translate(-50%);text-shadow:0 0 12px rgba(250,204,21,.52);pointer-events:none}.connection-editor__node--trace-source:after{content:attr(data-trace-label)}.connection-editor__node--trace-reacting:after{content:attr(data-trace-label);color:#86efac;text-shadow:0 0 12px rgba(34,197,94,.44)}.connection-editor__node--trace-source .connection-editor__node-segment--output{fill-opacity:.66;stroke-width:2.2;filter:drop-shadow(0 0 14px rgba(255,159,47,.42))}.connection-editor__node--expanded .connection-editor__node-ring{box-shadow:0 0 0 2px #22d3eebd,0 0 34px #22d3ee3d}.connection-editor__node--rotating .connection-editor__node-ring{box-shadow:0 0 0 2px #facc15c7,0 0 42px #facc1547;animation:node-focus-breathe 1.1s ease-in-out infinite}.connection-editor__node--rotating .connection-editor__node-segment{fill-opacity:.68;stroke-opacity:1;stroke-width:1.9;cursor:grabbing}.connection-editor__node-title,.connection-editor__node-subtitle{display:block;max-width:92px;overflow:hidden;text-overflow:ellipsis;white-space:nowrap;text-align:center}.connection-editor__node-title{color:#f8fafc;font-size:.82rem;font-weight:800}.connection-editor__node-subtitle{margin-top:4px;color:#a7b4c8;font-size:.62rem;text-transform:uppercase;letter-spacing:.08em}.connection-editor__ports{position:absolute;display:grid;gap:6px;width:104px;opacity:0;pointer-events:none;transition:opacity .16s ease}.connection-editor__segment-popover{position:absolute;z-index:80;width:292px;max-height:320px;overflow:auto;display:grid;gap:10px;padding:14px;border-radius:16px;border:1px solid rgba(148,163,184,.18);background:linear-gradient(135deg,#0f172af5,#110c20f0),#090c16eb;box-shadow:0 28px 72px #0000007a,0 0 48px #a855f71a,inset 0 1px #ffffff0d;-webkit-backdrop-filter:blur(18px);backdrop-filter:blur(18px)}.connection-editor__segment-popover-header{display:flex;align-items:flex-start;justify-content:space-between;gap:12px;padding-bottom:2px}.connection-editor__segment-popover-title{color:#94a3b8;font-size:.68rem;font-weight:800;letter-spacing:.14em;text-transform:uppercase}.connection-editor__segment-popover-hint{margin-top:5px;color:#64748b;font-size:.66rem;font-weight:700}.connection-editor__segment-rotation{flex:0 0 auto;min-width:54px;padding:5px 8px;border-radius:999px;border:1px solid rgba(34,211,238,.28);background:#082f4957;color:#7dd3fc;font-size:.66rem;font-weight:900;font-family:ui-monospace,SFMono-Regular,Consolas,Liberation Mono,monospace;text-align:center;box-shadow:inset 0 0 16px #0ea5e914}.connection-editor__segment-row{display:grid;grid-template-columns:28px 72px minmax(0,1fr) auto;align-items:center;gap:8px;min-height:40px;padding:7px;border-radius:12px;border:1px solid rgba(148,163,184,.12);background:linear-gradient(90deg,#0f172ac7,#0f172a75),#0f172a99;transition:border-color .15s ease,background .15s ease,box-shadow .15s ease,transform .15s ease}.connection-editor__segment-row--input{border-color:#22d3ee42}.connection-editor__segment-row--output{border-color:#f59e0b47}.connection-editor__segment-row--state{border-color:#a855f74d}.connection-editor__segment-row--source,.connection-editor__segment-row--candidate{transform:translate(2px);box-shadow:0 0 22px #f59e0b24,inset 0 0 20px #f59e0b14}.connection-editor__segment-row--compatible{border-color:#22d3ee6b;box-shadow:inset 0 0 18px #22d3ee14}.connection-editor__segment-row--compat-preview{border-color:#f59e0b94;background:linear-gradient(90deg,#f59e0b1f,#0f172a8a),#0f172ab3;box-shadow:0 0 22px #f59e0b1f,inset 0 0 18px #f59e0b14}.connection-editor__segment-row--invalid-drop{border-color:#fb7185b3;background:linear-gradient(90deg,#f43f5e24,#0f172a94),#0f172ab3;box-shadow:0 0 24px #f43f5e2e,inset 0 0 18px #f43f5e1a;animation:invalid-drop-jolt .36s ease-out}.connection-editor__segment-index{color:#64748b;font-size:.64rem;font-weight:900;font-family:ui-monospace,SFMono-Regular,Consolas,Liberation Mono,monospace;letter-spacing:.08em}.connection-editor__segment-kind{display:inline-flex;align-items:center;gap:6px;color:#94a3b8;font-size:.62rem;font-weight:800;text-transform:uppercase;min-width:0;white-space:nowrap}.connection-editor__segment-kind-dot{width:7px;height:7px;border-radius:999px;background:#94a3b8;box-shadow:0 0 12px #94a3b847}.connection-editor__segment-row--input .connection-editor__segment-kind-dot{background:#22d3ee;box-shadow:0 0 12px #22d3ee61}.connection-editor__segment-row--output .connection-editor__segment-kind-dot{background:#fb923c;box-shadow:0 0 12px #fb923c66}.connection-editor__segment-row--state .connection-editor__segment-kind-dot{background:#a855f7;box-shadow:0 0 12px #a855f76b}.connection-editor__segment-label{display:inline-flex;align-items:center;gap:5px;min-width:0;overflow:hidden;color:#e2e8f0;font-size:.74rem;font-weight:700;text-overflow:ellipsis;white-space:nowrap}.connection-editor__segment-actions{display:inline-flex;gap:4px}.connection-editor__segment-action{width:24px;height:24px;border-radius:999px;border:1px solid rgba(148,163,184,.18);background:#060c16b8;color:#dbeafe;cursor:pointer;font-weight:900;line-height:1}.connection-editor__segment-action:hover{border-color:#22d3ee75;box-shadow:0 0 14px #22d3ee29}.connection-editor__port{min-height:24px;border-radius:999px;border:1px solid rgba(148,163,184,.14);background:#080d18c2;color:#cbd5e1;font-size:.64rem;font-weight:700;font-family:ui-monospace,SFMono-Regular,Consolas,Liberation Mono,monospace;overflow:hidden;text-overflow:ellipsis;white-space:nowrap;cursor:crosshair;box-shadow:0 8px 20px #00000038}.connection-editor__port--output{border-color:#f59e0b75;color:#fbbf24}.connection-editor__port--input{border-color:#06b6d475;color:#22d3ee}.connection-editor__port--state{border-color:#a855f785;color:#c084fc}.connection-editor__port--compatible{background:#22c55e29;box-shadow:0 0 0 1px #22c55e61,0 0 18px #22c55e2e;animation:snap-pulse 1s ease-in-out infinite}.connection-editor__port--source{border-color:#fb923cb8;background:#fb923c29;color:#fed7aa;box-shadow:0 0 0 1px #fb923c73,0 0 20px #fb923c2e}.connection-editor__port--candidate{background:#22c55e3d;box-shadow:0 0 0 2px #22c55e94,0 0 24px #22c55e3d}.connection-editor__port--incompatible{opacity:.42;cursor:not-allowed;filter:grayscale(.45)}.connection-editor__port--invalid-drop{opacity:1;border-color:#fb7185c7;color:#fecdd3;background:#f43f5e2e;box-shadow:0 0 0 2px #f43f5e75,0 0 24px #f43f5e38;filter:none;animation:invalid-drop-jolt .36s ease-out}.connection-editor__port--connection-focus{border-color:#facc15ad;color:#fde68a;background:#facc151f;box-shadow:0 0 0 1px #facc156b,0 0 20px #facc152e;animation:port-focus-pulse 1.25s ease-in-out infinite}.connection-editor__drag-tip{position:absolute;z-index:6;display:grid;gap:4px;width:min(330px,calc(100% - 28px));padding:10px 12px;border-radius:14px;border:1px solid rgba(125,211,252,.26);background:linear-gradient(135deg,#0ea5e91f,#0f172aeb),#080d18f0;box-shadow:0 18px 44px #0206176b,0 0 28px #0ea5e91a;font-size:.76rem;pointer-events:none;-webkit-backdrop-filter:blur(16px);backdrop-filter:blur(16px);animation:tooltip-rise .14s ease-out}.connection-editor__drag-tip--valid{border-color:#22c55e66;background:linear-gradient(135deg,#22c55e29,#0f172aeb),#080d18f0;box-shadow:0 18px 44px #0206176b,0 0 30px #22c55e24}.connection-editor__drag-tip--invalid{z-index:7;border-color:#fb71858a;background:linear-gradient(135deg,#f43f5e2e,#0f172af0),#080d18f5;box-shadow:0 18px 44px #0206176b,0 0 34px #f43f5e29;animation:tooltip-rise .14s ease-out,invalid-drop-jolt .36s ease-out}.connection-editor__invalid-drop-pulse{position:absolute;z-index:6;width:16px;height:16px;border-radius:999px;border:2px solid rgba(251,113,133,.88);background:#f43f5e38;box-shadow:0 0 0 8px #f43f5e1a,0 0 28px #f43f5e3d;pointer-events:none;transform:translate(-50%,-50%);animation:invalid-drop-ping 1.2s ease-out both}.connection-editor__drag-tip span{color:#7dd3fc;text-transform:uppercase;letter-spacing:.12em;font-size:.62rem;font-weight:800}.connection-editor__drag-tip strong{min-width:0;overflow:hidden;color:#f8fafc;font-size:.78rem;font-weight:900;text-overflow:ellipsis;white-space:nowrap}.connection-editor__drag-tip small{color:#94a3b8;font-size:.68rem;font-weight:700}.connection-editor__drag-tip--valid small{color:#86efac}.connection-editor__drag-tip--invalid span,.connection-editor__drag-tip--invalid small{color:#fda4af}.connection-editor__summary{grid-column:1;grid-row:3;display:grid;grid-template-columns:repeat(4,minmax(0,1fr));gap:10px}.connection-editor__side-panel{grid-column:2;grid-row:2 / 4;position:relative;z-index:8;min-width:0;min-height:0;display:grid;align-content:start;gap:14px;overflow:auto;padding-inline-end:4px;scrollbar-color:var(--pce-outline-strong) var(--pce-surface-soft)}.connection-editor__metric,.connection-editor__item{border-radius:16px;background:var(--pce-surface);border:1px solid var(--pce-outline);box-shadow:inset 0 1px var(--pce-glass-highlight);-webkit-backdrop-filter:blur(16px);backdrop-filter:blur(16px)}.connection-editor__metric{padding:10px;display:grid;gap:4px}.connection-editor__metric span{color:var(--pce-muted);font-size:.72rem}.connection-editor__metric strong,.connection-editor__details-row strong{color:var(--pce-strong);font-size:.9rem}.connection-editor__filters,.connection-editor__actions,.connection-editor__badges{display:flex;gap:8px;flex-wrap:wrap}.connection-editor__filter,.connection-editor__action{border:1px solid var(--pce-outline-strong);background:var(--pce-surface-soft);color:var(--pce-fg);border-radius:999px;padding:6px 10px;font-size:.75rem;font-weight:700;cursor:pointer}.connection-editor__filter--active,.connection-editor__action:hover{border-color:color-mix(in srgb,var(--pce-secondary) 62%,transparent);background:color-mix(in srgb,var(--pce-secondary) 16%,var(--pce-surface-soft));color:var(--pce-strong)}.connection-editor__action--danger{border-color:#f8717161;color:#fecaca}.connection-editor__item{width:100%;text-align:start;padding:12px;display:grid;gap:6px;cursor:pointer;color:inherit}.connection-editor__item--active{border-color:#a855f7b8;background:linear-gradient(90deg,#0ea5e91a,#a855f721)}.connection-editor__item-title{font-weight:800;color:#f8fafc;word-break:break-word}.connection-editor__badge{padding:3px 8px;border-radius:999px;background:#0ea5e92e;color:#bae6fd;font-size:.72rem;font-weight:800}.connection-editor__section{min-width:0;padding:14px;border-radius:18px;background:var(--pce-surface);border:1px solid var(--pce-outline);box-shadow:inset 0 1px var(--pce-glass-highlight),0 18px 50px var(--pce-shadow-soft);-webkit-backdrop-filter:blur(18px);backdrop-filter:blur(18px)}.connection-editor__badge--warning{background:#facc1524;color:#fde68a}.connection-editor__badge--error{background:#ef444424;color:#fecaca}.connection-editor__diagnostics{display:grid;gap:8px}.connection-editor__diagnostic{display:grid;gap:4px;padding:10px;border-radius:12px;border:1px solid var(--pce-outline);background:var(--pce-surface-soft);color:var(--pce-fg);font-size:.78rem;line-height:1.35}.connection-editor__diagnostic--warning{border-color:#f59e0b47;background:#f59e0b1a}.connection-editor__diagnostic--error{border-color:#ef44445c;background:#ef44441f}.connection-editor__diagnostic-severity{font-size:.68rem;font-weight:900;letter-spacing:.08em;text-transform:uppercase;color:#f8fafc}.connection-editor__suggestions{display:grid;gap:10px;margin-top:14px;padding-top:14px;border-top:1px solid var(--pce-outline)}.connection-editor__suggestion{display:grid;gap:8px;width:100%;padding:12px;border-radius:16px;border:1px solid color-mix(in srgb,var(--pce-secondary) 26%,transparent);background:linear-gradient(135deg,color-mix(in srgb,var(--pce-secondary) 12%,transparent),color-mix(in srgb,var(--pce-primary) 8%,transparent)),var(--pce-surface-strong);color:var(--pce-fg);text-align:start;cursor:pointer;transition:transform .16s ease,border-color .16s ease,background .16s ease}.connection-editor__suggestion:hover{transform:translateY(-1px);border-color:color-mix(in srgb,var(--pce-primary) 46%,transparent);background:linear-gradient(135deg,color-mix(in srgb,var(--pce-secondary) 18%,transparent),color-mix(in srgb,var(--pce-primary) 12%,transparent)),var(--pce-surface-strong)}.connection-editor__suggestion-route{display:grid;gap:4px;font-size:.78rem}.connection-editor__suggestion-route strong{color:var(--pce-strong);font-size:.82rem}.connection-editor__suggestion-reason{color:var(--pce-muted);font-size:.76rem;line-height:1.35}.connection-editor__suggestion-action{justify-self:start;padding:3px 8px;border-radius:999px;background:#22d3ee24;color:#67e8f9;font-size:.68rem;font-weight:900;letter-spacing:.06em;text-transform:uppercase}:host-context(.theme-light) .connection-editor__suggestion-action{background:color-mix(in srgb,var(--pce-primary) 12%,var(--pce-surface-soft));color:#075f73}.connection-editor__trace{display:grid;gap:10px;margin-top:14px;padding-top:14px;border-top:1px solid var(--pce-outline)}.connection-editor__trace-summary{color:var(--pce-muted);font-size:.78rem;line-height:1.35}.connection-editor__trace-step{display:grid;grid-template-columns:24px minmax(76px,auto) 1fr;gap:8px;align-items:center;padding:9px;border-radius:12px;border:1px solid rgba(34,211,238,.18);background:var(--pce-surface-soft);font-size:.76rem}.connection-editor__trace-step--blocked{border-color:#ef444457;background:#ef44441a}.connection-editor__trace-order{display:inline-grid;place-items:center;width:22px;height:22px;border-radius:999px;background:#22d3ee29;color:#67e8f9;font-weight:900}.connection-editor__trace-phase{color:var(--pce-strong);font-weight:900;text-transform:uppercase;letter-spacing:.06em;font-size:.66rem}.connection-editor__trace-copy{min-width:0;color:var(--pce-fg);word-break:break-word}.connection-editor__transform-steps{display:grid;gap:8px}.connection-editor__transform-step{display:grid;grid-template-columns:minmax(0,1fr) auto auto;gap:8px;align-items:center;padding:9px;border-radius:12px;border:1px solid rgba(168,85,247,.22);background:var(--pce-surface-soft)}.connection-editor__transform-kind{min-width:0;color:var(--pce-strong);font-weight:900;word-break:break-word}.connection-editor__transform-phase{color:var(--pce-muted);font-size:.68rem;font-weight:800;text-transform:uppercase;letter-spacing:.06em}.connection-editor__details-row,.connection-editor__details-block{display:grid;gap:6px}.connection-editor__rule-grid{display:grid;gap:10px}.connection-editor__rule-card{display:grid;gap:8px;padding:10px;border-radius:12px;border:1px solid var(--pce-outline);background:var(--pce-surface-soft)}.connection-editor__rule-heading{color:var(--pce-fg);font-size:.72rem;font-weight:900;text-transform:uppercase;letter-spacing:.06em}pre{margin:0;padding:12px;border-radius:12px;background:color-mix(in srgb,var(--pce-surface-strong) 82%,#020617);color:var(--pce-fg);overflow:auto;font-size:.75rem}@keyframes connection-flow{to{stroke-dashoffset:-38}}@keyframes drag-wire-pulse{0%,to{stroke-opacity:.76}50%{stroke-opacity:1}}@keyframes drag-halo-pulse{0%,to{stroke-opacity:.48}50%{stroke-opacity:.82}}@keyframes endpoint-pulse{0%,to{opacity:.78;transform:scale(1)}50%{opacity:1;transform:scale(1.25)}}@keyframes selected-wire-aura{0%,to{stroke-opacity:.46}50%{stroke-opacity:.92}}@keyframes wire-draw-in{0%{stroke-dashoffset:640;opacity:.32}70%{opacity:1}to{stroke-dashoffset:0;opacity:1}}@keyframes new-wire-halo{0%{stroke-opacity:0;stroke-width:30}28%{stroke-opacity:.78}to{stroke-opacity:0;stroke-width:12}}@keyframes new-dock-link-flash{0%{transform:translateY(-2px);box-shadow:0 16px 40px #0206175c,0 0 42px #fb923c47}to{transform:translateY(0)}}@keyframes trace-wire-pulse{0%,to{stroke-opacity:.78}50%{stroke-opacity:1}}@keyframes trace-halo-pulse{0%,to{stroke-opacity:.34}50%{stroke-opacity:.86}}@keyframes tooltip-rise{0%{opacity:0;transform:translateY(6px)}to{opacity:1;transform:translateY(0)}}@keyframes invalid-drop-jolt{0%,to{transform:translate(0)}28%{transform:translate(-3px)}56%{transform:translate(3px)}}@keyframes invalid-drop-ping{0%{opacity:1;transform:translate(-50%,-50%) scale(.72)}72%{opacity:.74;transform:translate(-50%,-50%) scale(1.35)}to{opacity:0;transform:translate(-50%,-50%) scale(1.8)}}@keyframes node-breathe{50%{transform:scale(1.035)}}@keyframes node-focus-breathe{0%,to{transform:scale(1)}50%{transform:scale(1.055)}}@keyframes trace-source-pulse{50%{transform:scale(1.04);box-shadow:0 0 0 3px #facc15db,0 0 0 22px #facc1514,0 0 64px #facc1557}}@keyframes trace-source-orbit{to{transform:rotate(360deg)}}@keyframes trace-reacting-pulse{50%{transform:scale(1.045);box-shadow:0 0 0 3px #22c55ead,0 0 62px #22c55e4d}}@keyframes segment-focus-sweep{0%,to{stroke-opacity:.82}50%{stroke-opacity:1}}@keyframes snap-pulse{50%{transform:scale(1.04)}}@keyframes port-focus-pulse{50%{transform:translateY(-1px);box-shadow:0 0 0 2px #facc158f,0 0 26px #facc153d}}@media(prefers-reduced-motion:reduce){.connection-editor__viewport,.connection-editor__node,.connection-editor__node-ring,.connection-editor__node-core,.connection-editor__node-segment,.connection-editor__dock-link,.connection-editor__port{transition-duration:1ms}.connection-editor__wire,.connection-editor__wire--state,.connection-editor__wire--projection,.connection-editor__wire--state-read,.connection-editor__wire--event-propagation,.connection-editor__wire--halo.connection-editor__wire--active,.connection-editor__wire--trace,.connection-editor__wire--halo.connection-editor__wire--trace,.connection-editor__wire-endpoint,.connection-editor__connection-tooltip,.connection-editor__dock-link--new,.connection-editor__trace-overlay,.connection-editor__trace-overlay-step,.connection-editor__drag-wire,.connection-editor__drag-wire--halo,.connection-editor__drag-endpoint,.connection-editor__drag-tip,.connection-editor__node-ring,.connection-editor__node--connection-focus .connection-editor__node-ring,.connection-editor__node--trace-source .connection-editor__node-ring,.connection-editor__node--trace-source:before,.connection-editor__node--trace-reacting .connection-editor__node-ring,.connection-editor__node--rotating .connection-editor__node-ring,.connection-editor__node-segment--connection-focus,.connection-editor__node-segment--compatible,.connection-editor__node-segment--invalid-drop,.connection-editor__segment-popover,.connection-editor__port--compatible,.connection-editor__port--invalid-drop,.connection-editor__port--connection-focus,.connection-editor__invalid-drop,.connection-editor__invalid-drop-pulse{animation:none}.connection-editor__wire{stroke-dashoffset:0}.connection-editor__wire--new{stroke-dasharray:10 8;stroke-dashoffset:0;opacity:1}.connection-editor__wire--halo.connection-editor__wire--new{stroke-width:12;stroke-opacity:.16}.connection-editor__wire-endpoint,.connection-editor__drag-endpoint,.connection-editor__node-ring,.connection-editor__node--trace-source:before{transform:none}.connection-editor__invalid-drop-pulse{opacity:0}}@media(max-width:900px){:host{inset:0}.connection-editor{inset:8px;height:calc(100vh - 16px);padding:12px;grid-template-columns:minmax(0,1fr);grid-template-rows:auto minmax(260px,1fr) auto minmax(150px,30vh) minmax(86px,126px)}.connection-editor__header,.connection-editor__stage,.connection-editor__summary,.connection-editor__side-panel,.connection-editor__dock{grid-column:1}.connection-editor__header{align-items:stretch;flex-wrap:wrap;border-radius:18px}.connection-editor__mode-frame{order:3;width:100%;max-width:100%}.connection-editor__mode-frame:before,.connection-editor__mode-frame:after{content:\"\";position:absolute;z-index:2;inset-block:4px;width:24px;border-radius:999px;pointer-events:none}.connection-editor__mode-frame:before{inset-inline-start:1px;background:linear-gradient(90deg,#080d18f0,#080d1800)}.connection-editor__mode-frame:after{inset-inline-end:1px;background:linear-gradient(270deg,#080d18f0,#080d1800)}.connection-editor__mode-shell{width:100%;max-width:100%;overflow-x:auto;scroll-padding-inline:28px;-webkit-overflow-scrolling:touch}.connection-editor__subtitle{margin-inline-start:auto}.connection-editor__stage{grid-row:2;min-height:260px}.connection-editor__summary{grid-row:3;grid-template-columns:1fr 1fr}.connection-editor__side-panel{grid-row:4;max-height:30vh}.connection-editor__dock{grid-row:5;min-height:0}.connection-editor__connection-tooltip{width:min(620px,calc(100% - 24px));max-height:min(260px,calc(100% - 24px));overflow:auto}.connection-editor__dock-tabs{width:100%;min-width:0;min-height:0;flex-wrap:wrap;align-items:flex-start}.connection-editor__dock-count{flex:1 1 100%;margin-inline-start:0}.connection-editor__dock-body{width:100%;min-width:0;max-height:76px;box-sizing:border-box}.connection-editor__dock-body pre{white-space:pre-wrap;overflow-wrap:anywhere}.connection-editor__dock-link{grid-template-columns:1fr;align-items:start}.connection-editor__dock-link-route{flex-wrap:wrap}.connection-editor__dock-link-badges{justify-content:flex-start}.connection-editor__trace-overlay{inset-inline-start:14px;width:min(420px,calc(100% - 28px));min-width:0;transform:none}.connection-editor__drag-tip{width:min(300px,calc(100% - 28px))}.connection-editor__segment-popover{width:min(280px,calc(100% - 28px));max-height:min(280px,calc(100% - 28px))}.connection-editor__minimap{inset-inline-end:10px;inset-block-end:10px;width:132px;height:94px;padding:16px 8px 8px;border-radius:14px}.connection-editor__minimap:before{inset:20px 8px 8px;background-size:18px 18px}.connection-editor__minimap-title{inset-block-start:6px;inset-inline-start:10px;font-size:.54rem}}@media(max-width:640px){.connection-editor{inset:4px;height:calc(100vh - 8px);padding:8px;gap:8px;grid-template-rows:auto minmax(240px,1fr) auto minmax(140px,28vh) minmax(82px,116px)}.connection-editor__header{gap:8px;padding:10px}.connection-editor__mode-shell{padding:4px;gap:2px}.connection-editor__mode{min-height:28px;gap:4px;padding:0 7px;font-size:.68rem}.connection-editor__mode-glyph{font-size:.64rem}.connection-editor__stage{min-height:240px}.connection-editor__zoom-controls{inset-inline-start:8px;inset-block-start:8px;gap:6px;width:126px}.connection-editor__tool-group,.connection-editor__trace-source{gap:6px;padding:8px;border-radius:12px}.connection-editor__tool-group{grid-template-columns:repeat(3,28px)}.connection-editor__tool-group:nth-of-type(2){grid-template-columns:repeat(2,28px)}.connection-editor__tool-button{width:28px;height:28px}.connection-editor__arrange-button,.connection-editor__simulate-button{min-height:30px;gap:6px;padding-inline:8px;font-size:.68rem}.connection-editor__summary{gap:6px}.connection-editor__side-panel{max-height:28vh}.connection-editor__dock{border-radius:16px}.connection-editor__dock-tabs{gap:4px}.connection-editor__dock-tab{padding:0 9px}.connection-editor__dock-count{font-size:.62rem}.connection-editor__dock-body{max-height:66px;padding:8px}.connection-editor__minimap{width:116px;height:84px}.connection-editor__segment-row{grid-template-columns:24px minmax(54px,.55fr) minmax(0,1fr) auto}}\n"], dependencies: [{ kind: "ngmodule", type: CommonModule }, { kind: "pipe", type: i2$1.JsonPipe, name: "json" }], changeDetection: i0.ChangeDetectionStrategy.OnPush });
7360
+ `, isInline: true, styles: [":host{position:fixed;inset:0;z-index:1000;pointer-events:none}.connection-editor{--pce-fg: var(--md-sys-color-on-surface, #dce6f4);--pce-strong: var(--md-sys-color-on-surface, #f8fafc);--pce-muted: var(--md-sys-color-on-surface-variant, #94a3b8);--pce-primary: var(--md-sys-color-primary, #19c8e8);--pce-secondary: var(--md-sys-color-secondary, #b46cff);--pce-tertiary: var(--md-sys-color-tertiary, #ff9f2f);--pce-success: var(--md-sys-color-tertiary, #10b981);--pce-warning: var(--md-sys-color-error, #ff9f2f);--pce-error: var(--md-sys-color-error, #ef4444);--pce-surface-base: color-mix(in srgb, var(--md-sys-color-surface, #07111f) 80%, #020617);--pce-surface: color-mix(in srgb, var(--md-sys-color-surface-container, #08101d) 78%, transparent);--pce-surface-strong: color-mix(in srgb, var(--md-sys-color-surface-container-high, #0f172a) 88%, transparent);--pce-surface-soft: color-mix(in srgb, var(--md-sys-color-surface-container-low, #080d18) 64%, transparent);--pce-outline: color-mix(in srgb, var(--md-sys-color-outline-variant, #899ab7) 46%, transparent);--pce-outline-strong: color-mix(in srgb, var(--md-sys-color-outline, #94a3b8) 58%, transparent);--pce-grid: color-mix(in srgb, var(--md-sys-color-outline-variant, #7d8fa9) 24%, transparent);--pce-glass-highlight: color-mix(in srgb, var(--md-sys-color-on-surface, #ffffff) 8%, transparent);--pce-shadow: color-mix(in srgb, #000 56%, transparent);--pce-shadow-soft: color-mix(in srgb, #000 30%, transparent);--pce-stage-bg: color-mix(in srgb, var(--md-sys-color-surface-container-lowest, #040a13) 42%, transparent);--pce-dock-bg: color-mix(in srgb, var(--md-sys-color-surface-container-high, #050912) 94%, transparent);position:absolute;inset:12px;height:calc(100vh - 24px);box-sizing:border-box;overflow:hidden;padding:16px;border-radius:18px;color:var(--pce-fg);background:radial-gradient(circle at 72% 20%,color-mix(in srgb,var(--pce-secondary) 16%,transparent),transparent 28%),radial-gradient(circle at 26% 74%,color-mix(in srgb,var(--pce-primary) 10%,transparent),transparent 34%),radial-gradient(circle at 48% 52%,color-mix(in srgb,var(--pce-tertiary) 5%,transparent),transparent 35%),linear-gradient(var(--pce-grid) 1px,transparent 1px),linear-gradient(90deg,var(--pce-grid) 1px,transparent 1px),var(--pce-surface-base);background-size:auto,auto,auto,38px 38px,38px 38px,auto;border:1px solid var(--pce-outline);box-shadow:0 28px 90px var(--pce-shadow);pointer-events:auto;display:grid;grid-template-columns:minmax(0,1fr) minmax(300px,380px);grid-template-rows:auto minmax(0,1fr) auto minmax(48px,140px);gap:14px}:host-context(.theme-light) .connection-editor{--pce-surface-base: color-mix(in srgb, var(--md-sys-color-surface, #ffffff) 94%, var(--md-sys-color-primary, #2563eb) 6%);--pce-surface: color-mix(in srgb, var(--md-sys-color-surface-container, #f8fafc) 82%, transparent);--pce-surface-strong: color-mix(in srgb, var(--md-sys-color-surface-container-high, #eef2ff) 88%, transparent);--pce-surface-soft: color-mix(in srgb, var(--md-sys-color-surface-container-low, #f8fafc) 70%, transparent);--pce-outline: color-mix(in srgb, var(--md-sys-color-outline-variant, #cbd5e1) 68%, transparent);--pce-outline-strong: color-mix(in srgb, var(--md-sys-color-outline, #64748b) 62%, transparent);--pce-grid: color-mix(in srgb, var(--md-sys-color-outline-variant, #cbd5e1) 34%, transparent);--pce-glass-highlight: color-mix(in srgb, #fff 64%, transparent);--pce-shadow: color-mix(in srgb, var(--md-sys-color-shadow, #64748b) 22%, transparent);--pce-shadow-soft: color-mix(in srgb, var(--md-sys-color-shadow, #64748b) 14%, transparent);--pce-stage-bg: color-mix(in srgb, var(--md-sys-color-surface-container-lowest, #ffffff) 58%, transparent);--pce-dock-bg: color-mix(in srgb, var(--md-sys-color-surface-container, #f8fafc) 92%, transparent)}.connection-editor__header{grid-column:1 / -1;display:flex;align-items:center;justify-content:space-between;gap:16px;min-height:42px;padding:8px 14px;border-radius:999px;background:var(--pce-surface);border:1px solid var(--pce-outline);box-shadow:inset 0 1px var(--pce-glass-highlight);-webkit-backdrop-filter:blur(18px);backdrop-filter:blur(18px)}.connection-editor__mode-frame{position:relative;min-width:0}.connection-editor__mode-shell{display:inline-flex;align-items:center;gap:4px;min-width:0;padding:4px;border-radius:999px;border:1px solid var(--pce-outline);background:linear-gradient(180deg,var(--pce-surface-strong),var(--pce-surface));box-shadow:inset 0 1px var(--pce-glass-highlight),0 10px 26px var(--pce-shadow-soft);scrollbar-width:none}.connection-editor__mode-shell::-webkit-scrollbar{display:none}.connection-editor__mode{min-height:30px;display:inline-flex;align-items:center;gap:7px;padding:0 12px;border:1px solid transparent;border-radius:999px;background:transparent;color:var(--pce-muted);cursor:pointer;font-size:.76rem;font-weight:800;white-space:nowrap;transition:background .16s ease,border-color .16s ease,color .16s ease,box-shadow .16s ease}.connection-editor__mode:hover,.connection-editor__mode--active{color:var(--pce-strong);border-color:color-mix(in srgb,var(--pce-primary) 28%,transparent);background:color-mix(in srgb,var(--pce-surface-strong) 82%,transparent);box-shadow:0 0 18px color-mix(in srgb,var(--pce-primary) 12%,transparent)}.connection-editor__mode-glyph{color:var(--pce-muted);font-family:ui-monospace,SFMono-Regular,Menlo,Monaco,Consolas,Liberation Mono,monospace;font-size:.72rem;font-weight:900}.connection-editor__mode--active .connection-editor__mode-glyph{color:var(--pce-primary)}.connection-editor__mode-dot{width:6px;height:6px;border-radius:999px;background:var(--pce-success);box-shadow:0 0 12px color-mix(in srgb,var(--pce-success) 70%,transparent)}.connection-editor__status-pill{display:inline-flex;align-items:center;gap:8px;min-height:24px;padding:0 12px;border-radius:999px;border:1px solid color-mix(in srgb,var(--pce-primary) 36%,transparent);background:var(--pce-surface-soft);color:var(--pce-muted);font-size:.72rem;font-weight:800;white-space:nowrap}.connection-editor__status-pill span{width:6px;height:6px;border-radius:999px;background:var(--pce-primary);box-shadow:0 0 12px color-mix(in srgb,var(--pce-primary) 70%,transparent)}.connection-editor__section{display:grid;gap:10px}.connection-editor__dock{grid-column:1 / -1;grid-row:4;position:relative;z-index:4;min-height:0;display:grid;border-radius:14px;border:1px solid var(--pce-outline);background:radial-gradient(circle at 16% 0%,color-mix(in srgb,var(--pce-primary) 22%,transparent),transparent 34%),radial-gradient(circle at 78% 0%,color-mix(in srgb,var(--pce-secondary) 25%,transparent),transparent 38%),linear-gradient(90deg,var(--pce-dock-bg),var(--pce-surface-strong) 46%,color-mix(in srgb,var(--pce-secondary) 14%,var(--pce-dock-bg))),var(--pce-dock-bg);box-shadow:0 18px 58px var(--pce-shadow-soft),inset 0 1px var(--pce-glass-highlight);overflow:hidden;-webkit-backdrop-filter:blur(18px);backdrop-filter:blur(18px)}.connection-editor__dock--collapsed .connection-editor__dock-tabs{border-block-end:0}.connection-editor__dock-tabs{display:flex;align-items:center;gap:10px;min-height:52px;padding:9px 14px;border-block-end:1px solid var(--pce-outline);background:linear-gradient(180deg,var(--pce-glass-highlight),transparent),color-mix(in srgb,var(--pce-surface-soft) 34%,transparent)}.connection-editor__dock-tab,.connection-editor__dock-toggle{min-height:30px;border-radius:999px;border:1px solid transparent;background:transparent;color:var(--pce-muted);cursor:pointer;font-size:.72rem;font-weight:900;letter-spacing:.14em;text-transform:uppercase;transition:border-color .15s ease,background .15s ease,color .15s ease,box-shadow .15s ease,transform .15s ease}.connection-editor__dock-tab{display:inline-flex;align-items:center;gap:8px;padding:0 13px;white-space:nowrap}.connection-editor__dock-tab-glyph{color:var(--pce-muted);font-family:ui-monospace,SFMono-Regular,Consolas,Liberation Mono,monospace;font-size:.8rem;letter-spacing:0;text-transform:none}.connection-editor__dock-tab--active{color:var(--pce-strong);border-color:var(--pce-outline-strong);background:linear-gradient(180deg,color-mix(in srgb,var(--pce-strong) 14%,transparent),color-mix(in srgb,var(--pce-strong) 6%,transparent));box-shadow:0 0 0 1px color-mix(in srgb,var(--pce-shadow) 72%,transparent),0 0 22px color-mix(in srgb,var(--pce-strong) 8%,transparent),inset 0 1px var(--pce-glass-highlight)}.connection-editor__dock-tab--active .connection-editor__dock-tab-glyph{color:var(--pce-strong)}.connection-editor__dock-count{margin-inline-start:auto;color:color-mix(in srgb,var(--pce-muted) 62%,transparent);font-size:.7rem;font-weight:800;letter-spacing:.16em;text-transform:uppercase;white-space:nowrap}.connection-editor__dock-toggle{width:32px;padding:0;border-color:var(--pce-outline);background:var(--pce-surface-soft);color:var(--pce-muted);font-size:.88rem;letter-spacing:0}.connection-editor__dock-body{max-height:154px;overflow:auto;padding:12px 12px 14px;border-block-start:1px solid var(--pce-outline);background:linear-gradient(90deg,color-mix(in srgb,var(--pce-primary) 9%,transparent),color-mix(in srgb,var(--pce-secondary) 10%,transparent) 62%,color-mix(in srgb,var(--pce-surface-strong) 18%,transparent)),color-mix(in srgb,var(--pce-surface-soft) 30%,transparent)}.connection-editor__dock-body pre{max-height:60px}.connection-editor__dock-links{display:grid;gap:8px}.connection-editor__dock-link-row{display:grid;grid-template-columns:minmax(0,1fr) auto;align-items:center;gap:10px;width:100%;padding:7px 10px;border-radius:10px;border:1px solid var(--pce-outline);background:linear-gradient(90deg,var(--pce-surface-soft),color-mix(in srgb,var(--pce-secondary) 10%,var(--pce-surface-soft)) 72%,var(--pce-surface-soft)),var(--pce-surface-soft);color:var(--pce-fg);transition:border-color .15s ease,background .15s ease,box-shadow .15s ease,transform .15s ease}.connection-editor__dock-link{display:grid;grid-template-columns:minmax(116px,.52fr) minmax(300px,1.72fr) minmax(160px,.9fr) auto;align-items:center;gap:12px;width:100%;min-height:42px;padding:0;border:0;border-radius:8px;background:transparent;color:inherit;cursor:pointer;text-align:start}.connection-editor__dock-link-row:hover,.connection-editor__dock-link--active{transform:translateY(-1px);border-color:color-mix(in srgb,var(--pce-primary) 42%,transparent);background:linear-gradient(90deg,color-mix(in srgb,var(--pce-primary) 13%,transparent),color-mix(in srgb,var(--pce-secondary) 16%,transparent),var(--pce-surface-strong)),var(--pce-surface-strong);box-shadow:0 12px 32px var(--pce-shadow-soft),inset 0 0 18px color-mix(in srgb,var(--pce-primary) 6%,transparent)}.connection-editor__dock-link--active{border-color:#facc1575;box-shadow:0 12px 32px var(--pce-shadow-soft),0 0 24px #facc151f}.connection-editor__dock-link--new{border-color:#fb923ca3;background:linear-gradient(90deg,#fb923c2e,#a855f729,#0ea5e91f),#0f172ac2;box-shadow:0 12px 34px #02061752,0 0 30px #fb923c2e;animation:new-dock-link-flash 1.35s ease-out forwards}.connection-editor__dock-link--error{border-color:#ef444461}.connection-editor__dock-jump{min-width:62px;min-height:30px;padding:0 10px;border-radius:999px;border:1px solid color-mix(in srgb,var(--pce-primary) 28%,transparent);background:color-mix(in srgb,var(--pce-surface-soft) 54%,transparent);color:var(--pce-primary);cursor:pointer;font-size:.66rem;font-weight:900;letter-spacing:.06em;text-transform:uppercase;transition:border-color .15s ease,background .15s ease,color .15s ease,box-shadow .15s ease}.connection-editor__dock-jump:hover,.connection-editor__dock-jump:focus-visible{border-color:color-mix(in srgb,var(--pce-primary) 56%,transparent);background:color-mix(in srgb,var(--pce-primary) 16%,transparent);color:var(--pce-strong);box-shadow:0 0 18px color-mix(in srgb,var(--pce-primary) 18%,transparent);outline:none}.connection-editor__dock-link-kind{display:inline-flex;align-items:center;gap:7px;min-width:0;color:var(--pce-muted);font-size:.66rem;font-weight:900;letter-spacing:.1em;text-transform:uppercase;white-space:nowrap}.connection-editor__dock-link-kind span{width:8px;height:8px;border-radius:999px;background:#b46cff;box-shadow:0 0 14px #b46cff7a}.connection-editor__dock-link--state .connection-editor__dock-link-kind span{background:#ff9f2f;box-shadow:0 0 16px #ff9f2f94}.connection-editor__dock-link--state-read .connection-editor__dock-link-kind span{background:#8b7dff;box-shadow:0 0 13px #8b7dff75}.connection-editor__dock-link--projection .connection-editor__dock-link-kind span{background:#19c8e8;box-shadow:0 0 10px #19c8e857}.connection-editor__dock-link--event-propagation .connection-editor__dock-link-kind span{background:#ffb454;box-shadow:0 0 15px #ffb45485}.connection-editor__dock-link--policy .connection-editor__dock-link-kind span{outline:1px solid rgba(34,197,94,.76);outline-offset:2px;box-shadow:0 0 16px #22c55e61}.connection-editor__dock-link--policy:not(.connection-editor__dock-link--state,.connection-editor__dock-link--state-read,.connection-editor__dock-link--projection,.connection-editor__dock-link--event-propagation) .connection-editor__dock-link-kind span{background:#22c55e}.connection-editor__dock-link-route{display:inline-flex;align-items:center;gap:8px;min-width:0}.connection-editor__dock-link-chip{min-width:0;overflow:hidden;padding:4px 8px;border-radius:999px;border:1px solid var(--pce-outline);background:color-mix(in srgb,var(--pce-surface-soft) 72%,transparent);color:var(--pce-fg);font-size:.72rem;font-weight:900;text-overflow:ellipsis;white-space:nowrap}.connection-editor__dock-link-chip--from{border-color:#ff9f2f66;color:#ffbd62}.connection-editor__dock-link-chip--to{border-color:#19c8e83d;color:#7dddeb}:host-context(.theme-light) .connection-editor__dock-link-chip--from{border-color:color-mix(in srgb,var(--pce-tertiary) 46%,transparent);color:#8a4600}:host-context(.theme-light) .connection-editor__dock-link-chip--to{border-color:color-mix(in srgb,var(--pce-primary) 34%,transparent);color:#075f73}.connection-editor__dock-link-arrow{flex:0 0 auto;color:var(--pce-muted);font-weight:900}.connection-editor__dock-link-id{min-width:0;overflow:hidden;color:var(--pce-muted);font-size:.66rem;font-weight:800;font-family:ui-monospace,SFMono-Regular,Consolas,Liberation Mono,monospace;text-overflow:ellipsis;white-space:nowrap}.connection-editor__dock-link-badges{display:inline-flex;justify-content:flex-end;gap:5px;min-width:70px}.connection-editor__dock-link-badges span{padding:3px 7px;border-radius:999px;background:#a855f724;color:#d8b4fe;font-size:.62rem;font-weight:900;text-transform:uppercase;white-space:nowrap}:host-context(.theme-light) .connection-editor__dock-link-badges span{background:color-mix(in srgb,var(--pce-secondary) 14%,var(--pce-surface-soft));color:#6d2a9f}.connection-editor__dock-empty{padding:12px;border-radius:12px;border:1px dashed var(--pce-outline);color:var(--pce-muted);font-size:.76rem;font-weight:700}.connection-editor__inspector{border-color:color-mix(in srgb,var(--pce-primary) 26%,transparent);background:linear-gradient(135deg,color-mix(in srgb,var(--pce-primary) 10%,transparent),color-mix(in srgb,var(--pce-secondary) 8%,transparent)),var(--pce-surface)}.connection-editor__eyebrow,.connection-editor__section-title{font-size:.72rem;text-transform:uppercase;letter-spacing:.16em;color:var(--pce-muted);font-weight:700}.connection-editor__title{font-size:1.02rem;font-weight:800}.connection-editor__subtitle,.connection-editor__item-copy,.connection-editor__item-meta,.connection-editor__details-row span,.connection-editor__details-label,.connection-editor__empty{color:var(--pce-muted);font-size:.84rem}.connection-editor__inspector-heading{display:grid;gap:4px;padding:10px 12px;border-radius:14px;background:var(--pce-surface-soft);border:1px solid var(--pce-outline)}.connection-editor__inspector-heading strong{color:var(--pce-strong);font-size:.96rem;overflow-wrap:anywhere}.connection-editor__inspector-heading span{color:var(--pce-primary);font-size:.76rem;font-weight:800;text-transform:uppercase;letter-spacing:.1em}.connection-editor__inspector-ports{display:flex;flex-wrap:wrap;gap:6px}.connection-editor__inspector-port{max-width:100%;padding:4px 8px;border-radius:999px;border:1px solid rgba(148,163,184,.16);background:#0f172a94;color:#cbd5e1;font-size:.68rem;font-weight:800;overflow:hidden;text-overflow:ellipsis;white-space:nowrap}.connection-editor__inspector-port--input{border-color:#22d3ee57;color:#67e8f9}.connection-editor__inspector-port--output{border-color:#f59e0b57;color:#fbbf24}.connection-editor__inspector-port--state{border-color:#a855f761;color:#d8b4fe}.connection-editor__segment-kind-legend{display:grid;gap:10px;padding:12px;border-radius:16px;border:1px solid rgba(148,163,184,.14);background:linear-gradient(135deg,#0f172aa8,#080d1885),#02061757}.connection-editor__segment-kind-grid{display:grid;grid-template-columns:repeat(3,minmax(0,1fr));gap:8px}.connection-editor__segment-kind-pill{min-width:0;display:inline-flex;align-items:center;justify-content:center;gap:6px;min-height:28px;padding:0 8px;border-radius:999px;border:1px solid rgba(148,163,184,.14);background:#0f172a94;color:#cbd5e1;font-size:.68rem;font-weight:900;overflow:hidden;white-space:nowrap}.connection-editor__segment-kind-pill span{width:8px;height:8px;flex:0 0 auto;border-radius:999px;background:currentColor;box-shadow:0 0 12px currentColor}.connection-editor__segment-kind-pill--input{border-color:#19c8e83d;color:#7dddeb}.connection-editor__segment-kind-pill--output{border-color:#ff9f2f61;color:#ffbd62}.connection-editor__segment-kind-pill--state{border-color:#b46cff61;color:#d9b8ff}:host-context(.theme-light) .connection-editor__segment-kind-pill{border-color:var(--pce-outline);background:color-mix(in srgb,var(--pce-surface-strong) 88%,transparent)}:host-context(.theme-light) .connection-editor__segment-kind-pill--input{color:#075f73}:host-context(.theme-light) .connection-editor__segment-kind-pill--output{color:#8a4600}:host-context(.theme-light) .connection-editor__segment-kind-pill--state{color:#6d2a9f}.connection-editor__stage{grid-column:1;grid-row:2;position:relative;min-height:0;height:100%;overflow:visible;border-radius:16px;border:1px solid var(--pce-outline);background:radial-gradient(circle at center,color-mix(in srgb,var(--pce-secondary) 7%,transparent),transparent 38%),radial-gradient(circle,var(--pce-grid) 1px,transparent 1.5px),var(--pce-stage-bg);background-size:auto,31px 31px,auto;box-shadow:inset 0 0 0 1px var(--pce-glass-highlight);cursor:grab;touch-action:none}.connection-editor__stage--panning,.connection-editor__stage:active{cursor:grabbing}.connection-editor__stage--dragging{cursor:crosshair}.connection-editor__stage--rotating{cursor:grabbing}.connection-editor__viewport{position:absolute;inset-block-start:0;inset-inline-start:0;width:900px;height:540px;overflow:visible;transform-origin:0 0;transition:transform .14s ease}.connection-editor__wires{position:absolute;inset:0;width:100%;height:100%;overflow:visible}.connection-editor__wire,.connection-editor__wire-hit{fill:none;stroke-linecap:round}.connection-editor__wire{stroke:#b46cff;stroke-width:1.45;stroke-opacity:.48;pointer-events:none;filter:url(#connection-glow);stroke-dasharray:10 8;animation:connection-flow 1.65s linear infinite}.connection-editor__wire-hit{stroke:transparent;stroke-width:18;cursor:pointer;pointer-events:stroke}.connection-editor__wire-hit--active{stroke-width:28}.connection-editor__wire--halo{stroke:#b46cff1f;stroke-width:7;stroke-dasharray:none;animation:none}.connection-editor__wire--state{stroke:#ff9f2f;stroke-width:2.25;stroke-dasharray:8 7;animation:connection-flow .92s linear infinite}.connection-editor__wire--state.connection-editor__wire--halo{stroke:#ff9f2f29;stroke-width:11}.connection-editor__wire--projection{stroke:#15b8d8;stroke-width:1.75;stroke-dasharray:20 8;animation:connection-flow 1.9s linear infinite}.connection-editor__wire--projection.connection-editor__wire--halo{stroke:#15b8d81a;stroke-width:7}.connection-editor__wire--state-read{stroke:#8b7dff;stroke-width:1.65;stroke-dasharray:3 11;animation:connection-flow 2.25s linear infinite reverse}.connection-editor__wire--state-read.connection-editor__wire--halo{stroke:#8b7dff21;stroke-width:8}.connection-editor__wire--event-propagation{stroke:#ffb454;stroke-width:2.05;stroke-dasharray:5 7;animation:connection-flow .78s linear infinite}.connection-editor__wire--event-propagation.connection-editor__wire--halo{stroke:#ffb4542e;stroke-width:10}.connection-editor__wire--policy{filter:drop-shadow(0 0 6px rgba(34,197,94,.2)) url(#connection-glow)}.connection-editor__wire--policy.connection-editor__wire--halo{stroke:#22c55e1f;stroke-width:13}.connection-editor__wire--warning{stroke:#ff9f2f}.connection-editor__wire--warning.connection-editor__wire--halo{stroke:#ff9f2f2e}.connection-editor__wire--error{stroke:#ef4444}.connection-editor__wire--error.connection-editor__wire--halo{stroke:#ef44442e}.connection-editor__wire--active{stroke:#d9b8ff;stroke-width:3;stroke-opacity:1;stroke-dasharray:5 7;animation-duration:.58s}.connection-editor__wire--halo.connection-editor__wire--active{stroke-width:16;stroke-opacity:.8;animation:selected-wire-aura 1.35s ease-in-out infinite}.connection-editor__wire--new{stroke-width:3.4;stroke-opacity:1;stroke-dasharray:640;stroke-dashoffset:640;animation:wire-draw-in .62s cubic-bezier(.16,1,.3,1) forwards,connection-flow 1.05s linear .62s infinite}.connection-editor__wire--halo.connection-editor__wire--new{stroke-width:22;stroke-opacity:0;animation:new-wire-halo 1.45s ease-out forwards}.connection-editor__wire--trace{stroke:#9b5cff;stroke-width:3.2;stroke-opacity:1;stroke-dasharray:7 6;animation:connection-flow .72s linear infinite,trace-wire-pulse 1.18s ease-in-out infinite}.connection-editor__wire--halo.connection-editor__wire--trace{stroke:#9b5cff57;stroke-width:18;stroke-opacity:.86;animation:trace-halo-pulse 1.18s ease-in-out infinite}.connection-editor__wire--mode-dimmed{stroke-opacity:.14;stroke-width:1.05;filter:none;animation-duration:2.6s}.connection-editor__wire--halo.connection-editor__wire--mode-dimmed{stroke-opacity:.05;stroke-width:5;animation:none}.connection-editor__wire-hit--mode-dimmed{stroke-width:12}.connection-editor__wire-endpoint{fill:#f8fafc;stroke:#0f172ae6;stroke-width:1.5;filter:drop-shadow(0 0 8px rgba(216,180,254,.8));pointer-events:none;animation:endpoint-pulse 1.2s ease-in-out infinite}.connection-editor__wire-endpoint--source{fill:#ff9f2f}.connection-editor__wire-endpoint--target{fill:#19c8e8}.connection-editor__connection-tooltip{position:absolute;z-index:6;width:min(312px,calc(100% - 24px));display:grid;gap:8px;padding:12px 14px;border-radius:14px;border:1px solid var(--pce-outline);background:linear-gradient(135deg,var(--pce-surface-strong),var(--pce-surface)),var(--pce-surface-strong);box-shadow:0 18px 44px var(--pce-shadow-soft),inset 0 1px var(--pce-glass-highlight);color:var(--pce-fg);pointer-events:none;-webkit-backdrop-filter:blur(18px);backdrop-filter:blur(18px);animation:tooltip-rise .14s ease-out}.connection-editor__connection-tooltip-callout{position:absolute;inset-block-start:100%;inset-inline-start:var(--connection-tooltip-callout-x, 42px);width:2px;height:28px;border-radius:999px;background:linear-gradient(180deg,#e2e8f0bd,#19c8e800);box-shadow:0 0 12px #19c8e852;transform:translate(-1px);pointer-events:none}.connection-editor__connection-tooltip-callout:before,.connection-editor__connection-tooltip-callout:after{content:\"\";position:absolute;border-radius:999px;pointer-events:none}.connection-editor__connection-tooltip-callout:before{inset-block-start:-5px;inset-inline-start:-5px;width:12px;height:12px;border:1px solid rgba(148,163,184,.24);background:#080d18f5;box-shadow:inset 0 1px #ffffff14}.connection-editor__connection-tooltip-callout:after{inset-block-end:-3px;inset-inline-start:-4px;width:10px;height:10px;background:#19c8e8;box-shadow:0 0 16px #19c8e88f}.connection-editor__connection-tooltip--projection{border-color:#19c8e833;background:linear-gradient(135deg,#15b8d81f,#0f172ae0),#070c16eb}.connection-editor__connection-tooltip--state{border-color:#ff9f2f66;background:linear-gradient(135deg,#ff9f2f3d,#0f172ae0),#070c16eb}.connection-editor__connection-tooltip--state .connection-editor__connection-tooltip-callout{background:linear-gradient(180deg,#ffbd62d1,#ff9f2f00);box-shadow:0 0 14px #ff9f2f61}.connection-editor__connection-tooltip--state .connection-editor__connection-tooltip-callout:after{background:#ff9f2f;box-shadow:0 0 18px #ff9f2fad}.connection-editor__connection-tooltip--error{border-color:#f871716b}.connection-editor__connection-tooltip--error .connection-editor__connection-tooltip-callout:after{background:#fb7185;box-shadow:0 0 18px #fb7185ad}.connection-editor__connection-tooltip-kind{display:inline-flex;align-items:center;gap:8px;color:#94a3b8;font-size:.62rem;font-weight:900;letter-spacing:.16em;text-transform:uppercase}.connection-editor__connection-tooltip-kind span{width:8px;height:8px;border-radius:999px;background:#19c8e8;box-shadow:0 0 12px #19c8e880}.connection-editor__connection-tooltip--state .connection-editor__connection-tooltip-kind span{background:#ff9f2f;box-shadow:0 0 16px #ff9f2fc7}.connection-editor__connection-tooltip-row{min-width:0;display:grid;grid-template-columns:54px minmax(0,1fr);align-items:center;gap:8px;min-height:28px;padding:0 10px;border-radius:999px;background:#0f172a94}.connection-editor__connection-tooltip-row span{color:#8d9bb0;font-size:.62rem;font-weight:900;letter-spacing:.12em;text-transform:uppercase}.connection-editor__connection-tooltip-row strong{min-width:0;overflow:hidden;color:#e2e8f0;font-size:.75rem;font-weight:900;text-overflow:ellipsis;white-space:nowrap}.connection-editor__connection-tooltip-badges{display:flex;flex-wrap:wrap;gap:6px}.connection-editor__connection-tooltip-badges span{padding:3px 8px;border-radius:999px;background:#02061799;color:#fbbf24;font-size:.66rem;font-weight:900}.connection-editor__trace-overlay{position:absolute;z-index:6;inset-block-start:16px;inset-inline-start:50%;width:min(560px,calc(100% - 360px));min-width:320px;padding:12px 14px;border-radius:16px;border:1px solid rgba(34,197,94,.26);background:linear-gradient(135deg,#22c55e1f,#0ea5e91a),#080d18f0;box-shadow:0 22px 56px #02061775,0 0 42px #22c55e1f;transform:translate(-50%);pointer-events:auto;-webkit-backdrop-filter:blur(18px);backdrop-filter:blur(18px);animation:tooltip-rise .16s ease-out}.connection-editor__trace-overlay-head,.connection-editor__trace-overlay-route{display:flex;align-items:center;justify-content:space-between;gap:12px;min-width:0}.connection-editor__trace-overlay-head span,.connection-editor__trace-overlay-route span{color:#86efac;font-size:.66rem;font-weight:900;letter-spacing:.12em;text-transform:uppercase;white-space:nowrap}.connection-editor__trace-overlay-head strong{color:#cbd5e1;font-size:.7rem;font-weight:900;font-family:ui-monospace,SFMono-Regular,Consolas,Liberation Mono,monospace}.connection-editor__trace-overlay-route{margin-top:6px}.connection-editor__trace-overlay-controls{display:grid;grid-template-columns:28px minmax(0,1fr) 28px;align-items:center;gap:8px;margin-top:10px}.connection-editor__trace-overlay-button{width:28px;height:24px;display:inline-grid;place-items:center;border:1px solid rgba(148,163,184,.18);border-radius:999px;background:#0206176b;color:#e2e8f0;cursor:pointer;font-size:1rem;font-weight:900;line-height:1;transition:border-color .15s ease,background .15s ease,color .15s ease,opacity .15s ease}.connection-editor__trace-overlay-button:hover:not(:disabled){border-color:#22d3ee6b;background:#0ea5e929;color:#f8fafc}.connection-editor__trace-overlay-button:disabled{cursor:default;opacity:.36}.connection-editor__trace-overlay-steps{min-width:0;display:flex;align-items:center;gap:6px;overflow-x:auto;padding:2px;scrollbar-width:none}.connection-editor__trace-overlay-steps::-webkit-scrollbar{display:none}.connection-editor__trace-overlay-step{position:relative;flex:1 0 28px;min-width:28px;height:22px;border:1px solid rgba(148,163,184,.16);border-radius:999px;background:#0f172a9e;color:#94a3b8;cursor:pointer;font-size:.62rem;font-weight:900;font-family:ui-monospace,SFMono-Regular,Consolas,Liberation Mono,monospace;transition:border-color .15s ease,background .15s ease,color .15s ease,box-shadow .15s ease}.connection-editor__trace-overlay-step--active{border-color:#22d3eea3;background:linear-gradient(90deg,#22d3ee3d,#9b5cff33);color:#f8fafc;box-shadow:0 0 18px #22d3ee33}.connection-editor__trace-overlay-step--blocked{border-color:#fb71855c;color:#fecdd3}.connection-editor__trace-overlay-route strong{min-width:0;overflow:hidden;color:#f8fafc;font-size:.82rem;font-weight:900;text-overflow:ellipsis;white-space:nowrap}.connection-editor__trace-overlay-bar{position:relative;height:5px;margin-top:10px;overflow:hidden;border-radius:999px;background:#94a3b829}.connection-editor__trace-overlay-bar span{position:absolute;inset-block:0;inset-inline-start:0;border-radius:inherit;background:linear-gradient(90deg,#22c55e,#22d3ee);box-shadow:0 0 18px #22c55e61;min-width:8%}.connection-editor__drag-wire{fill:none;stroke:#94a3b8;stroke-width:2.4;stroke-linecap:round;stroke-dasharray:6 7;pointer-events:none;filter:url(#connection-glow);animation:connection-flow 1.05s linear infinite,drag-wire-pulse 1.2s ease-in-out infinite}.connection-editor__drag-wire--halo{stroke:#94a3b829;stroke-width:14;stroke-dasharray:none;animation:drag-halo-pulse 1.2s ease-in-out infinite}.connection-editor__drag-wire--valid{stroke:#22c55e}.connection-editor__drag-wire--halo.connection-editor__drag-wire--valid{stroke:#22c55e47}.connection-editor__drag-endpoint{fill:#94a3b8;stroke:#020617eb;stroke-width:2;pointer-events:none;filter:url(#connection-glow);transform-box:fill-box;transform-origin:center;animation:endpoint-pulse 1s ease-in-out infinite}.connection-editor__drag-endpoint--source{fill:#ff9f2f}.connection-editor__drag-endpoint--target{fill:#7dddeb}.connection-editor__drag-endpoint--valid{fill:#22c55e;stroke:#bbf7d0e0}.connection-editor__wire-handle-line{stroke-width:2;stroke-linecap:round;stroke-dasharray:4 5;pointer-events:none;opacity:.88;filter:url(#connection-glow)}.connection-editor__wire-handle-line--source{stroke:#ff9f2ff0}.connection-editor__wire-handle-line--target{stroke:#19c8e8c2}.connection-editor__wire-control{fill:#0f172af5;stroke:#cbd5e1c7;stroke-width:1.8;pointer-events:none;filter:url(#connection-glow)}.connection-editor__wire-label{pointer-events:none;filter:drop-shadow(0 0 10px rgba(2,6,23,.44));animation:tooltip-rise .14s ease-out}.connection-editor__wire-label rect{fill:#080d18eb;stroke-width:1}.connection-editor__wire-label text{fill:#e2e8f0;font-family:ui-monospace,SFMono-Regular,Consolas,Liberation Mono,monospace;font-size:8px;font-weight:900;letter-spacing:.08em;text-transform:uppercase}.connection-editor__wire-label--source rect{stroke:#ff9f2fad}.connection-editor__wire-label--target rect{stroke:#19c8e86b}.connection-editor__zoom-controls{position:absolute;inset-inline-start:14px;inset-block-start:14px;z-index:4;display:grid;gap:8px;width:210px;pointer-events:auto}.connection-editor__tool-group,.connection-editor__trace-source{display:grid;gap:8px;padding:10px;border-radius:14px;border:1px solid var(--pce-outline);background:linear-gradient(180deg,var(--pce-surface-strong),var(--pce-surface));box-shadow:0 16px 36px var(--pce-shadow-soft),inset 0 1px var(--pce-glass-highlight);-webkit-backdrop-filter:blur(16px);backdrop-filter:blur(16px)}.connection-editor__tool-group{grid-template-columns:repeat(3,30px);width:max-content}.connection-editor__tool-group:nth-of-type(2){grid-template-columns:repeat(2,30px)}.connection-editor__arrange-button{width:100%;min-height:32px;display:inline-flex;align-items:center;justify-content:center;gap:8px;border-radius:999px;border:1px solid rgba(168,85,247,.34);background:linear-gradient(90deg,#a855f72e,#22d3ee1f);color:#e9d5ff;font-size:.74rem;font-weight:800;letter-spacing:.02em;cursor:pointer}.connection-editor__arrange-button span{color:#c084fc;font-family:ui-monospace,SFMono-Regular,Menlo,Monaco,Consolas,Liberation Mono,monospace;font-weight:900}.connection-editor__tool-button{width:30px;height:30px;border-radius:999px;border:1px solid var(--pce-outline);background:var(--pce-surface-soft);color:var(--pce-fg);font-size:.9rem;font-weight:800;letter-spacing:.02em;cursor:pointer;line-height:1}.connection-editor__tool-button:hover:not(:disabled){border-color:color-mix(in srgb,var(--pce-primary) 42%,transparent);color:var(--pce-primary);box-shadow:0 0 18px color-mix(in srgb,var(--pce-primary) 16%,transparent)}.connection-editor__history-button:disabled{cursor:not-allowed;opacity:.42}.connection-editor__arrange-button--active{border-color:#22d3ee94;background:linear-gradient(90deg,#0ea5e93d,#22d3ee2e);color:#cffafe}.connection-editor__trace-source{gap:4px;max-height:230px;overflow:auto}.connection-editor__trace-source-title{padding:2px 4px 6px;color:var(--pce-muted);font-size:.64rem;font-weight:900;letter-spacing:.18em;text-transform:uppercase}.connection-editor__trace-source-item{min-width:0;min-height:30px;display:flex;align-items:center;gap:8px;padding:0 8px;border:0;border-radius:8px;background:transparent;color:var(--pce-fg);cursor:pointer;font-size:.74rem;font-weight:800;text-align:start}.connection-editor__trace-source-item span{color:#f59e0b;font-family:ui-monospace,SFMono-Regular,Menlo,Monaco,Consolas,Liberation Mono,monospace;font-size:.72rem;font-weight:900}.connection-editor__trace-source-item:hover,.connection-editor__trace-source-item--active{background:var(--pce-surface-strong);color:var(--pce-strong);box-shadow:inset 3px 0 #f59e0bd1}.connection-editor__minimap{position:absolute;inset-inline-end:14px;inset-block-end:14px;z-index:4;width:184px;height:124px;padding:18px 10px 10px;overflow:hidden;border-radius:16px;border:1px solid color-mix(in srgb,var(--pce-primary) 30%,transparent);background:linear-gradient(135deg,color-mix(in srgb,var(--pce-primary) 12%,transparent),var(--pce-surface-strong)),var(--pce-surface);box-shadow:0 20px 48px var(--pce-shadow-soft),inset 0 1px var(--pce-glass-highlight);cursor:pointer;-webkit-backdrop-filter:blur(16px);backdrop-filter:blur(16px)}.connection-editor__minimap:hover,.connection-editor__minimap--panning{border-color:#22d3ee75;box-shadow:0 20px 48px var(--pce-shadow-soft),0 0 24px color-mix(in srgb,var(--pce-primary) 14%,transparent),inset 0 1px var(--pce-glass-highlight)}.connection-editor__minimap--panning{cursor:grabbing}.connection-editor__minimap:before{content:\"\";position:absolute;inset:22px 10px 10px;border-radius:10px;background-image:radial-gradient(circle,rgba(125,211,252,.18) 1px,transparent 1px);background-size:22px 22px;opacity:.58;pointer-events:none}.connection-editor__minimap-title{position:absolute;inset-block-start:7px;inset-inline-start:12px;color:var(--pce-muted);font-size:.6rem;font-weight:900;letter-spacing:.16em;text-transform:uppercase}.connection-editor__minimap svg{position:relative;width:100%;height:100%;display:block;overflow:visible}.connection-editor__minimap-wire{fill:none;stroke:#b46cff8f;stroke-width:4;stroke-linecap:round;opacity:.86}.connection-editor__minimap-wire--state{stroke:#ff9f2fdb}.connection-editor__minimap-wire--state-read{stroke:#8b7dffb8;stroke-dasharray:4 9}.connection-editor__minimap-wire--projection{stroke:#19c8e88a;stroke-dasharray:18 8}.connection-editor__minimap-wire--event-propagation{stroke:#ffb454cc;stroke-dasharray:6 7}.connection-editor__minimap-wire--policy{filter:drop-shadow(0 0 6px rgba(34,197,94,.28))}.connection-editor__minimap-wire--trace{stroke:#9b5cffe0;stroke-width:5;stroke-dasharray:12 9;animation:connection-flow 1s linear infinite}.connection-editor__minimap-wire--active{stroke:#facc15eb;stroke-width:6;filter:drop-shadow(0 0 8px rgba(250,204,21,.38))}.connection-editor__minimap-wire--mode-dimmed{opacity:.2;stroke-width:2.6;filter:none}.connection-editor__minimap-node{fill:#f59e0be0;stroke:#020617db;stroke-width:4;filter:drop-shadow(0 0 7px rgba(245,158,11,.24))}.connection-editor__minimap-node--state{fill:#a855f7e6;filter:drop-shadow(0 0 8px rgba(168,85,247,.34))}.connection-editor__minimap-node--selected{fill:#facc15f5;stroke:#fef08aeb;filter:drop-shadow(0 0 10px rgba(250,204,21,.42))}.connection-editor__minimap-node--trace-source{fill:#facc15f5;filter:drop-shadow(0 0 10px rgba(250,204,21,.44))}.connection-editor__minimap-node--trace-reacting{fill:#22c55eeb;filter:drop-shadow(0 0 10px rgba(34,197,94,.42))}.connection-editor__minimap-node--mode-dimmed{opacity:.28;filter:none}.connection-editor__minimap-viewport{fill:#7dd3fc1f;stroke:#7dd3fce6;stroke-width:5;stroke-dasharray:18 10;filter:drop-shadow(0 0 10px rgba(125,211,252,.3));transition:x .12s ease,y .12s ease,width .12s ease,height .12s ease}.connection-editor__minimap--panning .connection-editor__minimap-viewport{fill:#22d3ee2e;stroke:#22d3eef5;stroke-dasharray:none}.connection-editor__node{position:absolute;width:168px;height:168px;transform:translate(-84px,-84px);border:0;padding:0;background:transparent;color:inherit;cursor:pointer;transition:filter .16s ease}.connection-editor__node--dragging{cursor:grabbing;filter:drop-shadow(0 0 22px rgba(34,211,238,.26));z-index:12}.connection-editor__node--connection-focus{filter:drop-shadow(0 0 16px rgba(34,211,238,.2))}.connection-editor__node--compat-target .connection-editor__node-ring{box-shadow:0 0 0 2px #22c55e66,0 0 0 18px #22c55e0b,0 0 32px #22c55e29}.connection-editor__node--mode-dimmed{opacity:.42;filter:grayscale(.22) saturate(.56)}.connection-editor__node--mode-dimmed .connection-editor__node-ring{animation:none;box-shadow:0 0 0 1px #2dd4bf14,0 0 14px #0ea5e90f}.connection-editor__node--mode-dimmed .connection-editor__node-halo{stroke-opacity:.28}.connection-editor__node-ring,.connection-editor__node-core,.connection-editor__node-svg{position:absolute;inset:0}.connection-editor__node-ring,.connection-editor__node-core{display:grid;place-items:center;clip-path:polygon(30% 0,70% 0,100% 30%,100% 70%,70% 100%,30% 100%,0 70%,0 30%)}.connection-editor__node-ring{background:radial-gradient(circle at center,transparent 0 44%,rgba(7,17,31,.96) 45% 57%,transparent 58%),conic-gradient(from -28deg,#06b6d4b3 0 28%,#f59e0b9e 28% 48%,#a855f780 48% 68%,#06b6d4a3 68% 100%);box-shadow:0 0 0 1px #2dd4bf2e,0 0 26px #0ea5e929;animation:node-breathe 2.8s ease-in-out infinite}.connection-editor__node-svg{overflow:visible;filter:drop-shadow(0 0 16px rgba(14,165,233,.16))}.connection-editor__node-halo{fill:transparent;stroke:#38bdf838;stroke-width:1;stroke-dasharray:0;pointer-events:none}.connection-editor__node-halo:nth-child(2){stroke:#38bdf824}.connection-editor__node-halo:nth-child(3){stroke:#94a3b81a}.connection-editor__node-segment{fill-opacity:.28;stroke-opacity:.72;stroke-width:1.15;transition:fill-opacity .16s ease,stroke-opacity .16s ease,stroke-width .16s ease;cursor:grab}.connection-editor__node:hover .connection-editor__node-segment,.connection-editor__node--selected .connection-editor__node-segment,.connection-editor__node--connection-focus .connection-editor__node-segment{fill-opacity:.54;stroke-opacity:.95;stroke-width:1.55}.connection-editor__node-segment--connection-focus{fill-opacity:.76;stroke-opacity:1;stroke-width:2;filter:drop-shadow(0 0 8px rgba(34,211,238,.76));animation:segment-focus-sweep 1.45s ease-in-out infinite}.connection-editor__node-segment--source{fill-opacity:.86;stroke-opacity:1;stroke-width:2.45;filter:drop-shadow(0 0 12px rgba(251,146,60,.82))}.connection-editor__node-segment--compatible{fill-opacity:.74;stroke-opacity:1;stroke-width:2;filter:drop-shadow(0 0 10px rgba(34,197,94,.72));animation:snap-pulse 1s ease-in-out infinite}.connection-editor__node-segment--compat-preview{fill-opacity:.86;stroke-opacity:1;stroke-width:2.45;filter:drop-shadow(0 0 13px rgba(245,158,11,.78))}.connection-editor__node-segment--candidate{fill-opacity:.92;stroke-opacity:1;stroke-width:2.8;filter:drop-shadow(0 0 16px rgba(34,197,94,.86))}.connection-editor__node-segment--incompatible{fill-opacity:.12;stroke-opacity:.28;cursor:not-allowed}.connection-editor__node-segment--invalid-drop{fill-opacity:.72;stroke:#fb7185;stroke-opacity:1;stroke-width:3;filter:drop-shadow(0 0 16px rgba(244,63,94,.84));animation:invalid-drop-jolt .36s ease-out}.connection-editor__node-segment--state{fill-opacity:.44;filter:drop-shadow(0 0 8px rgba(180,108,255,.2))}.connection-editor__node-segment--mode-dimmed{fill-opacity:.08;stroke-opacity:.2;stroke-width:.9;filter:none}.connection-editor__node-anchor{opacity:.95;filter:drop-shadow(0 0 6px currentColor)}.connection-editor__node-rotate-handle{cursor:grab;opacity:0;pointer-events:none;transition:opacity .16s ease,filter .16s ease;filter:drop-shadow(0 0 8px rgba(34,211,238,.28))}.connection-editor__node:hover .connection-editor__node-rotate-handle,.connection-editor__node--selected .connection-editor__node-rotate-handle,.connection-editor__node--rotating .connection-editor__node-rotate-handle{opacity:1;pointer-events:auto}.connection-editor__node--rotating .connection-editor__node-rotate-handle{cursor:grabbing;filter:drop-shadow(0 0 12px rgba(34,211,238,.54))}.connection-editor__node-rotate-hit{fill:transparent}.connection-editor__node-rotate-dot{fill:var(--pce-surface-strong);stroke:var(--pce-primary);stroke-opacity:.88;stroke-width:1.4}.connection-editor__node-rotate-arc,.connection-editor__node-rotate-arrow{fill:none;stroke:var(--pce-primary);stroke-linecap:round;stroke-linejoin:round;stroke-opacity:.96;stroke-width:1.2;pointer-events:none}.connection-editor__segment-icon,.connection-editor__segment-label{pointer-events:none;fill:#cbd5e1;font-family:ui-monospace,SFMono-Regular,Menlo,Monaco,Consolas,Liberation Mono,monospace;font-weight:800;paint-order:stroke;stroke:#020617c2;stroke-width:3px;stroke-linejoin:round}.connection-editor__segment-icon{font-size:12px;fill:#19c8e8}.connection-editor__segment-icon--output{fill:#ff9f2f}.connection-editor__segment-label{font-size:9.5px;letter-spacing:0;fill:#e2e8f0e0}.connection-editor__node-core{inset:43px;padding:12px;border-radius:999px;clip-path:none;display:flex;flex-direction:column;align-items:center;justify-content:center;background:radial-gradient(circle at center,#111827 0 58%,#060b14);border:1px solid rgba(226,232,240,.1);box-shadow:0 12px 28px #00000073,inset 0 1px #ffffff0d;color:#f8fafc;text-shadow:0 1px 2px rgba(0,0,0,.62)}.connection-editor__node-icon{display:block;max-width:44px;overflow:hidden;color:#f8fafc;font-family:Material Symbols Outlined,Material Icons,sans-serif;font-size:1.22rem;font-weight:400;line-height:1;text-align:center;text-transform:none;letter-spacing:0;white-space:nowrap;filter:drop-shadow(0 0 10px rgba(226,232,240,.18))}.connection-editor__node--state .connection-editor__node-ring{background:radial-gradient(circle at center,transparent 0 44%,rgba(7,17,31,.96) 45% 57%,transparent 58%),conic-gradient(from 14deg,#a855f7c7 0 42%,#7e3af26b 42% 78%,#f59e0b47 78% 100%);box-shadow:0 0 0 1px #a855f738,0 0 30px #a855f733}.connection-editor__node--selected .connection-editor__node-ring{box-shadow:0 0 0 2px #facc15bd,0 0 34px #facc153d}.connection-editor__node--connection-focus .connection-editor__node-ring{box-shadow:0 0 0 2px #22d3eead,0 0 38px #22d3ee42;animation:node-focus-breathe 1.7s ease-in-out infinite}.connection-editor__node--trace-source .connection-editor__node-ring{box-shadow:0 0 0 2px #facc15c7,0 0 0 18px #facc150f,0 0 54px #facc154d;animation:trace-source-pulse 1.38s ease-in-out infinite}.connection-editor__node--trace-source:before{content:\"\";position:absolute;z-index:0;inset:-44px;border-radius:999px;border:2px solid rgba(250,204,21,.36);background:radial-gradient(circle at center,transparent 0 64%,rgba(250,204,21,.05) 65% 66%,transparent 67%),conic-gradient(from -20deg,#facc1500,#facc1552,#facc1500);box-shadow:0 0 36px #facc151f;opacity:.92;pointer-events:none;animation:trace-source-orbit 2.8s linear infinite}.connection-editor__node--trace-reacting .connection-editor__node-ring{box-shadow:0 0 0 2px #22c55e94,0 0 46px #22c55e38;animation:trace-reacting-pulse 1.38s ease-in-out infinite}.connection-editor__node--trace-source:after,.connection-editor__node--trace-reacting:after{position:absolute;z-index:3;inset-inline-start:50%;inset-block-start:-42px;padding:0;border:0;background:transparent;color:#facc15;font-family:ui-monospace,SFMono-Regular,Menlo,Monaco,Consolas,Liberation Mono,monospace;font-size:.68rem;font-weight:900;letter-spacing:.18em;text-transform:uppercase;transform:translate(-50%);text-shadow:0 0 12px rgba(250,204,21,.52);pointer-events:none}.connection-editor__node--trace-source:after{content:attr(data-trace-label)}.connection-editor__node--trace-reacting:after{content:attr(data-trace-label);color:#86efac;text-shadow:0 0 12px rgba(34,197,94,.44)}.connection-editor__node--trace-source .connection-editor__node-segment--output{fill-opacity:.66;stroke-width:2.2;filter:drop-shadow(0 0 14px rgba(255,159,47,.42))}.connection-editor__node--expanded .connection-editor__node-ring{box-shadow:0 0 0 2px #22d3eebd,0 0 34px #22d3ee3d}.connection-editor__node--rotating .connection-editor__node-ring{box-shadow:0 0 0 2px #facc15c7,0 0 42px #facc1547;animation:node-focus-breathe 1.1s ease-in-out infinite}.connection-editor__node--rotating .connection-editor__node-segment{fill-opacity:.68;stroke-opacity:1;stroke-width:1.9;cursor:grabbing}.connection-editor__node-title,.connection-editor__node-subtitle{display:block;max-width:92px;overflow:hidden;text-overflow:ellipsis;white-space:nowrap;text-align:center}.connection-editor__node-title{color:#f8fafc;font-size:.82rem;font-weight:800}.connection-editor__node-subtitle{margin-top:4px;color:#a7b4c8;font-size:.62rem;text-transform:uppercase;letter-spacing:.08em}.connection-editor__ports{position:absolute;display:grid;gap:6px;width:104px;opacity:0;pointer-events:none;transition:opacity .16s ease}.connection-editor__segment-popover{position:absolute;z-index:80;width:292px;max-height:320px;overflow:auto;display:grid;gap:10px;padding:14px;border-radius:16px;border:1px solid rgba(148,163,184,.18);background:linear-gradient(135deg,#0f172af5,#110c20f0),#090c16eb;box-shadow:0 28px 72px #0000007a,0 0 48px #a855f71a,inset 0 1px #ffffff0d;-webkit-backdrop-filter:blur(18px);backdrop-filter:blur(18px)}.connection-editor__segment-popover-header{display:flex;align-items:flex-start;justify-content:space-between;gap:12px;padding-bottom:2px}.connection-editor__segment-popover-title{color:#94a3b8;font-size:.68rem;font-weight:800;letter-spacing:.14em;text-transform:uppercase}.connection-editor__segment-popover-hint{margin-top:5px;color:#64748b;font-size:.66rem;font-weight:700}.connection-editor__segment-rotation{flex:0 0 auto;min-width:54px;padding:5px 8px;border-radius:999px;border:1px solid rgba(34,211,238,.28);background:#082f4957;color:#7dd3fc;font-size:.66rem;font-weight:900;font-family:ui-monospace,SFMono-Regular,Consolas,Liberation Mono,monospace;text-align:center;box-shadow:inset 0 0 16px #0ea5e914}.connection-editor__segment-row{display:grid;grid-template-columns:28px 72px minmax(0,1fr) auto;align-items:center;gap:8px;min-height:40px;padding:7px;border-radius:12px;border:1px solid rgba(148,163,184,.12);background:linear-gradient(90deg,#0f172ac7,#0f172a75),#0f172a99;transition:border-color .15s ease,background .15s ease,box-shadow .15s ease,transform .15s ease}.connection-editor__segment-row--input{border-color:#22d3ee42}.connection-editor__segment-row--output{border-color:#f59e0b47}.connection-editor__segment-row--state{border-color:#a855f74d}.connection-editor__segment-row--source,.connection-editor__segment-row--candidate{transform:translate(2px);box-shadow:0 0 22px #f59e0b24,inset 0 0 20px #f59e0b14}.connection-editor__segment-row--compatible{border-color:#22d3ee6b;box-shadow:inset 0 0 18px #22d3ee14}.connection-editor__segment-row--compat-preview{border-color:#f59e0b94;background:linear-gradient(90deg,#f59e0b1f,#0f172a8a),#0f172ab3;box-shadow:0 0 22px #f59e0b1f,inset 0 0 18px #f59e0b14}.connection-editor__segment-row--invalid-drop{border-color:#fb7185b3;background:linear-gradient(90deg,#f43f5e24,#0f172a94),#0f172ab3;box-shadow:0 0 24px #f43f5e2e,inset 0 0 18px #f43f5e1a;animation:invalid-drop-jolt .36s ease-out}.connection-editor__segment-index{color:#64748b;font-size:.64rem;font-weight:900;font-family:ui-monospace,SFMono-Regular,Consolas,Liberation Mono,monospace;letter-spacing:.08em}.connection-editor__segment-kind{display:inline-flex;align-items:center;gap:6px;color:#94a3b8;font-size:.62rem;font-weight:800;text-transform:uppercase;min-width:0;white-space:nowrap}.connection-editor__segment-kind-dot{width:7px;height:7px;border-radius:999px;background:#94a3b8;box-shadow:0 0 12px #94a3b847}.connection-editor__segment-row--input .connection-editor__segment-kind-dot{background:#22d3ee;box-shadow:0 0 12px #22d3ee61}.connection-editor__segment-row--output .connection-editor__segment-kind-dot{background:#fb923c;box-shadow:0 0 12px #fb923c66}.connection-editor__segment-row--state .connection-editor__segment-kind-dot{background:#a855f7;box-shadow:0 0 12px #a855f76b}.connection-editor__segment-label{display:inline-flex;align-items:center;gap:5px;min-width:0;overflow:hidden;color:#e2e8f0;font-size:.74rem;font-weight:700;text-overflow:ellipsis;white-space:nowrap}.connection-editor__segment-actions{display:inline-flex;gap:4px}.connection-editor__segment-action{width:24px;height:24px;border-radius:999px;border:1px solid rgba(148,163,184,.18);background:#060c16b8;color:#dbeafe;cursor:pointer;font-weight:900;line-height:1}.connection-editor__segment-action:hover{border-color:#22d3ee75;box-shadow:0 0 14px #22d3ee29}.connection-editor__port{min-height:24px;border-radius:999px;border:1px solid rgba(148,163,184,.14);background:#080d18c2;color:#cbd5e1;font-size:.64rem;font-weight:700;font-family:ui-monospace,SFMono-Regular,Consolas,Liberation Mono,monospace;overflow:hidden;text-overflow:ellipsis;white-space:nowrap;cursor:crosshair;box-shadow:0 8px 20px #00000038}.connection-editor__port--output{border-color:#f59e0b75;color:#fbbf24}.connection-editor__port--input{border-color:#06b6d475;color:#22d3ee}.connection-editor__port--state{border-color:#a855f785;color:#c084fc}.connection-editor__port--compatible{background:#22c55e29;box-shadow:0 0 0 1px #22c55e61,0 0 18px #22c55e2e;animation:snap-pulse 1s ease-in-out infinite}.connection-editor__port--source{border-color:#fb923cb8;background:#fb923c29;color:#fed7aa;box-shadow:0 0 0 1px #fb923c73,0 0 20px #fb923c2e}.connection-editor__port--candidate{background:#22c55e3d;box-shadow:0 0 0 2px #22c55e94,0 0 24px #22c55e3d}.connection-editor__port--incompatible{opacity:.42;cursor:not-allowed;filter:grayscale(.45)}.connection-editor__port--invalid-drop{opacity:1;border-color:#fb7185c7;color:#fecdd3;background:#f43f5e2e;box-shadow:0 0 0 2px #f43f5e75,0 0 24px #f43f5e38;filter:none;animation:invalid-drop-jolt .36s ease-out}.connection-editor__port--connection-focus{border-color:#facc15ad;color:#fde68a;background:#facc151f;box-shadow:0 0 0 1px #facc156b,0 0 20px #facc152e;animation:port-focus-pulse 1.25s ease-in-out infinite}.connection-editor__drag-tip{position:absolute;z-index:6;display:grid;gap:4px;width:min(330px,calc(100% - 28px));padding:10px 12px;border-radius:14px;border:1px solid rgba(125,211,252,.26);background:linear-gradient(135deg,#0ea5e91f,#0f172aeb),#080d18f0;box-shadow:0 18px 44px #0206176b,0 0 28px #0ea5e91a;font-size:.76rem;pointer-events:none;-webkit-backdrop-filter:blur(16px);backdrop-filter:blur(16px);animation:tooltip-rise .14s ease-out}.connection-editor__drag-tip--valid{border-color:#22c55e66;background:linear-gradient(135deg,#22c55e29,#0f172aeb),#080d18f0;box-shadow:0 18px 44px #0206176b,0 0 30px #22c55e24}.connection-editor__drag-tip--invalid{z-index:7;border-color:#fb71858a;background:linear-gradient(135deg,#f43f5e2e,#0f172af0),#080d18f5;box-shadow:0 18px 44px #0206176b,0 0 34px #f43f5e29;animation:tooltip-rise .14s ease-out,invalid-drop-jolt .36s ease-out}.connection-editor__invalid-drop-pulse{position:absolute;z-index:6;width:16px;height:16px;border-radius:999px;border:2px solid rgba(251,113,133,.88);background:#f43f5e38;box-shadow:0 0 0 8px #f43f5e1a,0 0 28px #f43f5e3d;pointer-events:none;transform:translate(-50%,-50%);animation:invalid-drop-ping 1.2s ease-out both}.connection-editor__drag-tip span{color:#7dd3fc;text-transform:uppercase;letter-spacing:.12em;font-size:.62rem;font-weight:800}.connection-editor__drag-tip strong{min-width:0;overflow:hidden;color:#f8fafc;font-size:.78rem;font-weight:900;text-overflow:ellipsis;white-space:nowrap}.connection-editor__drag-tip small{color:#94a3b8;font-size:.68rem;font-weight:700}.connection-editor__drag-tip--valid small{color:#86efac}.connection-editor__drag-tip--invalid span,.connection-editor__drag-tip--invalid small{color:#fda4af}.connection-editor__summary{grid-column:1;grid-row:3;display:grid;grid-template-columns:repeat(4,minmax(0,1fr));gap:10px}.connection-editor__side-panel{grid-column:2;grid-row:2 / 4;position:relative;z-index:8;min-width:0;min-height:0;display:grid;align-content:start;gap:14px;overflow:auto;padding-inline-end:4px;scrollbar-color:var(--pce-outline-strong) var(--pce-surface-soft)}.connection-editor__metric,.connection-editor__item{border-radius:16px;background:var(--pce-surface);border:1px solid var(--pce-outline);box-shadow:inset 0 1px var(--pce-glass-highlight);-webkit-backdrop-filter:blur(16px);backdrop-filter:blur(16px)}.connection-editor__metric{padding:10px;display:grid;gap:4px}.connection-editor__metric span{color:var(--pce-muted);font-size:.72rem}.connection-editor__metric strong,.connection-editor__details-row strong{color:var(--pce-strong);font-size:.9rem}.connection-editor__filters,.connection-editor__actions,.connection-editor__badges{display:flex;gap:8px;flex-wrap:wrap}.connection-editor__filter,.connection-editor__action{border:1px solid var(--pce-outline-strong);background:var(--pce-surface-soft);color:var(--pce-fg);border-radius:999px;padding:6px 10px;font-size:.75rem;font-weight:700;cursor:pointer}.connection-editor__filter--active,.connection-editor__action:hover{border-color:color-mix(in srgb,var(--pce-secondary) 62%,transparent);background:color-mix(in srgb,var(--pce-secondary) 16%,var(--pce-surface-soft));color:var(--pce-strong)}.connection-editor__action--danger{border-color:#f8717161;color:#fecaca}.connection-editor__item{width:100%;text-align:start;padding:12px;display:grid;gap:6px;cursor:pointer;color:inherit}.connection-editor__item--active{border-color:#a855f7b8;background:linear-gradient(90deg,#0ea5e91a,#a855f721)}.connection-editor__item-title{font-weight:800;color:#f8fafc;word-break:break-word}.connection-editor__badge{padding:3px 8px;border-radius:999px;background:#0ea5e92e;color:#bae6fd;font-size:.72rem;font-weight:800}.connection-editor__section{min-width:0;padding:14px;border-radius:18px;background:var(--pce-surface);border:1px solid var(--pce-outline);box-shadow:inset 0 1px var(--pce-glass-highlight),0 18px 50px var(--pce-shadow-soft);-webkit-backdrop-filter:blur(18px);backdrop-filter:blur(18px)}.connection-editor__badge--warning{background:#facc1524;color:#fde68a}.connection-editor__badge--error{background:#ef444424;color:#fecaca}.connection-editor__diagnostics{display:grid;gap:8px}.connection-editor__diagnostic{display:grid;gap:4px;padding:10px;border-radius:12px;border:1px solid var(--pce-outline);background:var(--pce-surface-soft);color:var(--pce-fg);font-size:.78rem;line-height:1.35}.connection-editor__diagnostic--warning{border-color:#f59e0b47;background:#f59e0b1a}.connection-editor__diagnostic--error{border-color:#ef44445c;background:#ef44441f}.connection-editor__diagnostic-severity{font-size:.68rem;font-weight:900;letter-spacing:.08em;text-transform:uppercase;color:#f8fafc}.connection-editor__suggestions{display:grid;gap:10px;margin-top:14px;padding-top:14px;border-top:1px solid var(--pce-outline)}.connection-editor__suggestion{display:grid;gap:8px;width:100%;padding:12px;border-radius:16px;border:1px solid color-mix(in srgb,var(--pce-secondary) 26%,transparent);background:linear-gradient(135deg,color-mix(in srgb,var(--pce-secondary) 12%,transparent),color-mix(in srgb,var(--pce-primary) 8%,transparent)),var(--pce-surface-strong);color:var(--pce-fg);text-align:start;cursor:pointer;transition:transform .16s ease,border-color .16s ease,background .16s ease}.connection-editor__suggestion:hover{transform:translateY(-1px);border-color:color-mix(in srgb,var(--pce-primary) 46%,transparent);background:linear-gradient(135deg,color-mix(in srgb,var(--pce-secondary) 18%,transparent),color-mix(in srgb,var(--pce-primary) 12%,transparent)),var(--pce-surface-strong)}.connection-editor__suggestion-route{display:grid;gap:4px;font-size:.78rem}.connection-editor__suggestion-route strong{color:var(--pce-strong);font-size:.82rem}.connection-editor__suggestion-reason{color:var(--pce-muted);font-size:.76rem;line-height:1.35}.connection-editor__suggestion-action{justify-self:start;padding:3px 8px;border-radius:999px;background:#22d3ee24;color:#67e8f9;font-size:.68rem;font-weight:900;letter-spacing:.06em;text-transform:uppercase}:host-context(.theme-light) .connection-editor__suggestion-action{background:color-mix(in srgb,var(--pce-primary) 12%,var(--pce-surface-soft));color:#075f73}.connection-editor__trace{display:grid;gap:10px;margin-top:14px;padding-top:14px;border-top:1px solid var(--pce-outline)}.connection-editor__trace-summary{color:var(--pce-muted);font-size:.78rem;line-height:1.35}.connection-editor__trace-step{display:grid;grid-template-columns:24px minmax(76px,auto) 1fr;gap:8px;align-items:center;padding:9px;border-radius:12px;border:1px solid rgba(34,211,238,.18);background:var(--pce-surface-soft);font-size:.76rem}.connection-editor__trace-step--blocked{border-color:#ef444457;background:#ef44441a}.connection-editor__trace-order{display:inline-grid;place-items:center;width:22px;height:22px;border-radius:999px;background:#22d3ee29;color:#67e8f9;font-weight:900}.connection-editor__trace-phase{color:var(--pce-strong);font-weight:900;text-transform:uppercase;letter-spacing:.06em;font-size:.66rem}.connection-editor__trace-copy{min-width:0;color:var(--pce-fg);word-break:break-word}.connection-editor__transform-steps{display:grid;gap:8px}.connection-editor__transform-step{display:grid;grid-template-columns:minmax(0,1fr) auto auto;gap:8px;align-items:center;padding:9px;border-radius:12px;border:1px solid rgba(168,85,247,.22);background:var(--pce-surface-soft)}.connection-editor__transform-kind{min-width:0;color:var(--pce-strong);font-weight:900;word-break:break-word}.connection-editor__transform-phase{color:var(--pce-muted);font-size:.68rem;font-weight:800;text-transform:uppercase;letter-spacing:.06em}.connection-editor__details-row,.connection-editor__details-block{display:grid;gap:6px}.connection-editor__rule-grid{display:grid;gap:10px}.connection-editor__rule-card{display:grid;gap:8px;padding:10px;border-radius:12px;border:1px solid var(--pce-outline);background:var(--pce-surface-soft)}.connection-editor__rule-heading{color:var(--pce-fg);font-size:.72rem;font-weight:900;text-transform:uppercase;letter-spacing:.06em}pre{margin:0;padding:12px;border-radius:12px;background:color-mix(in srgb,var(--pce-surface-strong) 82%,#020617);color:var(--pce-fg);overflow:auto;font-size:.75rem}@keyframes connection-flow{to{stroke-dashoffset:-38}}@keyframes drag-wire-pulse{0%,to{stroke-opacity:.76}50%{stroke-opacity:1}}@keyframes drag-halo-pulse{0%,to{stroke-opacity:.48}50%{stroke-opacity:.82}}@keyframes endpoint-pulse{0%,to{opacity:.78;transform:scale(1)}50%{opacity:1;transform:scale(1.25)}}@keyframes selected-wire-aura{0%,to{stroke-opacity:.46}50%{stroke-opacity:.92}}@keyframes wire-draw-in{0%{stroke-dashoffset:640;opacity:.32}70%{opacity:1}to{stroke-dashoffset:0;opacity:1}}@keyframes new-wire-halo{0%{stroke-opacity:0;stroke-width:30}28%{stroke-opacity:.78}to{stroke-opacity:0;stroke-width:12}}@keyframes new-dock-link-flash{0%{transform:translateY(-2px);box-shadow:0 16px 40px #0206175c,0 0 42px #fb923c47}to{transform:translateY(0)}}@keyframes trace-wire-pulse{0%,to{stroke-opacity:.78}50%{stroke-opacity:1}}@keyframes trace-halo-pulse{0%,to{stroke-opacity:.34}50%{stroke-opacity:.86}}@keyframes tooltip-rise{0%{opacity:0;transform:translateY(6px)}to{opacity:1;transform:translateY(0)}}@keyframes invalid-drop-jolt{0%,to{transform:translate(0)}28%{transform:translate(-3px)}56%{transform:translate(3px)}}@keyframes invalid-drop-ping{0%{opacity:1;transform:translate(-50%,-50%) scale(.72)}72%{opacity:.74;transform:translate(-50%,-50%) scale(1.35)}to{opacity:0;transform:translate(-50%,-50%) scale(1.8)}}@keyframes node-breathe{50%{transform:scale(1.035)}}@keyframes node-focus-breathe{0%,to{transform:scale(1)}50%{transform:scale(1.055)}}@keyframes trace-source-pulse{50%{transform:scale(1.04);box-shadow:0 0 0 3px #facc15db,0 0 0 22px #facc1514,0 0 64px #facc1557}}@keyframes trace-source-orbit{to{transform:rotate(360deg)}}@keyframes trace-reacting-pulse{50%{transform:scale(1.045);box-shadow:0 0 0 3px #22c55ead,0 0 62px #22c55e4d}}@keyframes segment-focus-sweep{0%,to{stroke-opacity:.82}50%{stroke-opacity:1}}@keyframes snap-pulse{50%{transform:scale(1.04)}}@keyframes port-focus-pulse{50%{transform:translateY(-1px);box-shadow:0 0 0 2px #facc158f,0 0 26px #facc153d}}@media(prefers-reduced-motion:reduce){.connection-editor__viewport,.connection-editor__node,.connection-editor__node-ring,.connection-editor__node-core,.connection-editor__node-segment,.connection-editor__dock-link,.connection-editor__port{transition-duration:1ms}.connection-editor__wire,.connection-editor__wire--state,.connection-editor__wire--projection,.connection-editor__wire--state-read,.connection-editor__wire--event-propagation,.connection-editor__wire--halo.connection-editor__wire--active,.connection-editor__wire--trace,.connection-editor__wire--halo.connection-editor__wire--trace,.connection-editor__wire-endpoint,.connection-editor__connection-tooltip,.connection-editor__dock-link--new,.connection-editor__trace-overlay,.connection-editor__trace-overlay-step,.connection-editor__drag-wire,.connection-editor__drag-wire--halo,.connection-editor__drag-endpoint,.connection-editor__drag-tip,.connection-editor__node-ring,.connection-editor__node--connection-focus .connection-editor__node-ring,.connection-editor__node--trace-source .connection-editor__node-ring,.connection-editor__node--trace-source:before,.connection-editor__node--trace-reacting .connection-editor__node-ring,.connection-editor__node--rotating .connection-editor__node-ring,.connection-editor__node-segment--connection-focus,.connection-editor__node-segment--compatible,.connection-editor__node-segment--invalid-drop,.connection-editor__segment-popover,.connection-editor__port--compatible,.connection-editor__port--invalid-drop,.connection-editor__port--connection-focus,.connection-editor__invalid-drop,.connection-editor__invalid-drop-pulse{animation:none}.connection-editor__wire{stroke-dashoffset:0}.connection-editor__wire--new{stroke-dasharray:10 8;stroke-dashoffset:0;opacity:1}.connection-editor__wire--halo.connection-editor__wire--new{stroke-width:12;stroke-opacity:.16}.connection-editor__wire-endpoint,.connection-editor__drag-endpoint,.connection-editor__node-ring,.connection-editor__node--trace-source:before{transform:none}.connection-editor__invalid-drop-pulse{opacity:0}}@media(max-width:900px){:host{inset:0}.connection-editor{inset:8px;height:calc(100vh - 16px);padding:12px;grid-template-columns:minmax(0,1fr);grid-template-rows:auto minmax(260px,1fr) auto minmax(150px,30vh) minmax(86px,126px)}.connection-editor__header,.connection-editor__stage,.connection-editor__summary,.connection-editor__side-panel,.connection-editor__dock{grid-column:1}.connection-editor__header{align-items:stretch;flex-wrap:wrap;border-radius:18px}.connection-editor__mode-frame{order:3;width:100%;max-width:100%}.connection-editor__mode-frame:before,.connection-editor__mode-frame:after{content:\"\";position:absolute;z-index:2;inset-block:4px;width:24px;border-radius:999px;pointer-events:none}.connection-editor__mode-frame:before{inset-inline-start:1px;background:linear-gradient(90deg,#080d18f0,#080d1800)}.connection-editor__mode-frame:after{inset-inline-end:1px;background:linear-gradient(270deg,#080d18f0,#080d1800)}.connection-editor__mode-shell{width:100%;max-width:100%;overflow-x:auto;scroll-padding-inline:28px;-webkit-overflow-scrolling:touch}.connection-editor__subtitle{margin-inline-start:auto}.connection-editor__stage{grid-row:2;min-height:260px}.connection-editor__summary{grid-row:3;grid-template-columns:1fr 1fr}.connection-editor__side-panel{grid-row:4;max-height:30vh}.connection-editor__dock{grid-row:5;min-height:0}.connection-editor__connection-tooltip{width:min(620px,calc(100% - 24px));max-height:min(260px,calc(100% - 24px));overflow:auto}.connection-editor__dock-tabs{width:100%;min-width:0;min-height:0;flex-wrap:wrap;align-items:flex-start}.connection-editor__dock-count{flex:1 1 100%;margin-inline-start:0}.connection-editor__dock-body{width:100%;min-width:0;max-height:76px;box-sizing:border-box}.connection-editor__dock-body pre{white-space:pre-wrap;overflow-wrap:anywhere}.connection-editor__dock-link{grid-template-columns:1fr;align-items:start}.connection-editor__dock-link-route{flex-wrap:wrap}.connection-editor__dock-link-badges{justify-content:flex-start}.connection-editor__trace-overlay{inset-inline-start:14px;width:min(420px,calc(100% - 28px));min-width:0;transform:none}.connection-editor__drag-tip{width:min(300px,calc(100% - 28px))}.connection-editor__segment-popover{width:min(280px,calc(100% - 28px));max-height:min(280px,calc(100% - 28px))}.connection-editor__minimap{inset-inline-end:10px;inset-block-end:10px;width:132px;height:94px;padding:16px 8px 8px;border-radius:14px}.connection-editor__minimap:before{inset:20px 8px 8px;background-size:18px 18px}.connection-editor__minimap-title{inset-block-start:6px;inset-inline-start:10px;font-size:.54rem}}@media(max-width:640px){.connection-editor{inset:4px;height:calc(100vh - 8px);padding:8px;gap:8px;grid-template-rows:auto minmax(240px,1fr) auto minmax(140px,28vh) minmax(82px,116px)}.connection-editor__header{gap:8px;padding:10px}.connection-editor__mode-shell{padding:4px;gap:2px}.connection-editor__mode{min-height:28px;gap:4px;padding:0 7px;font-size:.68rem}.connection-editor__mode-glyph{font-size:.64rem}.connection-editor__stage{min-height:240px}.connection-editor__zoom-controls{inset-inline-start:8px;inset-block-start:8px;gap:6px;width:126px}.connection-editor__tool-group,.connection-editor__trace-source{gap:6px;padding:8px;border-radius:12px}.connection-editor__tool-group{grid-template-columns:repeat(3,28px)}.connection-editor__tool-group:nth-of-type(2){grid-template-columns:repeat(2,28px)}.connection-editor__tool-button{width:28px;height:28px}.connection-editor__arrange-button,.connection-editor__simulate-button{min-height:30px;gap:6px;padding-inline:8px;font-size:.68rem}.connection-editor__summary{gap:6px}.connection-editor__side-panel{max-height:28vh}.connection-editor__dock{border-radius:16px}.connection-editor__dock-tabs{gap:4px}.connection-editor__dock-tab{padding:0 9px}.connection-editor__dock-count{font-size:.62rem}.connection-editor__dock-body{max-height:66px;padding:8px}.connection-editor__minimap{width:116px;height:84px}.connection-editor__segment-row{grid-template-columns:24px minmax(54px,.55fr) minmax(0,1fr) auto}}\n"], dependencies: [{ kind: "ngmodule", type: CommonModule }, { kind: "pipe", type: i2$3.JsonPipe, name: "json" }], changeDetection: i0.ChangeDetectionStrategy.OnPush });
7217
7361
  }
7218
- i0.ɵɵngDeclareClassMetadata({ minVersion: "12.0.0", version: "20.3.17", ngImport: i0, type: ConnectionEditorComponent, decorators: [{
7362
+ i0.ɵɵngDeclareClassMetadata({ minVersion: "12.0.0", version: "21.2.14", ngImport: i0, type: ConnectionEditorComponent, decorators: [{
7219
7363
  type: Component,
7220
7364
  args: [{ selector: 'praxis-connection-editor', imports: [CommonModule], providers: [providePraxisPageBuilderI18n()], host: {
7221
7365
  '(document:pointerdown)': 'closeFloatingPanelsOnOutsidePointerDown($event)',
@@ -8572,12 +8716,12 @@ class DynamicPageConfigEditorComponent {
8572
8716
  isDirty$ = new BehaviorSubject(false);
8573
8717
  isValid$ = new BehaviorSubject(true);
8574
8718
  isBusy$ = new BehaviorSubject(false);
8575
- activeTab = signal('canvas', ...(ngDevMode ? [{ debugName: "activeTab" }] : []));
8576
- canvasError = signal(null, ...(ngDevMode ? [{ debugName: "canvasError" }] : []));
8577
- groupingError = signal(null, ...(ngDevMode ? [{ debugName: "groupingError" }] : []));
8578
- contextError = signal(null, ...(ngDevMode ? [{ debugName: "contextError" }] : []));
8579
- stateError = signal(null, ...(ngDevMode ? [{ debugName: "stateError" }] : []));
8580
- deviceError = signal(null, ...(ngDevMode ? [{ debugName: "deviceError" }] : []));
8719
+ activeTab = signal('canvas', ...(ngDevMode ? [{ debugName: "activeTab" }] : /* istanbul ignore next */ []));
8720
+ canvasError = signal(null, ...(ngDevMode ? [{ debugName: "canvasError" }] : /* istanbul ignore next */ []));
8721
+ groupingError = signal(null, ...(ngDevMode ? [{ debugName: "groupingError" }] : /* istanbul ignore next */ []));
8722
+ contextError = signal(null, ...(ngDevMode ? [{ debugName: "contextError" }] : /* istanbul ignore next */ []));
8723
+ stateError = signal(null, ...(ngDevMode ? [{ debugName: "stateError" }] : /* istanbul ignore next */ []));
8724
+ deviceError = signal(null, ...(ngDevMode ? [{ debugName: "deviceError" }] : /* istanbul ignore next */ []));
8581
8725
  injectedData = inject(SETTINGS_PANEL_DATA$1, { optional: true });
8582
8726
  pageInput = null;
8583
8727
  snapshot = '';
@@ -8746,8 +8890,8 @@ class DynamicPageConfigEditorComponent {
8746
8890
  defaultCanvas() { return { mode: 'grid', columns: 12, rowUnit: '80px', gap: '16px', autoRows: 'fixed', items: {} }; }
8747
8891
  clone(value) { if (value == null || typeof value !== 'object')
8748
8892
  return value; return JSON.parse(JSON.stringify(value)); }
8749
- static ɵfac = i0.ɵɵngDeclareFactory({ minVersion: "12.0.0", version: "20.3.17", ngImport: i0, type: DynamicPageConfigEditorComponent, deps: [], target: i0.ɵɵFactoryTarget.Component });
8750
- static ɵcmp = i0.ɵɵngDeclareComponent({ minVersion: "17.0.0", version: "20.3.17", type: DynamicPageConfigEditorComponent, isStandalone: true, selector: "praxis-dynamic-page-config-editor", inputs: { page: "page", layout: "layout", presets: "presets", pagePreset: "pagePreset" }, outputs: { pageChange: "pageChange" }, ngImport: i0, template: `
8893
+ static ɵfac = i0.ɵɵngDeclareFactory({ minVersion: "12.0.0", version: "21.2.14", ngImport: i0, type: DynamicPageConfigEditorComponent, deps: [], target: i0.ɵɵFactoryTarget.Component });
8894
+ static ɵcmp = i0.ɵɵngDeclareComponent({ minVersion: "17.0.0", version: "21.2.14", type: DynamicPageConfigEditorComponent, isStandalone: true, selector: "praxis-dynamic-page-config-editor", inputs: { page: "page", layout: "layout", presets: "presets", pagePreset: "pagePreset" }, outputs: { pageChange: "pageChange" }, ngImport: i0, template: `
8751
8895
  <div class="editor">
8752
8896
  <div class="head">
8753
8897
  <div>Configuracao da pagina</div>
@@ -8768,11 +8912,11 @@ class DynamicPageConfigEditorComponent {
8768
8912
  <mat-tab label="Estado da Pagina"><mat-form-field appearance="outline" class="wide"><mat-label>State (JSON)</mat-label><textarea matInput rows="14" [formControl]="stateControl"></textarea></mat-form-field></mat-tab>
8769
8913
  </mat-tab-group>
8770
8914
  </div>
8771
- `, isInline: true, styles: [".editor,.panel{display:grid;gap:16px;color:var(--md-sys-color-on-surface, currentColor)}.head,.summary{display:flex;gap:12px;align-items:center;flex-wrap:wrap}.summary{color:var(--md-sys-color-on-surface-variant, currentColor)}.grid{display:grid;gap:12px;grid-template-columns:repeat(auto-fit,minmax(220px,1fr))}.card{display:grid;gap:12px;padding:16px;border:1px solid var(--md-sys-color-outline-variant, color-mix(in srgb, currentColor 18%, transparent));border-radius:8px;background:var(--md-sys-color-surface-container-low, var(--md-sys-color-surface-container, transparent));color:var(--md-sys-color-on-surface, currentColor)}.wide{grid-column:1 / -1}.hint{color:var(--md-sys-color-on-surface-variant, currentColor);font-size:12px}:host ::ng-deep .mat-mdc-tab-body-content{padding-top:12px;box-sizing:border-box}\n"], dependencies: [{ kind: "ngmodule", type: CommonModule }, { kind: "ngmodule", type: ReactiveFormsModule }, { kind: "directive", type: i1$1.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$1.NumberValueAccessor, selector: "input[type=number][formControlName],input[type=number][formControl],input[type=number][ngModel]" }, { kind: "directive", type: i1$1.NgControlStatus, selector: "[formControlName],[ngModel],[formControl]" }, { kind: "directive", type: i1$1.NgControlStatusGroup, selector: "[formGroupName],[formArrayName],[ngModelGroup],[formGroup],form:not([ngNoForm]),[ngForm]" }, { kind: "directive", type: i1$1.MinValidator, selector: "input[type=number][min][formControlName],input[type=number][min][formControl],input[type=number][min][ngModel]", inputs: ["min"] }, { kind: "directive", type: i1$1.FormControlDirective, selector: "[formControl]", inputs: ["formControl", "disabled", "ngModel"], outputs: ["ngModelChange"], exportAs: ["ngForm"] }, { kind: "directive", type: i1$1.FormGroupDirective, selector: "[formGroup]", inputs: ["formGroup"], outputs: ["ngSubmit"], exportAs: ["ngForm"] }, { kind: "directive", type: i1$1.FormControlName, selector: "[formControlName]", inputs: ["formControlName", "disabled", "ngModel"], outputs: ["ngModelChange"] }, { kind: "ngmodule", type: MatButtonModule }, { kind: "component", type: i2.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: i2.MatIconButton, selector: "button[mat-icon-button], a[mat-icon-button], button[matIconButton], a[matIconButton]", exportAs: ["matButton", "matAnchor"] }, { kind: "ngmodule", type: MatFormFieldModule }, { kind: "component", type: i3$2.MatFormField, selector: "mat-form-field", inputs: ["hideRequiredMarker", "color", "floatLabel", "appearance", "subscriptSizing", "hintLabel"], exportAs: ["matFormField"] }, { kind: "directive", type: i3$2.MatLabel, selector: "mat-label" }, { kind: "ngmodule", type: MatIconModule }, { kind: "component", type: i3.MatIcon, selector: "mat-icon", inputs: ["color", "inline", "svgIcon", "fontSet", "fontIcon"], exportAs: ["matIcon"] }, { kind: "ngmodule", type: MatInputModule }, { kind: "directive", type: i6.MatInput, selector: "input[matInput], textarea[matInput], select[matNativeControl], input[matNativeControl], textarea[matNativeControl]", inputs: ["disabled", "id", "placeholder", "name", "required", "type", "errorStateMatcher", "aria-describedby", "value", "readonly", "disabledInteractive"], exportAs: ["matInput"] }, { kind: "ngmodule", type: MatSelectModule }, { kind: "component", type: i6$2.MatSelect, selector: "mat-select", inputs: ["aria-describedby", "panelClass", "disabled", "disableRipple", "tabIndex", "hideSingleSelectionIndicator", "placeholder", "required", "multiple", "disableOptionCentering", "compareWith", "value", "aria-label", "aria-labelledby", "errorStateMatcher", "typeaheadDebounceInterval", "sortComparator", "id", "panelWidth", "canSelectNullableOptions"], outputs: ["openedChange", "opened", "closed", "selectionChange", "valueChange"], exportAs: ["matSelect"] }, { kind: "component", type: i6$2.MatOption, selector: "mat-option", inputs: ["value", "id", "disabled"], outputs: ["onSelectionChange"], exportAs: ["matOption"] }, { kind: "ngmodule", type: MatTabsModule }, { kind: "component", type: i7.MatTab, selector: "mat-tab", inputs: ["disabled", "label", "aria-label", "aria-labelledby", "labelClass", "bodyClass", "id"], exportAs: ["matTab"] }, { kind: "component", type: i7.MatTabGroup, selector: "mat-tab-group", inputs: ["color", "fitInkBarToContent", "mat-stretch-tabs", "mat-align-tabs", "dynamicHeight", "selectedIndex", "headerPosition", "animationDuration", "contentTabIndex", "disablePagination", "disableRipple", "preserveContent", "backgroundColor", "aria-label", "aria-labelledby"], outputs: ["selectedIndexChange", "focusChange", "animationDone", "selectedTabChange"], exportAs: ["matTabGroup"] }], changeDetection: i0.ChangeDetectionStrategy.OnPush });
8915
+ `, isInline: true, styles: [".editor,.panel{display:grid;gap:16px;color:var(--md-sys-color-on-surface, currentColor)}.head,.summary{display:flex;gap:12px;align-items:center;flex-wrap:wrap}.summary{color:var(--md-sys-color-on-surface-variant, currentColor)}.grid{display:grid;gap:12px;grid-template-columns:repeat(auto-fit,minmax(220px,1fr))}.card{display:grid;gap:12px;padding:16px;border:1px solid var(--md-sys-color-outline-variant, color-mix(in srgb, currentColor 18%, transparent));border-radius:8px;background:var(--md-sys-color-surface-container-low, var(--md-sys-color-surface-container, transparent));color:var(--md-sys-color-on-surface, currentColor)}.wide{grid-column:1 / -1}.hint{color:var(--md-sys-color-on-surface-variant, currentColor);font-size:12px}:host ::ng-deep .mat-mdc-tab-body-content{padding-top:12px;box-sizing:border-box}\n"], dependencies: [{ kind: "ngmodule", type: ReactiveFormsModule }, { kind: "directive", type: i1$1.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$1.NumberValueAccessor, selector: "input[type=number][formControlName],input[type=number][formControl],input[type=number][ngModel]" }, { kind: "directive", type: i1$1.NgControlStatus, selector: "[formControlName],[ngModel],[formControl]" }, { kind: "directive", type: i1$1.NgControlStatusGroup, selector: "[formGroupName],[formArrayName],[ngModelGroup],[formGroup],[formArray],form:not([ngNoForm]),[ngForm]" }, { kind: "directive", type: i1$1.MinValidator, selector: "input[type=number][min][formControlName],input[type=number][min][formControl],input[type=number][min][ngModel]", inputs: ["min"] }, { kind: "directive", type: i1$1.FormControlDirective, selector: "[formControl]", inputs: ["formControl", "disabled", "ngModel"], outputs: ["ngModelChange"], exportAs: ["ngForm"] }, { kind: "directive", type: i1$1.FormGroupDirective, selector: "[formGroup]", inputs: ["formGroup"], outputs: ["ngSubmit"], exportAs: ["ngForm"] }, { kind: "directive", type: i1$1.FormControlName, selector: "[formControlName]", inputs: ["formControlName", "disabled", "ngModel"], outputs: ["ngModelChange"] }, { kind: "ngmodule", type: MatButtonModule }, { kind: "component", type: i2.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: i2.MatIconButton, selector: "button[mat-icon-button], a[mat-icon-button], button[matIconButton], a[matIconButton]", exportAs: ["matButton", "matAnchor"] }, { kind: "ngmodule", type: MatFormFieldModule }, { kind: "component", type: i3$1.MatFormField, selector: "mat-form-field", inputs: ["hideRequiredMarker", "color", "floatLabel", "appearance", "subscriptSizing", "hintLabel"], exportAs: ["matFormField"] }, { kind: "directive", type: i3$1.MatLabel, selector: "mat-label" }, { kind: "ngmodule", type: MatIconModule }, { kind: "component", type: i2$1.MatIcon, selector: "mat-icon", inputs: ["color", "inline", "svgIcon", "fontSet", "fontIcon"], exportAs: ["matIcon"] }, { kind: "ngmodule", type: MatInputModule }, { kind: "directive", type: i5.MatInput, selector: "input[matInput], textarea[matInput], select[matNativeControl], input[matNativeControl], textarea[matNativeControl]", inputs: ["disabled", "id", "placeholder", "name", "required", "type", "errorStateMatcher", "aria-describedby", "value", "readonly", "disabledInteractive"], exportAs: ["matInput"] }, { kind: "ngmodule", type: MatSelectModule }, { kind: "component", type: i6$1.MatSelect, selector: "mat-select", inputs: ["aria-describedby", "panelClass", "disabled", "disableRipple", "tabIndex", "hideSingleSelectionIndicator", "placeholder", "required", "multiple", "disableOptionCentering", "compareWith", "value", "aria-label", "aria-labelledby", "errorStateMatcher", "typeaheadDebounceInterval", "sortComparator", "id", "panelWidth", "canSelectNullableOptions"], outputs: ["openedChange", "opened", "closed", "selectionChange", "valueChange"], exportAs: ["matSelect"] }, { kind: "component", type: i6$1.MatOption, selector: "mat-option", inputs: ["value", "id", "disabled"], outputs: ["onSelectionChange"], exportAs: ["matOption"] }, { kind: "ngmodule", type: MatTabsModule }, { kind: "component", type: i7.MatTab, selector: "mat-tab", inputs: ["disabled", "label", "aria-label", "aria-labelledby", "labelClass", "bodyClass", "id"], exportAs: ["matTab"] }, { kind: "component", type: i7.MatTabGroup, selector: "mat-tab-group", inputs: ["color", "fitInkBarToContent", "mat-stretch-tabs", "mat-align-tabs", "dynamicHeight", "selectedIndex", "headerPosition", "animationDuration", "contentTabIndex", "disablePagination", "disableRipple", "preserveContent", "backgroundColor", "aria-label", "aria-labelledby"], outputs: ["selectedIndexChange", "focusChange", "animationDone", "selectedTabChange"], exportAs: ["matTabGroup"] }], changeDetection: i0.ChangeDetectionStrategy.OnPush });
8772
8916
  }
8773
- i0.ɵɵngDeclareClassMetadata({ minVersion: "12.0.0", version: "20.3.17", ngImport: i0, type: DynamicPageConfigEditorComponent, decorators: [{
8917
+ i0.ɵɵngDeclareClassMetadata({ minVersion: "12.0.0", version: "21.2.14", ngImport: i0, type: DynamicPageConfigEditorComponent, decorators: [{
8774
8918
  type: Component,
8775
- args: [{ selector: 'praxis-dynamic-page-config-editor', standalone: true, imports: [CommonModule, ReactiveFormsModule, MatButtonModule, MatFormFieldModule, MatIconModule, MatInputModule, MatSelectModule, MatTabsModule], template: `
8919
+ args: [{ selector: 'praxis-dynamic-page-config-editor', standalone: true, imports: [ReactiveFormsModule, MatButtonModule, MatFormFieldModule, MatIconModule, MatInputModule, MatSelectModule, MatTabsModule], template: `
8776
8920
  <div class="editor">
8777
8921
  <div class="head">
8778
8922
  <div>Configuracao da pagina</div>
@@ -8817,9 +8961,9 @@ class PageConfigEditorComponent {
8817
8961
  groupingKinds = GROUPING_KINDS;
8818
8962
  layoutPresetEntries = Object.values(BUILTIN_PAGE_LAYOUT_PRESETS);
8819
8963
  themePresetEntries = Object.values(BUILTIN_PAGE_THEME_PRESETS);
8820
- page = input(null, ...(ngDevMode ? [{ debugName: "page" }] : []));
8821
- identity = input(null, ...(ngDevMode ? [{ debugName: "identity" }] : []));
8822
- layoutCompatOptions = input(null, ...(ngDevMode ? [{ debugName: "layoutCompatOptions" }] : []));
8964
+ page = input(null, ...(ngDevMode ? [{ debugName: "page" }] : /* istanbul ignore next */ []));
8965
+ identity = input(null, ...(ngDevMode ? [{ debugName: "identity" }] : /* istanbul ignore next */ []));
8966
+ layoutCompatOptions = input(null, ...(ngDevMode ? [{ debugName: "layoutCompatOptions" }] : /* istanbul ignore next */ []));
8823
8967
  pageChange = output();
8824
8968
  form = new FormGroup({
8825
8969
  cols: new FormControl(null),
@@ -8839,10 +8983,10 @@ class PageConfigEditorComponent {
8839
8983
  deviceDesktopForm = this.createDeviceLayoutForm();
8840
8984
  deviceTabletForm = this.createDeviceLayoutForm();
8841
8985
  deviceMobileForm = this.createDeviceLayoutForm();
8842
- contextError = signal(null, ...(ngDevMode ? [{ debugName: "contextError" }] : []));
8843
- layoutError = signal(null, ...(ngDevMode ? [{ debugName: "layoutError" }] : []));
8844
- stateError = signal(null, ...(ngDevMode ? [{ debugName: "stateError" }] : []));
8845
- activeTab = signal('layout', ...(ngDevMode ? [{ debugName: "activeTab" }] : []));
8986
+ contextError = signal(null, ...(ngDevMode ? [{ debugName: "contextError" }] : /* istanbul ignore next */ []));
8987
+ layoutError = signal(null, ...(ngDevMode ? [{ debugName: "layoutError" }] : /* istanbul ignore next */ []));
8988
+ stateError = signal(null, ...(ngDevMode ? [{ debugName: "stateError" }] : /* istanbul ignore next */ []));
8989
+ activeTab = signal('layout', ...(ngDevMode ? [{ debugName: "activeTab" }] : /* istanbul ignore next */ []));
8846
8990
  shellPresetEntries = Object.entries(BUILTIN_SHELL_PRESETS).map(([id, preset]) => ({
8847
8991
  id,
8848
8992
  label: preset?.label || id,
@@ -9654,8 +9798,8 @@ class PageConfigEditorComponent {
9654
9798
  return value;
9655
9799
  return JSON.parse(JSON.stringify(value));
9656
9800
  }
9657
- static ɵfac = i0.ɵɵngDeclareFactory({ minVersion: "12.0.0", version: "20.3.17", ngImport: i0, type: PageConfigEditorComponent, deps: [], target: i0.ɵɵFactoryTarget.Component });
9658
- static ɵcmp = i0.ɵɵngDeclareComponent({ minVersion: "17.0.0", version: "20.3.17", type: PageConfigEditorComponent, isStandalone: true, selector: "praxis-page-config-editor", inputs: { page: { classPropertyName: "page", publicName: "page", isSignal: true, isRequired: false, transformFunction: null }, identity: { classPropertyName: "identity", publicName: "identity", isSignal: true, isRequired: false, transformFunction: null }, layoutCompatOptions: { classPropertyName: "layoutCompatOptions", publicName: "layoutCompatOptions", isSignal: true, isRequired: false, transformFunction: null } }, outputs: { pageChange: "pageChange" }, providers: [providePraxisPageBuilderI18n()], ngImport: i0, template: `
9801
+ static ɵfac = i0.ɵɵngDeclareFactory({ minVersion: "12.0.0", version: "21.2.14", ngImport: i0, type: PageConfigEditorComponent, deps: [], target: i0.ɵɵFactoryTarget.Component });
9802
+ static ɵcmp = i0.ɵɵngDeclareComponent({ minVersion: "17.0.0", version: "21.2.14", type: PageConfigEditorComponent, isStandalone: true, selector: "praxis-page-config-editor", inputs: { page: { classPropertyName: "page", publicName: "page", isSignal: true, isRequired: false, transformFunction: null }, identity: { classPropertyName: "identity", publicName: "identity", isSignal: true, isRequired: false, transformFunction: null }, layoutCompatOptions: { classPropertyName: "layoutCompatOptions", publicName: "layoutCompatOptions", isSignal: true, isRequired: false, transformFunction: null } }, outputs: { pageChange: "pageChange" }, providers: [providePraxisPageBuilderI18n()], ngImport: i0, template: `
9659
9803
  <div class="page-config">
9660
9804
  <div class="page-head">
9661
9805
  <div class="page-head__copy"><div class="page-title">{{ tx('editor.title', 'Page settings') }}</div><div class="page-subtitle">{{ tx('editor.subtitle', 'Define layout, themes, grouping and declarative state without leaving the canonical dynamic page flow.') }}</div></div>
@@ -10273,12 +10417,11 @@ class PageConfigEditorComponent {
10273
10417
  </div>
10274
10418
  }
10275
10419
  </div>
10276
- `, isInline: true, styles: [".page-config{display:grid;gap:12px;padding:16px;background:var(--md-sys-color-surface-container-lowest, var(--md-sys-color-surface));border:1px solid var(--md-sys-color-outline-variant);border-radius:12px}.page-head{display:flex;align-items:flex-start;gap:12px}.page-head__copy{display:grid;gap:4px}.page-title{font-weight:600;font-size:18px;line-height:1.2}.page-subtitle{max-width:72ch;color:var(--md-sys-color-on-surface-variant);font-size:13px;line-height:1.45}.spacer{flex:1}.page-summary{display:flex;flex-wrap:wrap;gap:8px}.page-tabs{border-radius:16px;overflow:hidden;background:color-mix(in srgb,var(--md-sys-color-surface-container-low) 78%,transparent);border:1px solid color-mix(in srgb,var(--md-sys-color-outline-variant) 82%,transparent)}.page-tabs ::ng-deep .mdc-tab{min-width:120px}.page-tabs ::ng-deep .mdc-tab__text-label{font-size:13px;font-weight:600}.page-tab-panel{display:grid;gap:12px;padding:16px 4px 4px}.page-chip{display:inline-flex;align-items:center;gap:8px;min-height:36px;padding:0 12px;border-radius:999px;border:1px solid color-mix(in srgb,var(--md-sys-color-outline-variant) 88%,transparent);background:color-mix(in srgb,var(--md-sys-color-surface-container-low) 82%,transparent);color:var(--md-sys-color-on-surface-variant);font-size:12px;font-weight:500}.page-chip mat-icon{width:18px;height:18px;font-size:18px}.page-chip--accent{border-color:color-mix(in srgb,var(--md-sys-color-primary) 35%,var(--md-sys-color-outline-variant));color:var(--md-sys-color-primary);background:color-mix(in srgb,var(--md-sys-color-primary-container) 30%,transparent)}.page-chip--warning{border-color:color-mix(in srgb,var(--md-sys-color-error) 35%,var(--md-sys-color-outline-variant));color:var(--md-sys-color-error);background:color-mix(in srgb,var(--md-sys-color-error-container) 35%,transparent)}.page-identity{display:grid;gap:4px;padding:12px 14px;border-radius:12px;border:1px solid color-mix(in srgb,var(--md-sys-color-outline-variant) 82%,transparent);background:color-mix(in srgb,var(--md-sys-color-surface-container-low) 70%,transparent);font-size:13px;color:var(--md-sys-color-on-surface-variant)}.page-section{font-weight:600;margin-top:8px}.page-section-help{margin-top:-4px;color:var(--md-sys-color-on-surface-variant);font-size:13px;line-height:1.45}.grid-form{display:grid;gap:12px;grid-template-columns:repeat(auto-fit,minmax(180px,1fr))}.state-grid{display:grid;gap:16px}.state-values,.state-group{padding:14px;border:1px solid var(--md-sys-color-outline-variant);border-radius:14px;background:linear-gradient(180deg,color-mix(in srgb,var(--md-sys-color-surface-container-low) 92%,transparent),transparent),var(--md-sys-color-surface-container-lowest, var(--md-sys-color-surface))}.state-group{display:grid;gap:12px}.state-group-head{display:flex;align-items:center;justify-content:space-between;gap:12px}.state-group-title{font-weight:600}.state-group-help{color:var(--md-sys-color-on-surface-variant);font-size:13px}.state-list{display:grid;gap:12px}.state-card{display:grid;gap:12px;padding:12px;border-radius:12px;border:1px solid color-mix(in srgb,var(--md-sys-color-outline-variant) 80%,transparent);background:color-mix(in srgb,var(--md-sys-color-surface-container) 84%,transparent)}.state-card-head{display:flex;align-items:center;justify-content:space-between;gap:12px}.state-card-title{font-weight:600}.state-card-grid{display:grid;gap:12px;grid-template-columns:repeat(auto-fit,minmax(180px,1fr))}.span-2{grid-column:span 2}.span-3{grid-column:1 / -1}.state-empty{color:var(--md-sys-color-on-surface-variant);font-size:13px}.state-operator-hint{display:flex;align-items:center;gap:8px;min-height:48px;padding:0 12px;border-radius:12px;color:var(--md-sys-color-on-surface-variant);background:color-mix(in srgb,var(--md-sys-color-secondary-container) 35%,transparent)}.state-operator-hint mat-icon{color:var(--md-sys-color-secondary)}.page-actions{display:flex;justify-content:flex-end}.page-error{color:var(--md-sys-color-error);font-size:13px}.page-config .mat-mdc-form-field{width:100%;--mdc-outlined-text-field-container-height: 48px;--mdc-outlined-text-field-outline-color: var(--md-sys-color-outline-variant);--mdc-outlined-text-field-hover-outline-color: var(--md-sys-color-outline);--mdc-outlined-text-field-focus-outline-color: var(--md-sys-color-primary);--mdc-outlined-text-field-error-outline-color: var(--md-sys-color-error);--mdc-outlined-text-field-error-focus-outline-color: var(--md-sys-color-error);--mdc-outlined-text-field-error-hover-outline-color: var(--md-sys-color-error);--mdc-outlined-text-field-label-text-color: var(--md-sys-color-on-surface-variant);--mdc-outlined-text-field-input-text-color: var(--md-sys-color-on-surface);--mdc-outlined-text-field-supporting-text-color: var(--md-sys-color-on-surface-variant)}.help-icon-button{--mdc-icon-button-state-layer-size: 28px;--mdc-icon-button-icon-size: 18px;width:28px;height:28px;padding:0;display:inline-flex;align-items:center;justify-content:center;margin-right:-4px}.help-icon-button mat-icon{font-size:18px;width:18px;height:18px}.mat-mdc-form-field-icon-suffix{align-self:center}@media(max-width:720px){.span-2,.span-3{grid-column:auto}.page-head{flex-direction:column}.state-group-head{align-items:stretch;flex-direction:column}}\n"], dependencies: [{ kind: "ngmodule", type: CommonModule }, { kind: "ngmodule", type: ReactiveFormsModule }, { kind: "directive", type: i1$1.ɵNgNoValidate, selector: "form:not([ngNoForm]):not([ngNativeValidate])" }, { kind: "directive", type: i1$1.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$1.NumberValueAccessor, selector: "input[type=number][formControlName],input[type=number][formControl],input[type=number][ngModel]" }, { kind: "directive", type: i1$1.NgControlStatus, selector: "[formControlName],[ngModel],[formControl]" }, { kind: "directive", type: i1$1.NgControlStatusGroup, selector: "[formGroupName],[formArrayName],[ngModelGroup],[formGroup],form:not([ngNoForm]),[ngForm]" }, { kind: "directive", type: i1$1.MinValidator, selector: "input[type=number][min][formControlName],input[type=number][min][formControl],input[type=number][min][ngModel]", inputs: ["min"] }, { kind: "directive", type: i1$1.FormControlDirective, selector: "[formControl]", inputs: ["formControl", "disabled", "ngModel"], outputs: ["ngModelChange"], exportAs: ["ngForm"] }, { kind: "directive", type: i1$1.FormGroupDirective, selector: "[formGroup]", inputs: ["formGroup"], outputs: ["ngSubmit"], exportAs: ["ngForm"] }, { kind: "directive", type: i1$1.FormControlName, selector: "[formControlName]", inputs: ["formControlName", "disabled", "ngModel"], outputs: ["ngModelChange"] }, { kind: "ngmodule", type: MatButtonModule }, { kind: "component", type: i2.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: i2.MatIconButton, selector: "button[mat-icon-button], a[mat-icon-button], button[matIconButton], a[matIconButton]", exportAs: ["matButton", "matAnchor"] }, { kind: "ngmodule", type: MatFormFieldModule }, { kind: "component", type: i3$2.MatFormField, selector: "mat-form-field", inputs: ["hideRequiredMarker", "color", "floatLabel", "appearance", "subscriptSizing", "hintLabel"], exportAs: ["matFormField"] }, { kind: "directive", type: i3$2.MatLabel, selector: "mat-label" }, { kind: "directive", type: i3$2.MatSuffix, selector: "[matSuffix], [matIconSuffix], [matTextSuffix]", inputs: ["matTextSuffix"] }, { kind: "ngmodule", type: MatInputModule }, { kind: "directive", type: i6.MatInput, selector: "input[matInput], textarea[matInput], select[matNativeControl], input[matNativeControl], textarea[matNativeControl]", inputs: ["disabled", "id", "placeholder", "name", "required", "type", "errorStateMatcher", "aria-describedby", "value", "readonly", "disabledInteractive"], exportAs: ["matInput"] }, { kind: "ngmodule", type: MatIconModule }, { kind: "component", type: i3.MatIcon, selector: "mat-icon", inputs: ["color", "inline", "svgIcon", "fontSet", "fontIcon"], exportAs: ["matIcon"] }, { kind: "ngmodule", type: MatSelectModule }, { kind: "component", type: i6$2.MatSelect, selector: "mat-select", inputs: ["aria-describedby", "panelClass", "disabled", "disableRipple", "tabIndex", "hideSingleSelectionIndicator", "placeholder", "required", "multiple", "disableOptionCentering", "compareWith", "value", "aria-label", "aria-labelledby", "errorStateMatcher", "typeaheadDebounceInterval", "sortComparator", "id", "panelWidth", "canSelectNullableOptions"], outputs: ["openedChange", "opened", "closed", "selectionChange", "valueChange"], exportAs: ["matSelect"] }, { kind: "component", type: i6$2.MatOption, selector: "mat-option", inputs: ["value", "id", "disabled"], outputs: ["onSelectionChange"], exportAs: ["matOption"] }, { kind: "ngmodule", type: MatTabsModule }, { kind: "component", type: i7.MatTab, selector: "mat-tab", inputs: ["disabled", "label", "aria-label", "aria-labelledby", "labelClass", "bodyClass", "id"], exportAs: ["matTab"] }, { kind: "component", type: i7.MatTabGroup, selector: "mat-tab-group", inputs: ["color", "fitInkBarToContent", "mat-stretch-tabs", "mat-align-tabs", "dynamicHeight", "selectedIndex", "headerPosition", "animationDuration", "contentTabIndex", "disablePagination", "disableRipple", "preserveContent", "backgroundColor", "aria-label", "aria-labelledby"], outputs: ["selectedIndexChange", "focusChange", "animationDone", "selectedTabChange"], exportAs: ["matTabGroup"] }, { kind: "ngmodule", type: MatTooltipModule }, { kind: "directive", type: i3$1.MatTooltip, selector: "[matTooltip]", inputs: ["matTooltipPosition", "matTooltipPositionAtOrigin", "matTooltipDisabled", "matTooltipShowDelay", "matTooltipHideDelay", "matTooltipTouchGestures", "matTooltip", "matTooltipClass"], exportAs: ["matTooltip"] }], changeDetection: i0.ChangeDetectionStrategy.OnPush });
10420
+ `, isInline: true, styles: [".page-config{display:grid;gap:12px;padding:16px;background:var(--md-sys-color-surface-container-lowest, var(--md-sys-color-surface));border:1px solid var(--md-sys-color-outline-variant);border-radius:12px}.page-head{display:flex;align-items:flex-start;gap:12px}.page-head__copy{display:grid;gap:4px}.page-title{font-weight:600;font-size:18px;line-height:1.2}.page-subtitle{max-width:72ch;color:var(--md-sys-color-on-surface-variant);font-size:13px;line-height:1.45}.spacer{flex:1}.page-summary{display:flex;flex-wrap:wrap;gap:8px}.page-tabs{border-radius:16px;overflow:hidden;background:color-mix(in srgb,var(--md-sys-color-surface-container-low) 78%,transparent);border:1px solid color-mix(in srgb,var(--md-sys-color-outline-variant) 82%,transparent)}.page-tabs ::ng-deep .mdc-tab{min-width:120px}.page-tabs ::ng-deep .mdc-tab__text-label{font-size:13px;font-weight:600}.page-tab-panel{display:grid;gap:12px;padding:16px 4px 4px}.page-chip{display:inline-flex;align-items:center;gap:8px;min-height:36px;padding:0 12px;border-radius:999px;border:1px solid color-mix(in srgb,var(--md-sys-color-outline-variant) 88%,transparent);background:color-mix(in srgb,var(--md-sys-color-surface-container-low) 82%,transparent);color:var(--md-sys-color-on-surface-variant);font-size:12px;font-weight:500}.page-chip mat-icon{width:18px;height:18px;font-size:18px}.page-chip--accent{border-color:color-mix(in srgb,var(--md-sys-color-primary) 35%,var(--md-sys-color-outline-variant));color:var(--md-sys-color-primary);background:color-mix(in srgb,var(--md-sys-color-primary-container) 30%,transparent)}.page-chip--warning{border-color:color-mix(in srgb,var(--md-sys-color-error) 35%,var(--md-sys-color-outline-variant));color:var(--md-sys-color-error);background:color-mix(in srgb,var(--md-sys-color-error-container) 35%,transparent)}.page-identity{display:grid;gap:4px;padding:12px 14px;border-radius:12px;border:1px solid color-mix(in srgb,var(--md-sys-color-outline-variant) 82%,transparent);background:color-mix(in srgb,var(--md-sys-color-surface-container-low) 70%,transparent);font-size:13px;color:var(--md-sys-color-on-surface-variant)}.page-section{font-weight:600;margin-top:8px}.page-section-help{margin-top:-4px;color:var(--md-sys-color-on-surface-variant);font-size:13px;line-height:1.45}.grid-form{display:grid;gap:12px;grid-template-columns:repeat(auto-fit,minmax(180px,1fr))}.state-grid{display:grid;gap:16px}.state-values,.state-group{padding:14px;border:1px solid var(--md-sys-color-outline-variant);border-radius:14px;background:linear-gradient(180deg,color-mix(in srgb,var(--md-sys-color-surface-container-low) 92%,transparent),transparent),var(--md-sys-color-surface-container-lowest, var(--md-sys-color-surface))}.state-group{display:grid;gap:12px}.state-group-head{display:flex;align-items:center;justify-content:space-between;gap:12px}.state-group-title{font-weight:600}.state-group-help{color:var(--md-sys-color-on-surface-variant);font-size:13px}.state-list{display:grid;gap:12px}.state-card{display:grid;gap:12px;padding:12px;border-radius:12px;border:1px solid color-mix(in srgb,var(--md-sys-color-outline-variant) 80%,transparent);background:color-mix(in srgb,var(--md-sys-color-surface-container) 84%,transparent)}.state-card-head{display:flex;align-items:center;justify-content:space-between;gap:12px}.state-card-title{font-weight:600}.state-card-grid{display:grid;gap:12px;grid-template-columns:repeat(auto-fit,minmax(180px,1fr))}.span-2{grid-column:span 2}.span-3{grid-column:1 / -1}.state-empty{color:var(--md-sys-color-on-surface-variant);font-size:13px}.state-operator-hint{display:flex;align-items:center;gap:8px;min-height:48px;padding:0 12px;border-radius:12px;color:var(--md-sys-color-on-surface-variant);background:color-mix(in srgb,var(--md-sys-color-secondary-container) 35%,transparent)}.state-operator-hint mat-icon{color:var(--md-sys-color-secondary)}.page-actions{display:flex;justify-content:flex-end}.page-error{color:var(--md-sys-color-error);font-size:13px}.page-config .mat-mdc-form-field{width:100%;--mdc-outlined-text-field-container-height: 48px;--mdc-outlined-text-field-outline-color: var(--md-sys-color-outline-variant);--mdc-outlined-text-field-hover-outline-color: var(--md-sys-color-outline);--mdc-outlined-text-field-focus-outline-color: var(--md-sys-color-primary);--mdc-outlined-text-field-error-outline-color: var(--md-sys-color-error);--mdc-outlined-text-field-error-focus-outline-color: var(--md-sys-color-error);--mdc-outlined-text-field-error-hover-outline-color: var(--md-sys-color-error);--mdc-outlined-text-field-label-text-color: var(--md-sys-color-on-surface-variant);--mdc-outlined-text-field-input-text-color: var(--md-sys-color-on-surface);--mdc-outlined-text-field-supporting-text-color: var(--md-sys-color-on-surface-variant)}.help-icon-button{--mdc-icon-button-state-layer-size: 28px;--mdc-icon-button-icon-size: 18px;width:28px;height:28px;padding:0;display:inline-flex;align-items:center;justify-content:center;margin-right:-4px}.help-icon-button mat-icon{font-size:18px;width:18px;height:18px}.mat-mdc-form-field-icon-suffix{align-self:center}@media(max-width:720px){.span-2,.span-3{grid-column:auto}.page-head{flex-direction:column}.state-group-head{align-items:stretch;flex-direction:column}}\n"], dependencies: [{ kind: "ngmodule", type: ReactiveFormsModule }, { kind: "directive", type: i1$1.ɵNgNoValidate, selector: "form:not([ngNoForm]):not([ngNativeValidate])" }, { kind: "directive", type: i1$1.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$1.NumberValueAccessor, selector: "input[type=number][formControlName],input[type=number][formControl],input[type=number][ngModel]" }, { kind: "directive", type: i1$1.NgControlStatus, selector: "[formControlName],[ngModel],[formControl]" }, { kind: "directive", type: i1$1.NgControlStatusGroup, selector: "[formGroupName],[formArrayName],[ngModelGroup],[formGroup],[formArray],form:not([ngNoForm]),[ngForm]" }, { kind: "directive", type: i1$1.MinValidator, selector: "input[type=number][min][formControlName],input[type=number][min][formControl],input[type=number][min][ngModel]", inputs: ["min"] }, { kind: "directive", type: i1$1.FormControlDirective, selector: "[formControl]", inputs: ["formControl", "disabled", "ngModel"], outputs: ["ngModelChange"], exportAs: ["ngForm"] }, { kind: "directive", type: i1$1.FormGroupDirective, selector: "[formGroup]", inputs: ["formGroup"], outputs: ["ngSubmit"], exportAs: ["ngForm"] }, { kind: "directive", type: i1$1.FormControlName, selector: "[formControlName]", inputs: ["formControlName", "disabled", "ngModel"], outputs: ["ngModelChange"] }, { kind: "ngmodule", type: MatButtonModule }, { kind: "component", type: i2.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: i2.MatIconButton, selector: "button[mat-icon-button], a[mat-icon-button], button[matIconButton], a[matIconButton]", exportAs: ["matButton", "matAnchor"] }, { kind: "ngmodule", type: MatFormFieldModule }, { kind: "component", type: i3$1.MatFormField, selector: "mat-form-field", inputs: ["hideRequiredMarker", "color", "floatLabel", "appearance", "subscriptSizing", "hintLabel"], exportAs: ["matFormField"] }, { kind: "directive", type: i3$1.MatLabel, selector: "mat-label" }, { kind: "directive", type: i3$1.MatSuffix, selector: "[matSuffix], [matIconSuffix], [matTextSuffix]", inputs: ["matTextSuffix"] }, { kind: "ngmodule", type: MatInputModule }, { kind: "directive", type: i5.MatInput, selector: "input[matInput], textarea[matInput], select[matNativeControl], input[matNativeControl], textarea[matNativeControl]", inputs: ["disabled", "id", "placeholder", "name", "required", "type", "errorStateMatcher", "aria-describedby", "value", "readonly", "disabledInteractive"], exportAs: ["matInput"] }, { kind: "ngmodule", type: MatIconModule }, { kind: "component", type: i2$1.MatIcon, selector: "mat-icon", inputs: ["color", "inline", "svgIcon", "fontSet", "fontIcon"], exportAs: ["matIcon"] }, { kind: "ngmodule", type: MatSelectModule }, { kind: "component", type: i6$1.MatSelect, selector: "mat-select", inputs: ["aria-describedby", "panelClass", "disabled", "disableRipple", "tabIndex", "hideSingleSelectionIndicator", "placeholder", "required", "multiple", "disableOptionCentering", "compareWith", "value", "aria-label", "aria-labelledby", "errorStateMatcher", "typeaheadDebounceInterval", "sortComparator", "id", "panelWidth", "canSelectNullableOptions"], outputs: ["openedChange", "opened", "closed", "selectionChange", "valueChange"], exportAs: ["matSelect"] }, { kind: "component", type: i6$1.MatOption, selector: "mat-option", inputs: ["value", "id", "disabled"], outputs: ["onSelectionChange"], exportAs: ["matOption"] }, { kind: "ngmodule", type: MatTabsModule }, { kind: "component", type: i7.MatTab, selector: "mat-tab", inputs: ["disabled", "label", "aria-label", "aria-labelledby", "labelClass", "bodyClass", "id"], exportAs: ["matTab"] }, { kind: "component", type: i7.MatTabGroup, selector: "mat-tab-group", inputs: ["color", "fitInkBarToContent", "mat-stretch-tabs", "mat-align-tabs", "dynamicHeight", "selectedIndex", "headerPosition", "animationDuration", "contentTabIndex", "disablePagination", "disableRipple", "preserveContent", "backgroundColor", "aria-label", "aria-labelledby"], outputs: ["selectedIndexChange", "focusChange", "animationDone", "selectedTabChange"], exportAs: ["matTabGroup"] }, { kind: "ngmodule", type: MatTooltipModule }, { kind: "directive", type: i3.MatTooltip, selector: "[matTooltip]", inputs: ["matTooltipPosition", "matTooltipPositionAtOrigin", "matTooltipDisabled", "matTooltipShowDelay", "matTooltipHideDelay", "matTooltipTouchGestures", "matTooltip", "matTooltipClass"], exportAs: ["matTooltip"] }], changeDetection: i0.ChangeDetectionStrategy.OnPush });
10277
10421
  }
10278
- i0.ɵɵngDeclareClassMetadata({ minVersion: "12.0.0", version: "20.3.17", ngImport: i0, type: PageConfigEditorComponent, decorators: [{
10422
+ i0.ɵɵngDeclareClassMetadata({ minVersion: "12.0.0", version: "21.2.14", ngImport: i0, type: PageConfigEditorComponent, decorators: [{
10279
10423
  type: Component,
10280
10424
  args: [{ selector: 'praxis-page-config-editor', standalone: true, imports: [
10281
- CommonModule,
10282
10425
  ReactiveFormsModule,
10283
10426
  MatButtonModule,
10284
10427
  MatFormFieldModule,
@@ -10286,7 +10429,7 @@ i0.ɵɵngDeclareClassMetadata({ minVersion: "12.0.0", version: "20.3.17", ngImpo
10286
10429
  MatIconModule,
10287
10430
  MatSelectModule,
10288
10431
  MatTabsModule,
10289
- MatTooltipModule,
10432
+ MatTooltipModule
10290
10433
  ], providers: [providePraxisPageBuilderI18n()], template: `
10291
10434
  <div class="page-config">
10292
10435
  <div class="page-head">
@@ -11521,10 +11664,10 @@ class PageBuilderAgenticAuthoringService {
11521
11664
  }
11522
11665
  return [];
11523
11666
  }
11524
- static ɵfac = i0.ɵɵngDeclareFactory({ minVersion: "12.0.0", version: "20.3.17", ngImport: i0, type: PageBuilderAgenticAuthoringService, deps: [], target: i0.ɵɵFactoryTarget.Injectable });
11525
- static ɵprov = i0.ɵɵngDeclareInjectable({ minVersion: "12.0.0", version: "20.3.17", ngImport: i0, type: PageBuilderAgenticAuthoringService, providedIn: 'root' });
11667
+ static ɵfac = i0.ɵɵngDeclareFactory({ minVersion: "12.0.0", version: "21.2.14", ngImport: i0, type: PageBuilderAgenticAuthoringService, deps: [], target: i0.ɵɵFactoryTarget.Injectable });
11668
+ static ɵprov = i0.ɵɵngDeclareInjectable({ minVersion: "12.0.0", version: "21.2.14", ngImport: i0, type: PageBuilderAgenticAuthoringService, providedIn: 'root' });
11526
11669
  }
11527
- i0.ɵɵngDeclareClassMetadata({ minVersion: "12.0.0", version: "20.3.17", ngImport: i0, type: PageBuilderAgenticAuthoringService, decorators: [{
11670
+ i0.ɵɵngDeclareClassMetadata({ minVersion: "12.0.0", version: "21.2.14", ngImport: i0, type: PageBuilderAgenticAuthoringService, decorators: [{
11528
11671
  type: Injectable,
11529
11672
  args: [{ providedIn: 'root' }]
11530
11673
  }] });
@@ -15086,48 +15229,48 @@ class DynamicPageBuilderComponent {
15086
15229
  agenticAuthoringSharedRuleHandoff = new EventEmitter();
15087
15230
  pageRestart = new EventEmitter();
15088
15231
  savedPageDeleteRequested = new EventEmitter();
15089
- currentPage = signal({ widgets: [] }, ...(ngDevMode ? [{ debugName: "currentPage" }] : []));
15090
- hasPageWidgets = computed(() => (this.currentPage().widgets || []).length > 0, ...(ngDevMode ? [{ debugName: "hasPageWidgets" }] : []));
15091
- connectionsViewerOpen = signal(false, ...(ngDevMode ? [{ debugName: "connectionsViewerOpen" }] : []));
15092
- agenticAuthoringOpen = signal(false, ...(ngDevMode ? [{ debugName: "agenticAuthoringOpen" }] : []));
15093
- agenticAuthoringPrompt = signal('', ...(ngDevMode ? [{ debugName: "agenticAuthoringPrompt" }] : []));
15094
- agenticAuthoringBusy = signal(false, ...(ngDevMode ? [{ debugName: "agenticAuthoringBusy" }] : []));
15095
- agenticAuthoringStatus = signal('', ...(ngDevMode ? [{ debugName: "agenticAuthoringStatus" }] : []));
15096
- agenticAuthoringError = signal('', ...(ngDevMode ? [{ debugName: "agenticAuthoringError" }] : []));
15097
- agenticAuthoringPreviewResult = signal(null, ...(ngDevMode ? [{ debugName: "agenticAuthoringPreviewResult" }] : []));
15098
- agenticAuthoringSemanticDecision = signal(null, ...(ngDevMode ? [{ debugName: "agenticAuthoringSemanticDecision" }] : []));
15099
- agenticAuthoringCanApply = signal(false, ...(ngDevMode ? [{ debugName: "agenticAuthoringCanApply" }] : []));
15100
- agenticAuthoringLastEtag = signal(null, ...(ngDevMode ? [{ debugName: "agenticAuthoringLastEtag" }] : []));
15101
- agenticAuthoringConversation = signal([], ...(ngDevMode ? [{ debugName: "agenticAuthoringConversation" }] : []));
15102
- agenticAuthoringQuickReplies = signal([], ...(ngDevMode ? [{ debugName: "agenticAuthoringQuickReplies" }] : []));
15103
- agenticAuthoringAttachments = signal([], ...(ngDevMode ? [{ debugName: "agenticAuthoringAttachments" }] : []));
15104
- agenticAuthoringSharedRuleHandoffState = signal(null, ...(ngDevMode ? [{ debugName: "agenticAuthoringSharedRuleHandoffState" }] : []));
15105
- sharedRuleCockpitBusyAction = signal(null, ...(ngDevMode ? [{ debugName: "sharedRuleCockpitBusyAction" }] : []));
15106
- sharedRuleCockpitError = signal('', ...(ngDevMode ? [{ debugName: "sharedRuleCockpitError" }] : []));
15107
- sharedRuleCockpitDefinition = signal(null, ...(ngDevMode ? [{ debugName: "sharedRuleCockpitDefinition" }] : []));
15108
- sharedRuleCockpitSimulation = signal(null, ...(ngDevMode ? [{ debugName: "sharedRuleCockpitSimulation" }] : []));
15109
- sharedRuleCockpitTimeline = signal(null, ...(ngDevMode ? [{ debugName: "sharedRuleCockpitTimeline" }] : []));
15110
- sharedRuleCockpitPublication = signal(null, ...(ngDevMode ? [{ debugName: "sharedRuleCockpitPublication" }] : []));
15111
- sharedRuleCockpitMaterializations = signal([], ...(ngDevMode ? [{ debugName: "sharedRuleCockpitMaterializations" }] : []));
15112
- sharedRuleCockpitEnforcement = signal(null, ...(ngDevMode ? [{ debugName: "sharedRuleCockpitEnforcement" }] : []));
15113
- projectKnowledgeCockpitBusyAction = signal(null, ...(ngDevMode ? [{ debugName: "projectKnowledgeCockpitBusyAction" }] : []));
15114
- projectKnowledgeCockpitError = signal('', ...(ngDevMode ? [{ debugName: "projectKnowledgeCockpitError" }] : []));
15115
- projectKnowledgeCockpitChangeSet = signal(null, ...(ngDevMode ? [{ debugName: "projectKnowledgeCockpitChangeSet" }] : []));
15116
- projectKnowledgeCockpitValidation = signal(null, ...(ngDevMode ? [{ debugName: "projectKnowledgeCockpitValidation" }] : []));
15117
- projectKnowledgeCockpitTimeline = signal(null, ...(ngDevMode ? [{ debugName: "projectKnowledgeCockpitTimeline" }] : []));
15118
- agenticAuthoringLlmDiagnostics = signal(null, ...(ngDevMode ? [{ debugName: "agenticAuthoringLlmDiagnostics" }] : []));
15119
- agenticAuthoringLlmDiagnosticsCollapsed = signal(true, ...(ngDevMode ? [{ debugName: "agenticAuthoringLlmDiagnosticsCollapsed" }] : []));
15120
- sharedRuleCockpitCollapsed = signal(false, ...(ngDevMode ? [{ debugName: "sharedRuleCockpitCollapsed" }] : []));
15121
- projectKnowledgeCockpitCollapsed = signal(true, ...(ngDevMode ? [{ debugName: "projectKnowledgeCockpitCollapsed" }] : []));
15122
- agenticAuthoringEditingMessageId = signal(null, ...(ngDevMode ? [{ debugName: "agenticAuthoringEditingMessageId" }] : []));
15123
- selectedWidgetKey = signal(null, ...(ngDevMode ? [{ debugName: "selectedWidgetKey" }] : []));
15124
- agenticAuthoringWidgetContextKey = signal(null, ...(ngDevMode ? [{ debugName: "agenticAuthoringWidgetContextKey" }] : []));
15232
+ currentPage = signal({ widgets: [] }, ...(ngDevMode ? [{ debugName: "currentPage" }] : /* istanbul ignore next */ []));
15233
+ hasPageWidgets = computed(() => (this.currentPage().widgets || []).length > 0, ...(ngDevMode ? [{ debugName: "hasPageWidgets" }] : /* istanbul ignore next */ []));
15234
+ connectionsViewerOpen = signal(false, ...(ngDevMode ? [{ debugName: "connectionsViewerOpen" }] : /* istanbul ignore next */ []));
15235
+ agenticAuthoringOpen = signal(false, ...(ngDevMode ? [{ debugName: "agenticAuthoringOpen" }] : /* istanbul ignore next */ []));
15236
+ agenticAuthoringPrompt = signal('', ...(ngDevMode ? [{ debugName: "agenticAuthoringPrompt" }] : /* istanbul ignore next */ []));
15237
+ agenticAuthoringBusy = signal(false, ...(ngDevMode ? [{ debugName: "agenticAuthoringBusy" }] : /* istanbul ignore next */ []));
15238
+ agenticAuthoringStatus = signal('', ...(ngDevMode ? [{ debugName: "agenticAuthoringStatus" }] : /* istanbul ignore next */ []));
15239
+ agenticAuthoringError = signal('', ...(ngDevMode ? [{ debugName: "agenticAuthoringError" }] : /* istanbul ignore next */ []));
15240
+ agenticAuthoringPreviewResult = signal(null, ...(ngDevMode ? [{ debugName: "agenticAuthoringPreviewResult" }] : /* istanbul ignore next */ []));
15241
+ agenticAuthoringSemanticDecision = signal(null, ...(ngDevMode ? [{ debugName: "agenticAuthoringSemanticDecision" }] : /* istanbul ignore next */ []));
15242
+ agenticAuthoringCanApply = signal(false, ...(ngDevMode ? [{ debugName: "agenticAuthoringCanApply" }] : /* istanbul ignore next */ []));
15243
+ agenticAuthoringLastEtag = signal(null, ...(ngDevMode ? [{ debugName: "agenticAuthoringLastEtag" }] : /* istanbul ignore next */ []));
15244
+ agenticAuthoringConversation = signal([], ...(ngDevMode ? [{ debugName: "agenticAuthoringConversation" }] : /* istanbul ignore next */ []));
15245
+ agenticAuthoringQuickReplies = signal([], ...(ngDevMode ? [{ debugName: "agenticAuthoringQuickReplies" }] : /* istanbul ignore next */ []));
15246
+ agenticAuthoringAttachments = signal([], ...(ngDevMode ? [{ debugName: "agenticAuthoringAttachments" }] : /* istanbul ignore next */ []));
15247
+ agenticAuthoringSharedRuleHandoffState = signal(null, ...(ngDevMode ? [{ debugName: "agenticAuthoringSharedRuleHandoffState" }] : /* istanbul ignore next */ []));
15248
+ sharedRuleCockpitBusyAction = signal(null, ...(ngDevMode ? [{ debugName: "sharedRuleCockpitBusyAction" }] : /* istanbul ignore next */ []));
15249
+ sharedRuleCockpitError = signal('', ...(ngDevMode ? [{ debugName: "sharedRuleCockpitError" }] : /* istanbul ignore next */ []));
15250
+ sharedRuleCockpitDefinition = signal(null, ...(ngDevMode ? [{ debugName: "sharedRuleCockpitDefinition" }] : /* istanbul ignore next */ []));
15251
+ sharedRuleCockpitSimulation = signal(null, ...(ngDevMode ? [{ debugName: "sharedRuleCockpitSimulation" }] : /* istanbul ignore next */ []));
15252
+ sharedRuleCockpitTimeline = signal(null, ...(ngDevMode ? [{ debugName: "sharedRuleCockpitTimeline" }] : /* istanbul ignore next */ []));
15253
+ sharedRuleCockpitPublication = signal(null, ...(ngDevMode ? [{ debugName: "sharedRuleCockpitPublication" }] : /* istanbul ignore next */ []));
15254
+ sharedRuleCockpitMaterializations = signal([], ...(ngDevMode ? [{ debugName: "sharedRuleCockpitMaterializations" }] : /* istanbul ignore next */ []));
15255
+ sharedRuleCockpitEnforcement = signal(null, ...(ngDevMode ? [{ debugName: "sharedRuleCockpitEnforcement" }] : /* istanbul ignore next */ []));
15256
+ projectKnowledgeCockpitBusyAction = signal(null, ...(ngDevMode ? [{ debugName: "projectKnowledgeCockpitBusyAction" }] : /* istanbul ignore next */ []));
15257
+ projectKnowledgeCockpitError = signal('', ...(ngDevMode ? [{ debugName: "projectKnowledgeCockpitError" }] : /* istanbul ignore next */ []));
15258
+ projectKnowledgeCockpitChangeSet = signal(null, ...(ngDevMode ? [{ debugName: "projectKnowledgeCockpitChangeSet" }] : /* istanbul ignore next */ []));
15259
+ projectKnowledgeCockpitValidation = signal(null, ...(ngDevMode ? [{ debugName: "projectKnowledgeCockpitValidation" }] : /* istanbul ignore next */ []));
15260
+ projectKnowledgeCockpitTimeline = signal(null, ...(ngDevMode ? [{ debugName: "projectKnowledgeCockpitTimeline" }] : /* istanbul ignore next */ []));
15261
+ agenticAuthoringLlmDiagnostics = signal(null, ...(ngDevMode ? [{ debugName: "agenticAuthoringLlmDiagnostics" }] : /* istanbul ignore next */ []));
15262
+ agenticAuthoringLlmDiagnosticsCollapsed = signal(true, ...(ngDevMode ? [{ debugName: "agenticAuthoringLlmDiagnosticsCollapsed" }] : /* istanbul ignore next */ []));
15263
+ sharedRuleCockpitCollapsed = signal(false, ...(ngDevMode ? [{ debugName: "sharedRuleCockpitCollapsed" }] : /* istanbul ignore next */ []));
15264
+ projectKnowledgeCockpitCollapsed = signal(true, ...(ngDevMode ? [{ debugName: "projectKnowledgeCockpitCollapsed" }] : /* istanbul ignore next */ []));
15265
+ agenticAuthoringEditingMessageId = signal(null, ...(ngDevMode ? [{ debugName: "agenticAuthoringEditingMessageId" }] : /* istanbul ignore next */ []));
15266
+ selectedWidgetKey = signal(null, ...(ngDevMode ? [{ debugName: "selectedWidgetKey" }] : /* istanbul ignore next */ []));
15267
+ agenticAuthoringWidgetContextKey = signal(null, ...(ngDevMode ? [{ debugName: "agenticAuthoringWidgetContextKey" }] : /* istanbul ignore next */ []));
15125
15268
  agenticAuthoringPanelLayout = signal(createPraxisAssistantViewportLayout({
15126
15269
  width: 440,
15127
15270
  height: 620,
15128
15271
  top: 96,
15129
15272
  margin: 24,
15130
- }), ...(ngDevMode ? [{ debugName: "agenticAuthoringPanelLayout" }] : []));
15273
+ }), ...(ngDevMode ? [{ debugName: "agenticAuthoringPanelLayout" }] : /* istanbul ignore next */ []));
15131
15274
  previewMode = false;
15132
15275
  agenticComponentCapabilities;
15133
15276
  agenticComponentCapabilitiesPromise;
@@ -17670,15 +17813,15 @@ class DynamicPageBuilderComponent {
17670
17813
  tx(key, fallback) {
17671
17814
  return resolvePraxisPageBuilderText(this.i18n, key, fallback);
17672
17815
  }
17673
- static ɵfac = i0.ɵɵngDeclareFactory({ minVersion: "12.0.0", version: "20.3.17", ngImport: i0, type: DynamicPageBuilderComponent, deps: [{ token: i1.MatDialog }, { token: SETTINGS_PANEL_BRIDGE, optional: true }], target: i0.ɵɵFactoryTarget.Component });
17674
- static ɵcmp = i0.ɵɵngDeclareComponent({ minVersion: "14.0.0", version: "20.3.17", type: DynamicPageBuilderComponent, isStandalone: true, selector: "praxis-dynamic-page-builder", inputs: { page: "page", context: "context", strictValidation: "strictValidation", autoPersist: "autoPersist", enableCustomization: "enableCustomization", showSettingsButton: "showSettingsButton", pageIdentity: "pageIdentity", componentInstanceId: "componentInstanceId", pageEditorComponent: "pageEditorComponent", enableAgenticAuthoring: "enableAgenticAuthoring", agenticAuthoringProvider: "agenticAuthoringProvider", agenticAuthoringModel: "agenticAuthoringModel", agenticAuthoringApiKey: "agenticAuthoringApiKey", agenticAuthoringComponentId: "agenticAuthoringComponentId", agenticAuthoringScope: "agenticAuthoringScope", agenticAuthoringEtag: "agenticAuthoringEtag", agenticAuthoringIncludeLlmDiagnostics: "agenticAuthoringIncludeLlmDiagnostics", agenticAuthoringEnableStreaming: "agenticAuthoringEnableStreaming", agenticAuthoringContextHints: "agenticAuthoringContextHints", showPageLifecycleActions: "showPageLifecycleActions", canDeleteSavedPage: "canDeleteSavedPage", pageLifecycleBusy: "pageLifecycleBusy", pageLifecycleResetRevision: "pageLifecycleResetRevision" }, outputs: { pageChange: "pageChange", pageSaveRequested: "pageSaveRequested", agenticAuthoringApplied: "agenticAuthoringApplied", agenticAuthoringSharedRuleHandoff: "agenticAuthoringSharedRuleHandoff", pageRestart: "pageRestart", savedPageDeleteRequested: "savedPageDeleteRequested" }, providers: [
17816
+ static ɵfac = i0.ɵɵngDeclareFactory({ minVersion: "12.0.0", version: "21.2.14", ngImport: i0, type: DynamicPageBuilderComponent, deps: [{ token: i1.MatDialog }, { token: SETTINGS_PANEL_BRIDGE, optional: true }], target: i0.ɵɵFactoryTarget.Component });
17817
+ static ɵcmp = i0.ɵɵngDeclareComponent({ minVersion: "17.0.0", version: "21.2.14", type: DynamicPageBuilderComponent, isStandalone: true, selector: "praxis-dynamic-page-builder", inputs: { page: "page", context: "context", strictValidation: "strictValidation", autoPersist: "autoPersist", enableCustomization: "enableCustomization", showSettingsButton: "showSettingsButton", pageIdentity: "pageIdentity", componentInstanceId: "componentInstanceId", pageEditorComponent: "pageEditorComponent", enableAgenticAuthoring: "enableAgenticAuthoring", agenticAuthoringProvider: "agenticAuthoringProvider", agenticAuthoringModel: "agenticAuthoringModel", agenticAuthoringApiKey: "agenticAuthoringApiKey", agenticAuthoringComponentId: "agenticAuthoringComponentId", agenticAuthoringScope: "agenticAuthoringScope", agenticAuthoringEtag: "agenticAuthoringEtag", agenticAuthoringIncludeLlmDiagnostics: "agenticAuthoringIncludeLlmDiagnostics", agenticAuthoringEnableStreaming: "agenticAuthoringEnableStreaming", agenticAuthoringContextHints: "agenticAuthoringContextHints", showPageLifecycleActions: "showPageLifecycleActions", canDeleteSavedPage: "canDeleteSavedPage", pageLifecycleBusy: "pageLifecycleBusy", pageLifecycleResetRevision: "pageLifecycleResetRevision" }, outputs: { pageChange: "pageChange", pageSaveRequested: "pageSaveRequested", agenticAuthoringApplied: "agenticAuthoringApplied", agenticAuthoringSharedRuleHandoff: "agenticAuthoringSharedRuleHandoff", pageRestart: "pageRestart", savedPageDeleteRequested: "savedPageDeleteRequested" }, providers: [
17675
17818
  providePraxisPageBuilderI18n(),
17676
17819
  { provide: DYNAMIC_PAGE_SHELL_EDITOR, useValue: WidgetShellEditorComponent },
17677
17820
  ], viewQueries: [{ propertyName: "runtime", first: true, predicate: ["runtime"], descendants: true }], usesOnChanges: true, ngImport: i0, template: `
17678
17821
  <div
17679
17822
  class="builder-shell"
17680
17823
  [class.builder-shell--agentic-review-rail]="agenticAuthoringReviewRailActive()"
17681
- >
17824
+ >
17682
17825
  <praxis-dynamic-page
17683
17826
  #runtime
17684
17827
  [page]="currentPage()"
@@ -17695,325 +17838,338 @@ class DynamicPageBuilderComponent {
17695
17838
  (widgetEvent)="onRuntimeWidgetEvent($event)"
17696
17839
  (widgetSelectionChange)="onRuntimeWidgetSelectionChange($event)"
17697
17840
  (widgetAssistantRequested)="openAgenticAuthoringForWidget($event)"
17698
- />
17699
-
17841
+ />
17842
+
17700
17843
  <praxis-connection-editor
17701
17844
  [open]="showSettings() && connectionsViewerOpen()"
17702
17845
  [page]="currentPage()"
17703
17846
  (pageChange)="onConnectionEditorPageChange($event)"
17704
17847
  (focusWidget)="focusCanvasWidget($event)"
17705
17848
  (openPageSettings)="openPageSettings()"
17706
- />
17707
-
17708
- <praxis-ai-assistant-shell
17709
- *ngIf="showSettings() && enableAgenticAuthoring && agenticAuthoringOpen()"
17710
- panelTestId="page-builder-agentic-authoring-panel"
17711
- testIdPrefix="page-builder-agentic"
17712
- submitTestId="page-builder-agentic-preview"
17713
- applyTestId="page-builder-agentic-persist"
17714
- [labels]="agenticAuthoringShellLabels()"
17715
- mode="agentic-authoring"
17716
- [state]="agenticAuthoringShellState()"
17717
- [contextItems]="agenticAuthoringContextItems()"
17718
- [attachments]="agenticAuthoringAttachments()"
17719
- [messages]="agenticAuthoringConversation()"
17720
- [quickReplies]="agenticAuthoringQuickReplies()"
17721
- [prompt]="agenticAuthoringPrompt()"
17722
- [statusText]="agenticAuthoringStatus()"
17723
- [errorText]="agenticAuthoringError()"
17724
- [busy]="agenticAuthoringBusy()"
17725
- [canApply]="agenticAuthoringCanApply()"
17726
- [primaryAction]="agenticAuthoringSubmitAction()"
17727
- [showAttachAction]="false"
17728
- [enablePastedAttachments]="false"
17729
- [layout]="agenticAuthoringPanelLayout()"
17730
- [minWidth]="320"
17731
- [minHeight]="280"
17732
- [margin]="8"
17733
- (promptChange)="agenticAuthoringPrompt.set($event)"
17734
- (submitPrompt)="agenticAuthoringPrompt.set($event); previewAgenticAuthoring()"
17735
- (apply)="persistAgenticAuthoring()"
17736
- (retryTurn)="retryAgenticAuthoring()"
17737
- (cancelTurn)="cancelAgenticAuthoring()"
17738
- (quickReply)="submitAgenticQuickReply($event)"
17739
- (attach)="attachAgenticContext()"
17740
- (removeAttachment)="removeAgenticAttachment($event)"
17741
- (editMessage)="editAgenticMessage($event)"
17742
- (resendMessage)="resendAgenticMessage($event)"
17743
- (layoutChange)="onAgenticAuthoringLayoutChange($event)"
17744
- (close)="minimizeAgenticAuthoring()"
17745
- />
17746
-
17747
- <section
17748
- *ngIf="agenticAuthoringIncludeLlmDiagnostics && agenticAuthoringLlmDiagnosticsText()"
17749
- class="agentic-diagnostics-panel"
17750
- [class.agentic-diagnostics-panel--collapsed]="agenticAuthoringLlmDiagnosticsCollapsed()"
17751
- data-testid="page-builder-agentic-llm-diagnostics"
17752
- role="region"
17753
- [attr.aria-label]="tx('agentic.diagnostics.title', 'LLM diagnostics')"
17754
- [style.top.px]="agenticAuthoringDiagnosticsTop()"
17755
- >
17756
- <header class="agentic-diagnostics-panel__header">
17757
- <span>{{ tx('agentic.diagnostics.title', 'LLM diagnostics') }}</span>
17758
- <div class="agentic-diagnostics-panel__header-actions">
17759
- <span class="agentic-diagnostics-panel__badge">
17760
- {{ tx('agentic.diagnostics.badge', 'Debug') }}
17761
- </span>
17762
- <button
17763
- class="agentic-diagnostics-panel__toggle"
17764
- data-testid="page-builder-agentic-llm-diagnostics-toggle"
17765
- type="button"
17766
- [attr.aria-expanded]="!agenticAuthoringLlmDiagnosticsCollapsed()"
17767
- (click)="toggleAgenticAuthoringLlmDiagnostics()"
17768
- >
17769
- {{ agenticAuthoringLlmDiagnosticsCollapsed()
17849
+ />
17850
+
17851
+ @if (showSettings() && enableAgenticAuthoring && agenticAuthoringOpen()) {
17852
+ <praxis-ai-assistant-shell
17853
+ panelTestId="page-builder-agentic-authoring-panel"
17854
+ testIdPrefix="page-builder-agentic"
17855
+ submitTestId="page-builder-agentic-preview"
17856
+ applyTestId="page-builder-agentic-persist"
17857
+ [labels]="agenticAuthoringShellLabels()"
17858
+ mode="agentic-authoring"
17859
+ [state]="agenticAuthoringShellState()"
17860
+ [contextItems]="agenticAuthoringContextItems()"
17861
+ [attachments]="agenticAuthoringAttachments()"
17862
+ [messages]="agenticAuthoringConversation()"
17863
+ [quickReplies]="agenticAuthoringQuickReplies()"
17864
+ [prompt]="agenticAuthoringPrompt()"
17865
+ [statusText]="agenticAuthoringStatus()"
17866
+ [errorText]="agenticAuthoringError()"
17867
+ [busy]="agenticAuthoringBusy()"
17868
+ [canApply]="agenticAuthoringCanApply()"
17869
+ [primaryAction]="agenticAuthoringSubmitAction()"
17870
+ [showAttachAction]="false"
17871
+ [enablePastedAttachments]="false"
17872
+ [layout]="agenticAuthoringPanelLayout()"
17873
+ [minWidth]="320"
17874
+ [minHeight]="280"
17875
+ [margin]="8"
17876
+ (promptChange)="agenticAuthoringPrompt.set($event)"
17877
+ (submitPrompt)="agenticAuthoringPrompt.set($event); previewAgenticAuthoring()"
17878
+ (apply)="persistAgenticAuthoring()"
17879
+ (retryTurn)="retryAgenticAuthoring()"
17880
+ (cancelTurn)="cancelAgenticAuthoring()"
17881
+ (quickReply)="submitAgenticQuickReply($event)"
17882
+ (attach)="attachAgenticContext()"
17883
+ (removeAttachment)="removeAgenticAttachment($event)"
17884
+ (editMessage)="editAgenticMessage($event)"
17885
+ (resendMessage)="resendAgenticMessage($event)"
17886
+ (layoutChange)="onAgenticAuthoringLayoutChange($event)"
17887
+ (close)="minimizeAgenticAuthoring()"
17888
+ />
17889
+ }
17890
+
17891
+ @if (agenticAuthoringIncludeLlmDiagnostics && agenticAuthoringLlmDiagnosticsText()) {
17892
+ <section
17893
+ class="agentic-diagnostics-panel"
17894
+ [class.agentic-diagnostics-panel--collapsed]="agenticAuthoringLlmDiagnosticsCollapsed()"
17895
+ data-testid="page-builder-agentic-llm-diagnostics"
17896
+ role="region"
17897
+ [attr.aria-label]="tx('agentic.diagnostics.title', 'LLM diagnostics')"
17898
+ [style.top.px]="agenticAuthoringDiagnosticsTop()"
17899
+ >
17900
+ <header class="agentic-diagnostics-panel__header">
17901
+ <span>{{ tx('agentic.diagnostics.title', 'LLM diagnostics') }}</span>
17902
+ <div class="agentic-diagnostics-panel__header-actions">
17903
+ <span class="agentic-diagnostics-panel__badge">
17904
+ {{ tx('agentic.diagnostics.badge', 'Debug') }}
17905
+ </span>
17906
+ <button
17907
+ class="agentic-diagnostics-panel__toggle"
17908
+ data-testid="page-builder-agentic-llm-diagnostics-toggle"
17909
+ type="button"
17910
+ [attr.aria-expanded]="!agenticAuthoringLlmDiagnosticsCollapsed()"
17911
+ (click)="toggleAgenticAuthoringLlmDiagnostics()"
17912
+ >
17913
+ {{ agenticAuthoringLlmDiagnosticsCollapsed()
17770
17914
  ? tx('agentic.diagnostics.expand', 'Expand')
17771
17915
  : tx('agentic.diagnostics.collapse', 'Collapse') }}
17772
- </button>
17773
- </div>
17774
- </header>
17775
- <ng-container *ngIf="!agenticAuthoringLlmDiagnosticsCollapsed()">
17776
- <p class="agentic-diagnostics-panel__description">
17777
- {{ tx('agentic.diagnostics.description', 'Prompt, context bundle, and tool catalog returned by the backend for this turn.') }}
17778
- </p>
17779
- <pre>{{ agenticAuthoringLlmDiagnosticsText() }}</pre>
17780
- </ng-container>
17781
- </section>
17782
-
17783
- <section
17784
- *ngIf="agenticAuthoringSharedRuleHandoffState() as handoff"
17785
- class="shared-rule-cockpit"
17786
- [class.shared-rule-cockpit--collapsed]="sharedRuleCockpitCollapsed()"
17787
- data-testid="page-builder-shared-rule-cockpit"
17788
- role="region"
17789
- [attr.aria-label]="tx('agentic.sharedRuleCockpit.title', 'Shared-rule governed actions')"
17790
- >
17791
- <header class="shared-rule-cockpit__header">
17792
- <div>
17793
- <strong>{{ tx('agentic.sharedRuleCockpit.title', 'Shared-rule governed actions') }}</strong>
17794
- <span>{{ handoff.ruleKey || handoff.recommendedRuleType || handoff.flowId }}</span>
17795
- </div>
17796
- <div class="shared-rule-cockpit__header-actions">
17797
- <span class="shared-rule-cockpit__badge">{{ handoff.routeGateStatus || handoff.previewDisposition }}</span>
17798
- <button
17799
- class="shared-rule-cockpit__toggle"
17800
- data-testid="shared-rule-cockpit-toggle"
17801
- type="button"
17802
- [attr.aria-expanded]="!sharedRuleCockpitCollapsed()"
17803
- (click)="toggleSharedRuleCockpit()"
17804
- >
17805
- {{ sharedRuleCockpitCollapsed()
17916
+ </button>
17917
+ </div>
17918
+ </header>
17919
+ @if (!agenticAuthoringLlmDiagnosticsCollapsed()) {
17920
+ <p class="agentic-diagnostics-panel__description">
17921
+ {{ tx('agentic.diagnostics.description', 'Prompt, context bundle, and tool catalog returned by the backend for this turn.') }}
17922
+ </p>
17923
+ <pre>{{ agenticAuthoringLlmDiagnosticsText() }}</pre>
17924
+ }
17925
+ </section>
17926
+ }
17927
+
17928
+ @if (agenticAuthoringSharedRuleHandoffState(); as handoff) {
17929
+ <section
17930
+ class="shared-rule-cockpit"
17931
+ [class.shared-rule-cockpit--collapsed]="sharedRuleCockpitCollapsed()"
17932
+ data-testid="page-builder-shared-rule-cockpit"
17933
+ role="region"
17934
+ [attr.aria-label]="tx('agentic.sharedRuleCockpit.title', 'Shared-rule governed actions')"
17935
+ >
17936
+ <header class="shared-rule-cockpit__header">
17937
+ <div>
17938
+ <strong>{{ tx('agentic.sharedRuleCockpit.title', 'Shared-rule governed actions') }}</strong>
17939
+ <span>{{ handoff.ruleKey || handoff.recommendedRuleType || handoff.flowId }}</span>
17940
+ </div>
17941
+ <div class="shared-rule-cockpit__header-actions">
17942
+ <span class="shared-rule-cockpit__badge">{{ handoff.routeGateStatus || handoff.previewDisposition }}</span>
17943
+ <button
17944
+ class="shared-rule-cockpit__toggle"
17945
+ data-testid="shared-rule-cockpit-toggle"
17946
+ type="button"
17947
+ [attr.aria-expanded]="!sharedRuleCockpitCollapsed()"
17948
+ (click)="toggleSharedRuleCockpit()"
17949
+ >
17950
+ {{ sharedRuleCockpitCollapsed()
17806
17951
  ? tx('agentic.sharedRuleCockpit.expand', 'Expand')
17807
17952
  : tx('agentic.sharedRuleCockpit.collapse', 'Collapse') }}
17808
- </button>
17809
- </div>
17810
- </header>
17811
-
17812
- <ng-container *ngIf="!sharedRuleCockpitCollapsed()">
17813
- <p class="shared-rule-cockpit__description">
17814
- {{ tx('agentic.sharedRuleCockpit.description', 'Continue the semantic decision in the governed domain-rules lifecycle. The cockpit calls canonical backend actions and only displays derived materializations.') }}
17815
- </p>
17816
-
17817
- <div class="shared-rule-cockpit__actions">
17818
- <button
17819
- *ngFor="let action of sharedRuleGovernedContinuationActions(); trackBy: trackGovernedContinuationAction"
17820
- mat-stroked-button
17821
- type="button"
17822
- [attr.data-testid]="governedContinuationActionTestId(action)"
17823
- [attr.data-action-kind]="action.kind"
17824
- [disabled]="!action.enabled"
17825
- [matTooltip]="governedContinuationActionTooltip(action)"
17826
- (click)="runSharedRuleGovernedContinuationAction(action)"
17827
- >
17828
- {{ tx(action.labelKey, action.labelFallback) }}
17829
- </button>
17830
- </div>
17831
-
17832
- <p *ngIf="sharedRuleCockpitBusyAction() as action" class="shared-rule-cockpit__status" data-testid="shared-rule-cockpit-busy">
17833
- {{ tx('agentic.sharedRuleCockpit.running', 'Running governed action') }}: {{ action }}
17834
- </p>
17835
- <p *ngIf="sharedRuleCockpitError()" class="shared-rule-cockpit__error" data-testid="shared-rule-cockpit-error">
17836
- {{ sharedRuleCockpitError() }}
17837
- </p>
17838
-
17839
- <dl class="shared-rule-cockpit__facts">
17840
- <div>
17841
- <dt>{{ tx('agentic.sharedRuleCockpit.definitionId', 'Definition') }}</dt>
17842
- <dd data-testid="shared-rule-cockpit-definition-id">{{ handoff.ruleDefinitionId || tx('agentic.sharedRuleCockpit.pending', 'pending') }}</dd>
17843
- </div>
17844
- <div>
17845
- <dt>{{ tx('agentic.sharedRuleCockpit.simulation', 'Simulation') }}</dt>
17846
- <dd data-testid="shared-rule-cockpit-simulation-result">{{ sharedRuleCockpitSimulation()?.result || tx('agentic.sharedRuleCockpit.pending', 'pending') }}</dd>
17847
- </div>
17848
- <div>
17849
- <dt>{{ tx('agentic.sharedRuleCockpit.publication', 'Publication') }}</dt>
17850
- <dd data-testid="shared-rule-cockpit-publication-status">{{ sharedRuleCockpitPublication()?.publicationStatus || tx('agentic.sharedRuleCockpit.pending', 'pending') }}</dd>
17851
- </div>
17852
- <div>
17853
- <dt>{{ tx('agentic.sharedRuleCockpit.materializations', 'Materializations') }}</dt>
17854
- <dd data-testid="shared-rule-cockpit-materialization-count">{{ sharedRuleCockpitMaterializations().length }}</dd>
17855
- </div>
17856
- <div>
17857
- <dt>{{ tx('agentic.sharedRuleCockpit.timeline', 'Governed timeline') }}</dt>
17858
- <dd data-testid="shared-rule-cockpit-timeline-count">{{ sharedRuleCockpitTimeline()?.events?.length || 0 }}</dd>
17859
- </div>
17860
- <div>
17861
- <dt>{{ tx('agentic.sharedRuleCockpit.enforcementState', 'Runtime enforcement') }}</dt>
17862
- <dd data-testid="shared-rule-cockpit-enforcement-status">{{ sharedRuleCockpitEnforcement()?.status || tx('agentic.sharedRuleCockpit.pending', 'pending') }}</dd>
17863
- </div>
17864
- </dl>
17865
-
17866
- <section
17867
- *ngIf="sharedRuleCockpitEnforcement() as enforcement"
17868
- class="shared-rule-cockpit__enforcement-matrix"
17869
- data-testid="shared-rule-cockpit-enforcement-matrix"
17870
- [attr.aria-label]="tx('agentic.sharedRuleCockpit.enforcementMatrix', 'Runtime enforcement matrix')"
17953
+ </button>
17954
+ </div>
17955
+ </header>
17956
+ @if (!sharedRuleCockpitCollapsed()) {
17957
+ <p class="shared-rule-cockpit__description">
17958
+ {{ tx('agentic.sharedRuleCockpit.description', 'Continue the semantic decision in the governed domain-rules lifecycle. The cockpit calls canonical backend actions and only displays derived materializations.') }}
17959
+ </p>
17960
+ <div class="shared-rule-cockpit__actions">
17961
+ @for (action of sharedRuleGovernedContinuationActions(); track trackGovernedContinuationAction($index, action)) {
17962
+ <button
17963
+ mat-stroked-button
17964
+ type="button"
17965
+ [attr.data-testid]="governedContinuationActionTestId(action)"
17966
+ [attr.data-action-kind]="action.kind"
17967
+ [disabled]="!action.enabled"
17968
+ [matTooltip]="governedContinuationActionTooltip(action)"
17969
+ (click)="runSharedRuleGovernedContinuationAction(action)"
17970
+ >
17971
+ {{ tx(action.labelKey, action.labelFallback) }}
17972
+ </button>
17973
+ }
17974
+ </div>
17975
+ @if (sharedRuleCockpitBusyAction(); as action) {
17976
+ <p class="shared-rule-cockpit__status" data-testid="shared-rule-cockpit-busy">
17977
+ {{ tx('agentic.sharedRuleCockpit.running', 'Running governed action') }}: {{ action }}
17978
+ </p>
17979
+ }
17980
+ @if (sharedRuleCockpitError()) {
17981
+ <p class="shared-rule-cockpit__error" data-testid="shared-rule-cockpit-error">
17982
+ {{ sharedRuleCockpitError() }}
17983
+ </p>
17984
+ }
17985
+ <dl class="shared-rule-cockpit__facts">
17986
+ <div>
17987
+ <dt>{{ tx('agentic.sharedRuleCockpit.definitionId', 'Definition') }}</dt>
17988
+ <dd data-testid="shared-rule-cockpit-definition-id">{{ handoff.ruleDefinitionId || tx('agentic.sharedRuleCockpit.pending', 'pending') }}</dd>
17989
+ </div>
17990
+ <div>
17991
+ <dt>{{ tx('agentic.sharedRuleCockpit.simulation', 'Simulation') }}</dt>
17992
+ <dd data-testid="shared-rule-cockpit-simulation-result">{{ sharedRuleCockpitSimulation()?.result || tx('agentic.sharedRuleCockpit.pending', 'pending') }}</dd>
17993
+ </div>
17994
+ <div>
17995
+ <dt>{{ tx('agentic.sharedRuleCockpit.publication', 'Publication') }}</dt>
17996
+ <dd data-testid="shared-rule-cockpit-publication-status">{{ sharedRuleCockpitPublication()?.publicationStatus || tx('agentic.sharedRuleCockpit.pending', 'pending') }}</dd>
17997
+ </div>
17998
+ <div>
17999
+ <dt>{{ tx('agentic.sharedRuleCockpit.materializations', 'Materializations') }}</dt>
18000
+ <dd data-testid="shared-rule-cockpit-materialization-count">{{ sharedRuleCockpitMaterializations().length }}</dd>
18001
+ </div>
18002
+ <div>
18003
+ <dt>{{ tx('agentic.sharedRuleCockpit.timeline', 'Governed timeline') }}</dt>
18004
+ <dd data-testid="shared-rule-cockpit-timeline-count">{{ sharedRuleCockpitTimeline()?.events?.length || 0 }}</dd>
18005
+ </div>
18006
+ <div>
18007
+ <dt>{{ tx('agentic.sharedRuleCockpit.enforcementState', 'Runtime enforcement') }}</dt>
18008
+ <dd data-testid="shared-rule-cockpit-enforcement-status">{{ sharedRuleCockpitEnforcement()?.status || tx('agentic.sharedRuleCockpit.pending', 'pending') }}</dd>
18009
+ </div>
18010
+ </dl>
18011
+ @if (sharedRuleCockpitEnforcement(); as enforcement) {
18012
+ <section
18013
+ class="shared-rule-cockpit__enforcement-matrix"
18014
+ data-testid="shared-rule-cockpit-enforcement-matrix"
18015
+ [attr.aria-label]="tx('agentic.sharedRuleCockpit.enforcementMatrix', 'Runtime enforcement matrix')"
18016
+ >
18017
+ <header class="shared-rule-cockpit__matrix-header">
18018
+ <div>
18019
+ <strong>{{ tx('agentic.sharedRuleCockpit.enforcementMatrix', 'Runtime enforcement matrix') }}</strong>
18020
+ <span>{{ tx('agentic.sharedRuleCockpit.enforcementMatrixDescription', 'Derived projections that the runtime can enforce after publication.') }}</span>
18021
+ </div>
18022
+ <span class="shared-rule-cockpit__matrix-badge" data-testid="shared-rule-cockpit-enforcement-counts">
18023
+ {{ enforcement.appliedCount }} {{ tx('agentic.sharedRuleCockpit.applied', 'applied') }} /
18024
+ {{ enforcement.pendingCount }} {{ tx('agentic.sharedRuleCockpit.waiting', 'waiting') }}
18025
+ </span>
18026
+ </header>
18027
+ <div class="shared-rule-cockpit__projection-grid">
18028
+ @for (projection of enforcement.projections; track trackSharedRuleEnforcementProjection($index, projection)) {
18029
+ <article
18030
+ class="shared-rule-cockpit__projection"
18031
+ [attr.data-status]="projection.status"
18032
+ data-testid="shared-rule-cockpit-enforcement-projection"
18033
+ >
18034
+ <span data-testid="shared-rule-cockpit-enforcement-layer">{{ projection.targetLayer }}</span>
18035
+ <strong>{{ projection.targetLayerLabel }}</strong>
18036
+ <small>{{ projection.targetArtifact || tx('agentic.sharedRuleCockpit.artifactPending', 'artifact pending') }}</small>
18037
+ <em>{{ projection.sourceHash || tx('agentic.sharedRuleCockpit.sourceHashPending', 'source hash pending') }}</em>
18038
+ </article>
18039
+ }
18040
+ </div>
18041
+ <p class="shared-rule-cockpit__matrix-source" data-testid="shared-rule-cockpit-enforcement-sourcehash">
18042
+ <strong>{{ tx('agentic.sharedRuleCockpit.sourceHashes', 'Source hashes') }}:</strong>
18043
+ {{ enforcement.sourceHashes.length ? enforcement.sourceHashes.join(', ') : tx('agentic.sharedRuleCockpit.sourceHashPending', 'source hash pending') }}
18044
+ </p>
18045
+ </section>
18046
+ }
18047
+ }
18048
+ </section>
18049
+ }
18050
+
18051
+ @if (agenticAuthoringProjectKnowledgeAudit(); as audit) {
18052
+ <section
18053
+ class="project-knowledge-cockpit shared-rule-cockpit"
18054
+ [class.shared-rule-cockpit--collapsed]="projectKnowledgeCockpitCollapsed()"
18055
+ data-testid="page-builder-project-knowledge-cockpit"
18056
+ role="region"
18057
+ [attr.aria-label]="tx('agentic.projectKnowledgeCockpit.title', 'Project Knowledge governed actions')"
17871
18058
  >
17872
- <header class="shared-rule-cockpit__matrix-header">
18059
+ <header class="shared-rule-cockpit__header">
17873
18060
  <div>
17874
- <strong>{{ tx('agentic.sharedRuleCockpit.enforcementMatrix', 'Runtime enforcement matrix') }}</strong>
17875
- <span>{{ tx('agentic.sharedRuleCockpit.enforcementMatrixDescription', 'Derived projections that the runtime can enforce after publication.') }}</span>
18061
+ <strong>{{ tx('agentic.projectKnowledgeCockpit.title', 'Project Knowledge governed actions') }}</strong>
18062
+ <span>{{ tx('agentic.projectKnowledgeCockpit.subtitle', 'Continue cited knowledge as a governed Domain Knowledge change-set.') }}</span>
17876
18063
  </div>
17877
- <span class="shared-rule-cockpit__matrix-badge" data-testid="shared-rule-cockpit-enforcement-counts">
17878
- {{ enforcement.appliedCount }} {{ tx('agentic.sharedRuleCockpit.applied', 'applied') }} /
17879
- {{ enforcement.pendingCount }} {{ tx('agentic.sharedRuleCockpit.waiting', 'waiting') }}
17880
- </span>
17881
- </header>
17882
-
17883
- <div class="shared-rule-cockpit__projection-grid">
17884
- <article
17885
- *ngFor="let projection of enforcement.projections; trackBy: trackSharedRuleEnforcementProjection"
17886
- class="shared-rule-cockpit__projection"
17887
- [attr.data-status]="projection.status"
17888
- data-testid="shared-rule-cockpit-enforcement-projection"
17889
- >
17890
- <span data-testid="shared-rule-cockpit-enforcement-layer">{{ projection.targetLayer }}</span>
17891
- <strong>{{ projection.targetLayerLabel }}</strong>
17892
- <small>{{ projection.targetArtifact || tx('agentic.sharedRuleCockpit.artifactPending', 'artifact pending') }}</small>
17893
- <em>{{ projection.sourceHash || tx('agentic.sharedRuleCockpit.sourceHashPending', 'source hash pending') }}</em>
17894
- </article>
17895
- </div>
17896
-
17897
- <p class="shared-rule-cockpit__matrix-source" data-testid="shared-rule-cockpit-enforcement-sourcehash">
17898
- <strong>{{ tx('agentic.sharedRuleCockpit.sourceHashes', 'Source hashes') }}:</strong>
17899
- {{ enforcement.sourceHashes.length ? enforcement.sourceHashes.join(', ') : tx('agentic.sharedRuleCockpit.sourceHashPending', 'source hash pending') }}
17900
- </p>
17901
- </section>
17902
- </ng-container>
17903
- </section>
17904
-
17905
- <section
17906
- *ngIf="agenticAuthoringProjectKnowledgeAudit() as audit"
17907
- class="project-knowledge-cockpit shared-rule-cockpit"
17908
- [class.shared-rule-cockpit--collapsed]="projectKnowledgeCockpitCollapsed()"
17909
- data-testid="page-builder-project-knowledge-cockpit"
17910
- role="region"
17911
- [attr.aria-label]="tx('agentic.projectKnowledgeCockpit.title', 'Project Knowledge governed actions')"
17912
- >
17913
- <header class="shared-rule-cockpit__header">
17914
- <div>
17915
- <strong>{{ tx('agentic.projectKnowledgeCockpit.title', 'Project Knowledge governed actions') }}</strong>
17916
- <span>{{ tx('agentic.projectKnowledgeCockpit.subtitle', 'Continue cited knowledge as a governed Domain Knowledge change-set.') }}</span>
17917
- </div>
17918
- <div class="shared-rule-cockpit__header-actions">
17919
- <span class="shared-rule-cockpit__badge">{{ audit.citationPolicy || audit.source || 'governed' }}</span>
17920
- <button
17921
- class="shared-rule-cockpit__toggle"
17922
- data-testid="project-knowledge-cockpit-toggle"
17923
- type="button"
17924
- [attr.aria-expanded]="!projectKnowledgeCockpitCollapsed()"
17925
- (click)="toggleProjectKnowledgeCockpit()"
17926
- >
17927
- {{ projectKnowledgeCockpitCollapsed()
18064
+ <div class="shared-rule-cockpit__header-actions">
18065
+ <span class="shared-rule-cockpit__badge">{{ audit.citationPolicy || audit.source || 'governed' }}</span>
18066
+ <button
18067
+ class="shared-rule-cockpit__toggle"
18068
+ data-testid="project-knowledge-cockpit-toggle"
18069
+ type="button"
18070
+ [attr.aria-expanded]="!projectKnowledgeCockpitCollapsed()"
18071
+ (click)="toggleProjectKnowledgeCockpit()"
18072
+ >
18073
+ {{ projectKnowledgeCockpitCollapsed()
17928
18074
  ? tx('agentic.projectKnowledgeCockpit.expand', 'Expand')
17929
18075
  : tx('agentic.projectKnowledgeCockpit.collapse', 'Collapse') }}
17930
- </button>
17931
- </div>
17932
- </header>
17933
-
17934
- <ng-container *ngIf="!projectKnowledgeCockpitCollapsed()">
17935
- <p class="shared-rule-cockpit__description">
17936
- {{ tx('agentic.projectKnowledgeCockpit.description', 'The cockpit proposes reviewed evidence through canonical Domain Knowledge change-set endpoints. It displays only safe status summaries and does not materialize knowledge locally.') }}
17937
- </p>
17938
-
17939
- <div class="shared-rule-cockpit__actions">
17940
- <button
17941
- *ngFor="let action of projectKnowledgeGovernedContinuationActions(); trackBy: trackGovernedContinuationAction"
17942
- mat-stroked-button
17943
- type="button"
17944
- [attr.data-testid]="governedContinuationActionTestId(action)"
17945
- [attr.data-action-kind]="action.kind"
17946
- [disabled]="!action.enabled"
17947
- [matTooltip]="governedContinuationActionTooltip(action)"
17948
- (click)="runProjectKnowledgeGovernedContinuationAction(action)"
17949
- >
17950
- {{ tx(action.labelKey, action.labelFallback) }}
17951
- </button>
17952
- </div>
17953
-
17954
- <p *ngIf="projectKnowledgeCockpitBusyAction() as action" class="shared-rule-cockpit__status" data-testid="project-knowledge-cockpit-busy">
17955
- {{ tx('agentic.projectKnowledgeCockpit.running', 'Running governed Project Knowledge action') }}: {{ action }}
17956
- </p>
17957
- <p *ngIf="projectKnowledgeCockpitError()" class="shared-rule-cockpit__error" data-testid="project-knowledge-cockpit-error">
17958
- {{ projectKnowledgeCockpitError() }}
17959
- </p>
17960
-
17961
- <dl class="shared-rule-cockpit__facts">
17962
- <div>
17963
- <dt>{{ tx('agentic.projectKnowledgeCockpit.audit', 'Audit') }}</dt>
17964
- <dd data-testid="project-knowledge-cockpit-audit-status">
17965
- {{ audit.citedCount || 0 }}/{{ audit.influenceCount || 0 }} {{ tx('agentic.projectKnowledgeCockpit.cited', 'cited') }}
17966
- </dd>
17967
- </div>
17968
- <div>
17969
- <dt>{{ tx('agentic.projectKnowledgeCockpit.changeSet', 'Change-set') }}</dt>
17970
- <dd data-testid="project-knowledge-cockpit-change-set-id">{{ projectKnowledgeCockpitChangeSet()?.id || tx('agentic.sharedRuleCockpit.pending', 'pending') }}</dd>
17971
- </div>
17972
- <div>
17973
- <dt>{{ tx('agentic.projectKnowledgeCockpit.validation', 'Validation') }}</dt>
17974
- <dd data-testid="project-knowledge-cockpit-validation-status">{{ projectKnowledgeCockpitValidation()?.validationStatus || projectKnowledgeCockpitChangeSet()?.validationStatus || tx('agentic.sharedRuleCockpit.pending', 'pending') }}</dd>
17975
- </div>
17976
- <div>
17977
- <dt>{{ tx('agentic.projectKnowledgeCockpit.status', 'Status') }}</dt>
17978
- <dd data-testid="project-knowledge-cockpit-change-set-status">{{ projectKnowledgeCockpitChangeSet()?.status || tx('agentic.sharedRuleCockpit.pending', 'pending') }}</dd>
17979
- </div>
17980
- <div>
17981
- <dt>{{ tx('agentic.projectKnowledgeCockpit.safeOperations', 'Safe operations') }}</dt>
17982
- <dd data-testid="project-knowledge-cockpit-safe-operation-count">{{ projectKnowledgeCockpitChangeSet()?.safeOperationSummary?.length || 0 }}</dd>
17983
- </div>
17984
- <div>
17985
- <dt>{{ tx('agentic.projectKnowledgeCockpit.timeline', 'Safe timeline') }}</dt>
17986
- <dd data-testid="project-knowledge-cockpit-timeline-count">{{ projectKnowledgeCockpitTimeline()?.events?.length || 0 }}</dd>
17987
- </div>
17988
- </dl>
17989
-
17990
- <ol
17991
- *ngIf="projectKnowledgeTimelineItems().length; else projectKnowledgeTimelineEmpty"
17992
- class="shared-rule-cockpit__timeline"
17993
- data-testid="project-knowledge-cockpit-timeline-body"
17994
- >
17995
- <li
17996
- *ngFor="let item of projectKnowledgeTimelineItems(); trackBy: trackProjectKnowledgeTimelineItem"
17997
- class="shared-rule-cockpit__timeline-item"
17998
- >
17999
- <span class="shared-rule-cockpit__timeline-icon" aria-hidden="true">{{ item.icon || 'timeline' }}</span>
18000
- <div>
18001
- <strong>{{ item.title }}</strong>
18002
- <span *ngIf="item.badge" class="shared-rule-cockpit__timeline-badge">{{ item.badge }}</span>
18003
- <p *ngIf="item.subtitle">{{ item.subtitle }}</p>
18004
- <small *ngIf="item.meta">{{ item.meta }}</small>
18005
- <time *ngIf="item.opposite">{{ item.opposite }}</time>
18076
+ </button>
18006
18077
  </div>
18007
- </li>
18008
- </ol>
18009
- <ng-template #projectKnowledgeTimelineEmpty>
18010
- <p class="shared-rule-cockpit__timeline-empty" data-testid="project-knowledge-cockpit-timeline-empty">
18011
- {{ tx('agentic.projectKnowledgeCockpit.timelineEmpty', 'No safe timeline events published for this change-set yet.') }}
18078
+ </header>
18079
+ @if (!projectKnowledgeCockpitCollapsed()) {
18080
+ <p class="shared-rule-cockpit__description">
18081
+ {{ tx('agentic.projectKnowledgeCockpit.description', 'The cockpit proposes reviewed evidence through canonical Domain Knowledge change-set endpoints. It displays only safe status summaries and does not materialize knowledge locally.') }}
18012
18082
  </p>
18013
- </ng-template>
18014
- </ng-container>
18015
- </section>
18016
-
18083
+ <div class="shared-rule-cockpit__actions">
18084
+ @for (action of projectKnowledgeGovernedContinuationActions(); track trackGovernedContinuationAction($index, action)) {
18085
+ <button
18086
+ mat-stroked-button
18087
+ type="button"
18088
+ [attr.data-testid]="governedContinuationActionTestId(action)"
18089
+ [attr.data-action-kind]="action.kind"
18090
+ [disabled]="!action.enabled"
18091
+ [matTooltip]="governedContinuationActionTooltip(action)"
18092
+ (click)="runProjectKnowledgeGovernedContinuationAction(action)"
18093
+ >
18094
+ {{ tx(action.labelKey, action.labelFallback) }}
18095
+ </button>
18096
+ }
18097
+ </div>
18098
+ @if (projectKnowledgeCockpitBusyAction(); as action) {
18099
+ <p class="shared-rule-cockpit__status" data-testid="project-knowledge-cockpit-busy">
18100
+ {{ tx('agentic.projectKnowledgeCockpit.running', 'Running governed Project Knowledge action') }}: {{ action }}
18101
+ </p>
18102
+ }
18103
+ @if (projectKnowledgeCockpitError()) {
18104
+ <p class="shared-rule-cockpit__error" data-testid="project-knowledge-cockpit-error">
18105
+ {{ projectKnowledgeCockpitError() }}
18106
+ </p>
18107
+ }
18108
+ <dl class="shared-rule-cockpit__facts">
18109
+ <div>
18110
+ <dt>{{ tx('agentic.projectKnowledgeCockpit.audit', 'Audit') }}</dt>
18111
+ <dd data-testid="project-knowledge-cockpit-audit-status">
18112
+ {{ audit.citedCount || 0 }}/{{ audit.influenceCount || 0 }} {{ tx('agentic.projectKnowledgeCockpit.cited', 'cited') }}
18113
+ </dd>
18114
+ </div>
18115
+ <div>
18116
+ <dt>{{ tx('agentic.projectKnowledgeCockpit.changeSet', 'Change-set') }}</dt>
18117
+ <dd data-testid="project-knowledge-cockpit-change-set-id">{{ projectKnowledgeCockpitChangeSet()?.id || tx('agentic.sharedRuleCockpit.pending', 'pending') }}</dd>
18118
+ </div>
18119
+ <div>
18120
+ <dt>{{ tx('agentic.projectKnowledgeCockpit.validation', 'Validation') }}</dt>
18121
+ <dd data-testid="project-knowledge-cockpit-validation-status">{{ projectKnowledgeCockpitValidation()?.validationStatus || projectKnowledgeCockpitChangeSet()?.validationStatus || tx('agentic.sharedRuleCockpit.pending', 'pending') }}</dd>
18122
+ </div>
18123
+ <div>
18124
+ <dt>{{ tx('agentic.projectKnowledgeCockpit.status', 'Status') }}</dt>
18125
+ <dd data-testid="project-knowledge-cockpit-change-set-status">{{ projectKnowledgeCockpitChangeSet()?.status || tx('agentic.sharedRuleCockpit.pending', 'pending') }}</dd>
18126
+ </div>
18127
+ <div>
18128
+ <dt>{{ tx('agentic.projectKnowledgeCockpit.safeOperations', 'Safe operations') }}</dt>
18129
+ <dd data-testid="project-knowledge-cockpit-safe-operation-count">{{ projectKnowledgeCockpitChangeSet()?.safeOperationSummary?.length || 0 }}</dd>
18130
+ </div>
18131
+ <div>
18132
+ <dt>{{ tx('agentic.projectKnowledgeCockpit.timeline', 'Safe timeline') }}</dt>
18133
+ <dd data-testid="project-knowledge-cockpit-timeline-count">{{ projectKnowledgeCockpitTimeline()?.events?.length || 0 }}</dd>
18134
+ </div>
18135
+ </dl>
18136
+ @if (projectKnowledgeTimelineItems().length) {
18137
+ <ol
18138
+ class="shared-rule-cockpit__timeline"
18139
+ data-testid="project-knowledge-cockpit-timeline-body"
18140
+ >
18141
+ @for (item of projectKnowledgeTimelineItems(); track trackProjectKnowledgeTimelineItem($index, item)) {
18142
+ <li
18143
+ class="shared-rule-cockpit__timeline-item"
18144
+ >
18145
+ <span class="shared-rule-cockpit__timeline-icon" aria-hidden="true">{{ item.icon || 'timeline' }}</span>
18146
+ <div>
18147
+ <strong>{{ item.title }}</strong>
18148
+ @if (item.badge) {
18149
+ <span class="shared-rule-cockpit__timeline-badge">{{ item.badge }}</span>
18150
+ }
18151
+ @if (item.subtitle) {
18152
+ <p>{{ item.subtitle }}</p>
18153
+ }
18154
+ @if (item.meta) {
18155
+ <small>{{ item.meta }}</small>
18156
+ }
18157
+ @if (item.opposite) {
18158
+ <time>{{ item.opposite }}</time>
18159
+ }
18160
+ </div>
18161
+ </li>
18162
+ }
18163
+ </ol>
18164
+ } @else {
18165
+ <p class="shared-rule-cockpit__timeline-empty" data-testid="project-knowledge-cockpit-timeline-empty">
18166
+ {{ tx('agentic.projectKnowledgeCockpit.timelineEmpty', 'No safe timeline events published for this change-set yet.') }}
18167
+ </p>
18168
+ }
18169
+ }
18170
+ </section>
18171
+ }
18172
+
18017
18173
  <praxis-floating-toolbar
18018
18174
  [visible]="showSettings()"
18019
18175
  [canUndo]="false"
@@ -18024,69 +18180,72 @@ class DynamicPageBuilderComponent {
18024
18180
  (settings)="openPageSettings()"
18025
18181
  (save)="saveCurrentPage()"
18026
18182
  (preview)="togglePreview()"
18027
- >
18028
- <button
18029
- *ngIf="showPageLifecycleActions && hasPageWidgets()"
18030
- pdx-toolbar-extra
18031
- mat-mini-fab
18032
- type="button"
18033
- [attr.data-testid]="'page-builder-restart-page'"
18034
- [disabled]="pageLifecycleBusy"
18035
- [matTooltip]="tx('pageLifecycle.restart', 'Restart page')"
18036
- [attr.aria-label]="tx('pageLifecycle.restartAria', 'Restart current page locally')"
18037
- (click)="pageRestart.emit()"
18038
- >
18039
- <mat-icon [praxisIcon]="'restart_alt'"></mat-icon>
18040
- </button>
18041
- <button
18042
- *ngIf="showPageLifecycleActions && canDeleteSavedPage"
18043
- pdx-toolbar-extra
18044
- mat-mini-fab
18045
- color="warn"
18046
- type="button"
18047
- [attr.data-testid]="'page-builder-delete-saved-page'"
18048
- [disabled]="pageLifecycleBusy"
18049
- [matTooltip]="tx('pageLifecycle.deleteSaved', 'Delete saved page')"
18050
- [attr.aria-label]="tx('pageLifecycle.deleteSavedAria', 'Delete persisted page and restart')"
18051
- (click)="savedPageDeleteRequested.emit()"
18052
- >
18053
- <mat-icon [praxisIcon]="'delete'"></mat-icon>
18054
- </button>
18055
- <button
18056
- *ngIf="enableAgenticAuthoring"
18057
- pdx-toolbar-extra
18058
- mat-mini-fab
18059
- type="button"
18060
- class="builder-shell__agentic-toggle"
18061
- [class.builder-shell__agentic-toggle--open]="agenticAuthoringOpen()"
18062
- [class.builder-shell__agentic-toggle--minimized]="agenticAuthoringMinimized()"
18063
- [attr.data-testid]="'page-builder-agentic-toggle'"
18064
- [matTooltip]="agenticAuthoringToggleLabel()"
18065
- [attr.aria-label]="agenticAuthoringToggleLabel()"
18066
- (click)="toggleAgenticAuthoring()"
18067
- >
18068
- <mat-icon [praxisIcon]="'auto_awesome'"></mat-icon>
18069
- </button>
18070
- <button
18071
- *ngIf="hasPageWidgets()"
18072
- pdx-toolbar-extra
18073
- mat-mini-fab
18074
- type="button"
18075
- [attr.data-testid]="'page-builder-connections-toggle'"
18076
- [matTooltip]="tx('connections.toggle', 'Edit connections')"
18077
- [attr.aria-label]="tx('connections.toggleAria', 'Edit connections')"
18078
- (click)="toggleConnectionsViewer()"
18079
18183
  >
18080
- <mat-icon [praxisIcon]="'hub'"></mat-icon>
18081
- </button>
18184
+ @if (showPageLifecycleActions && hasPageWidgets()) {
18185
+ <button
18186
+ pdx-toolbar-extra
18187
+ mat-mini-fab
18188
+ type="button"
18189
+ [attr.data-testid]="'page-builder-restart-page'"
18190
+ [disabled]="pageLifecycleBusy"
18191
+ [matTooltip]="tx('pageLifecycle.restart', 'Restart page')"
18192
+ [attr.aria-label]="tx('pageLifecycle.restartAria', 'Restart current page locally')"
18193
+ (click)="pageRestart.emit()"
18194
+ >
18195
+ <mat-icon [praxisIcon]="'restart_alt'"></mat-icon>
18196
+ </button>
18197
+ }
18198
+ @if (showPageLifecycleActions && canDeleteSavedPage) {
18199
+ <button
18200
+ pdx-toolbar-extra
18201
+ mat-mini-fab
18202
+ color="warn"
18203
+ type="button"
18204
+ [attr.data-testid]="'page-builder-delete-saved-page'"
18205
+ [disabled]="pageLifecycleBusy"
18206
+ [matTooltip]="tx('pageLifecycle.deleteSaved', 'Delete saved page')"
18207
+ [attr.aria-label]="tx('pageLifecycle.deleteSavedAria', 'Delete persisted page and restart')"
18208
+ (click)="savedPageDeleteRequested.emit()"
18209
+ >
18210
+ <mat-icon [praxisIcon]="'delete'"></mat-icon>
18211
+ </button>
18212
+ }
18213
+ @if (enableAgenticAuthoring) {
18214
+ <button
18215
+ pdx-toolbar-extra
18216
+ mat-mini-fab
18217
+ type="button"
18218
+ class="builder-shell__agentic-toggle"
18219
+ [class.builder-shell__agentic-toggle--open]="agenticAuthoringOpen()"
18220
+ [class.builder-shell__agentic-toggle--minimized]="agenticAuthoringMinimized()"
18221
+ [attr.data-testid]="'page-builder-agentic-toggle'"
18222
+ [matTooltip]="agenticAuthoringToggleLabel()"
18223
+ [attr.aria-label]="agenticAuthoringToggleLabel()"
18224
+ (click)="toggleAgenticAuthoring()"
18225
+ >
18226
+ <mat-icon [praxisIcon]="'auto_awesome'"></mat-icon>
18227
+ </button>
18228
+ }
18229
+ @if (hasPageWidgets()) {
18230
+ <button
18231
+ pdx-toolbar-extra
18232
+ mat-mini-fab
18233
+ type="button"
18234
+ [attr.data-testid]="'page-builder-connections-toggle'"
18235
+ [matTooltip]="tx('connections.toggle', 'Edit connections')"
18236
+ [attr.aria-label]="tx('connections.toggleAria', 'Edit connections')"
18237
+ (click)="toggleConnectionsViewer()"
18238
+ >
18239
+ <mat-icon [praxisIcon]="'hub'"></mat-icon>
18240
+ </button>
18241
+ }
18082
18242
  </praxis-floating-toolbar>
18083
18243
  </div>
18084
- `, isInline: true, styles: [":host{display:block;position:relative;min-height:var(--pdx-page-builder-min-height, 420px)}.builder-shell{display:block;position:relative;min-height:inherit;height:100%}.builder-shell:has(.pdx-shell.fullscreen) praxis-floating-toolbar{display:none}.agentic-diagnostics-panel{position:absolute;z-index:21;right:16px;width:min(520px,calc(100% - 32px));max-height:min(440px,calc(100% - 32px));overflow:auto;padding:12px;border:1px solid rgba(107,114,128,.28);border-radius:8px;background:#fffffff5;color:#111827;box-shadow:0 14px 36px #0000003d}.agentic-diagnostics-panel--collapsed{width:min(280px,calc(100% - 32px));max-height:58px;overflow:hidden;padding:10px 12px;pointer-events:auto}.agentic-diagnostics-panel__header{display:flex;align-items:center;justify-content:space-between;gap:12px;font-size:13px;font-weight:700}.agentic-diagnostics-panel__header-actions{display:flex;align-items:center;gap:8px}.agentic-diagnostics-panel__badge{padding:2px 6px;border:1px solid rgba(107,114,128,.28);border-radius:8px;font-size:11px;font-weight:600;color:#4b5563}.agentic-diagnostics-panel__toggle,.shared-rule-cockpit__toggle{appearance:none;border:1px solid rgba(30,64,175,.18);border-radius:999px;background:#ffffffd6;color:#1e3a8a;cursor:pointer;font-size:11px;font-weight:700;line-height:1;padding:6px 9px;white-space:nowrap}.agentic-diagnostics-panel__description{margin:8px 0 10px;color:#4b5563;font-size:12px;line-height:1.4}.agentic-diagnostics-panel pre{margin:0;white-space:pre-wrap;overflow-wrap:anywhere;font-size:11px;line-height:1.45;color:#1f2937}praxis-ai-assistant-shell{position:relative;z-index:140}@media(min-width:1100px){.builder-shell--agentic-review-rail{box-sizing:border-box;padding-right:464px}}.builder-shell__agentic-toggle{position:relative}.builder-shell__agentic-toggle--open,.builder-shell__agentic-toggle--minimized{outline:2px solid rgba(96,165,250,.52);outline-offset:2px}.builder-shell__agentic-toggle--minimized:after{content:\"\";position:absolute;top:6px;right:6px;width:8px;height:8px;border:2px solid var(--md-sys-color-surface, #111827);border-radius:999px;background:#34d399}.shared-rule-cockpit{position:absolute;z-index:120;left:16px;bottom:88px;width:min(720px,calc(100% - 32px));max-height:min(560px,calc(100vh - 140px));padding:14px;border:1px solid rgba(30,64,175,.22);border-radius:12px;background:linear-gradient(135deg,#eff6fffa,#fffbebf5);color:#172554;box-shadow:0 18px 46px #0f172a38;overflow:auto;overscroll-behavior:contain}.shared-rule-cockpit--collapsed{width:min(360px,calc(100% - 32px));max-height:72px;overflow:hidden;padding:10px 12px}.shared-rule-cockpit__header{display:flex;align-items:flex-start;justify-content:space-between;gap:12px}.shared-rule-cockpit__header-actions{display:flex;align-items:center;gap:8px}.shared-rule-cockpit__header div{display:grid;gap:2px}.shared-rule-cockpit__header strong{font-size:14px;line-height:1.2}.shared-rule-cockpit__header span{color:#475569;font-size:12px;overflow-wrap:anywhere}.shared-rule-cockpit__badge{flex:0 0 auto;max-width:220px;padding:3px 8px;border:1px solid rgba(30,64,175,.2);border-radius:999px;background:#ffffffbd;color:#1e3a8a;font-size:11px;font-weight:700;overflow:hidden;text-overflow:ellipsis;white-space:nowrap}.shared-rule-cockpit__description,.shared-rule-cockpit__status,.shared-rule-cockpit__error{margin:10px 0 0;color:#334155;font-size:12px;line-height:1.45}.shared-rule-cockpit__error{color:#991b1b;font-weight:600}.shared-rule-cockpit__actions{display:flex;flex-wrap:wrap;gap:8px;margin-top:12px}.shared-rule-cockpit__facts{display:grid;grid-template-columns:repeat(3,minmax(0,1fr));gap:8px;margin:12px 0 0}.shared-rule-cockpit__facts div{min-width:0;padding:8px;border-radius:10px;background:#ffffffb8}.shared-rule-cockpit__facts dt{color:#64748b;font-size:11px;font-weight:700;text-transform:uppercase;letter-spacing:.04em}.shared-rule-cockpit__facts dd{margin:4px 0 0;color:#0f172a;font-size:12px;overflow-wrap:anywhere}.shared-rule-cockpit__enforcement-matrix{display:grid;gap:10px;margin-top:12px;padding:10px;border:1px solid rgba(30,64,175,.14);border-radius:12px;background:#ffffff94}.shared-rule-cockpit__matrix-header{display:flex;align-items:flex-start;justify-content:space-between;gap:10px}.shared-rule-cockpit__matrix-header div{display:grid;gap:2px}.shared-rule-cockpit__matrix-header strong{color:#0f172a;font-size:12px}.shared-rule-cockpit__matrix-header span,.shared-rule-cockpit__matrix-source{color:#475569;font-size:11px;line-height:1.35;overflow-wrap:anywhere}.shared-rule-cockpit__matrix-badge{flex:0 0 auto;padding:3px 8px;border-radius:999px;background:#16a34a1f;color:#166534;font-weight:800;white-space:nowrap}.shared-rule-cockpit__projection-grid{display:grid;grid-template-columns:repeat(2,minmax(0,1fr));gap:8px}.shared-rule-cockpit__projection{display:grid;gap:3px;min-width:0;padding:9px;border:1px solid rgba(15,23,42,.08);border-radius:11px;background:#f8fafcd1}.shared-rule-cockpit__projection[data-status=ready]{border-color:#16a34a33;background:#f0fdf4d1}.shared-rule-cockpit__projection span{color:#1d4ed8;font-size:10px;font-weight:800;letter-spacing:.04em;text-transform:uppercase;overflow-wrap:anywhere}.shared-rule-cockpit__projection strong{color:#0f172a;font-size:12px}.shared-rule-cockpit__projection small,.shared-rule-cockpit__projection em{color:#475569;font-size:11px;font-style:normal;overflow-wrap:anywhere}.shared-rule-cockpit__matrix-source{margin:0}.shared-rule-cockpit__timeline{display:grid;gap:8px;max-height:190px;margin:12px 0 0;padding:0;overflow:auto;list-style:none}.shared-rule-cockpit__timeline-item{display:grid;grid-template-columns:auto minmax(0,1fr);gap:10px;padding:10px;border:1px solid rgba(30,64,175,.12);border-radius:12px;background:#ffffffc2}.shared-rule-cockpit__timeline-icon{display:grid;width:24px;height:24px;place-items:center;border-radius:999px;background:#1e40af1a;color:#1e3a8a;font-family:Material Icons;font-size:16px;line-height:1}.shared-rule-cockpit__timeline-item strong{color:#0f172a;font-size:12px;line-height:1.35}.shared-rule-cockpit__timeline-item p,.shared-rule-cockpit__timeline-item small,.shared-rule-cockpit__timeline-item time,.shared-rule-cockpit__timeline-empty{display:block;margin:3px 0 0;color:#475569;font-size:11px;line-height:1.35;overflow-wrap:anywhere}.shared-rule-cockpit__timeline-badge{display:inline-flex;margin-left:6px;padding:2px 6px;border-radius:999px;background:#0ea5e91f;color:#075985;font-size:10px;font-weight:700}.shared-rule-cockpit__timeline-empty{padding:10px;border-radius:12px;background:#ffffffa3}@media(max-width:720px){.shared-rule-cockpit{bottom:72px;max-height:calc(100vh - 112px)}.shared-rule-cockpit__facts,.shared-rule-cockpit__projection-grid{grid-template-columns:1fr}}\n"], dependencies: [{ kind: "ngmodule", type: CommonModule }, { kind: "directive", type: i2$1.NgForOf, selector: "[ngFor][ngForOf]", inputs: ["ngForOf", "ngForTrackBy", "ngForTemplate"] }, { kind: "directive", type: i2$1.NgIf, selector: "[ngIf]", inputs: ["ngIf", "ngIfThen", "ngIfElse"] }, { kind: "ngmodule", type: MatButtonModule }, { kind: "component", type: i2.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: i2.MatMiniFabButton, selector: "button[mat-mini-fab], a[mat-mini-fab], button[matMiniFab], a[matMiniFab]", exportAs: ["matButton", "matAnchor"] }, { kind: "ngmodule", type: MatIconModule }, { kind: "component", type: i3.MatIcon, selector: "mat-icon", inputs: ["color", "inline", "svgIcon", "fontSet", "fontIcon"], exportAs: ["matIcon"] }, { kind: "ngmodule", type: MatTooltipModule }, { kind: "directive", type: i3$1.MatTooltip, selector: "[matTooltip]", inputs: ["matTooltipPosition", "matTooltipPositionAtOrigin", "matTooltipDisabled", "matTooltipShowDelay", "matTooltipHideDelay", "matTooltipTouchGestures", "matTooltip", "matTooltipClass"], exportAs: ["matTooltip"] }, { kind: "directive", type: PraxisIconDirective, selector: "mat-icon[praxisIcon]", inputs: ["praxisIcon"] }, { kind: "component", type: DynamicWidgetPageComponent, selector: "praxis-dynamic-page", inputs: ["page", "context", "strictValidation", "enableCustomization", "showPageSettingsButton", "shellEditorComponent", "pageEditorComponent", "autoPersist", "pageIdentity", "componentInstanceId", "showWidgetAssistantButton"], outputs: ["pageChange", "widgetEvent", "widgetSelectionChange", "widgetAssistantRequested", "widgetDiagnosticsChange"] }, { kind: "component", type: FloatingToolbarComponent, selector: "praxis-floating-toolbar", inputs: ["visible", "canUndo", "canRedo", "showSave", "showPreview"], outputs: ["add", "undo", "redo", "settings", "preview", "save"] }, { kind: "component", type: ConnectionEditorComponent, selector: "praxis-connection-editor", inputs: ["open", "page"], outputs: ["pageChange", "focusWidget", "openPageSettings"] }, { kind: "component", type: PraxisAiAssistantShellComponent, selector: "praxis-ai-assistant-shell", inputs: ["labels", "mode", "state", "contextItems", "attachments", "messages", "quickReplies", "prompt", "statusText", "errorText", "testIdPrefix", "panelTestId", "submitTestId", "applyTestId", "primaryAction", "secondaryActions", "governanceActions", "busy", "canSubmit", "canApply", "submitOnEnter", "showAttachAction", "enablePastedAttachments", "enableFileAttachments", "attachmentAccept", "attachmentMultiple", "draggable", "resizable", "minWidth", "minHeight", "margin", "layout"], outputs: ["promptChange", "submitPrompt", "apply", "retryTurn", "cancelTurn", "shellAction", "close", "attach", "attachmentsPasted", "attachmentsSelected", "removeAttachment", "messageAction", "editMessage", "resendMessage", "quickReply", "layoutChange"] }] });
18244
+ `, isInline: true, styles: [":host{display:block;position:relative;min-height:var(--pdx-page-builder-min-height, 420px)}.builder-shell{display:block;position:relative;min-height:inherit;height:100%}.builder-shell:has(.pdx-shell.fullscreen) praxis-floating-toolbar{display:none}.agentic-diagnostics-panel{position:absolute;z-index:21;right:16px;width:min(520px,calc(100% - 32px));max-height:min(440px,calc(100% - 32px));overflow:auto;padding:12px;border:1px solid rgba(107,114,128,.28);border-radius:8px;background:#fffffff5;color:#111827;box-shadow:0 14px 36px #0000003d}.agentic-diagnostics-panel--collapsed{width:min(280px,calc(100% - 32px));max-height:58px;overflow:hidden;padding:10px 12px;pointer-events:auto}.agentic-diagnostics-panel__header{display:flex;align-items:center;justify-content:space-between;gap:12px;font-size:13px;font-weight:700}.agentic-diagnostics-panel__header-actions{display:flex;align-items:center;gap:8px}.agentic-diagnostics-panel__badge{padding:2px 6px;border:1px solid rgba(107,114,128,.28);border-radius:8px;font-size:11px;font-weight:600;color:#4b5563}.agentic-diagnostics-panel__toggle,.shared-rule-cockpit__toggle{appearance:none;border:1px solid rgba(30,64,175,.18);border-radius:999px;background:#ffffffd6;color:#1e3a8a;cursor:pointer;font-size:11px;font-weight:700;line-height:1;padding:6px 9px;white-space:nowrap}.agentic-diagnostics-panel__description{margin:8px 0 10px;color:#4b5563;font-size:12px;line-height:1.4}.agentic-diagnostics-panel pre{margin:0;white-space:pre-wrap;overflow-wrap:anywhere;font-size:11px;line-height:1.45;color:#1f2937}praxis-ai-assistant-shell{position:relative;z-index:140}@media(min-width:1100px){.builder-shell--agentic-review-rail{box-sizing:border-box;padding-right:464px}}.builder-shell__agentic-toggle{position:relative}.builder-shell__agentic-toggle--open,.builder-shell__agentic-toggle--minimized{outline:2px solid rgba(96,165,250,.52);outline-offset:2px}.builder-shell__agentic-toggle--minimized:after{content:\"\";position:absolute;top:6px;right:6px;width:8px;height:8px;border:2px solid var(--md-sys-color-surface, #111827);border-radius:999px;background:#34d399}.shared-rule-cockpit{position:absolute;z-index:120;left:16px;bottom:88px;width:min(720px,calc(100% - 32px));max-height:min(560px,calc(100vh - 140px));padding:14px;border:1px solid rgba(30,64,175,.22);border-radius:12px;background:linear-gradient(135deg,#eff6fffa,#fffbebf5);color:#172554;box-shadow:0 18px 46px #0f172a38;overflow:auto;overscroll-behavior:contain}.shared-rule-cockpit--collapsed{width:min(360px,calc(100% - 32px));max-height:72px;overflow:hidden;padding:10px 12px}.shared-rule-cockpit__header{display:flex;align-items:flex-start;justify-content:space-between;gap:12px}.shared-rule-cockpit__header-actions{display:flex;align-items:center;gap:8px}.shared-rule-cockpit__header div{display:grid;gap:2px}.shared-rule-cockpit__header strong{font-size:14px;line-height:1.2}.shared-rule-cockpit__header span{color:#475569;font-size:12px;overflow-wrap:anywhere}.shared-rule-cockpit__badge{flex:0 0 auto;max-width:220px;padding:3px 8px;border:1px solid rgba(30,64,175,.2);border-radius:999px;background:#ffffffbd;color:#1e3a8a;font-size:11px;font-weight:700;overflow:hidden;text-overflow:ellipsis;white-space:nowrap}.shared-rule-cockpit__description,.shared-rule-cockpit__status,.shared-rule-cockpit__error{margin:10px 0 0;color:#334155;font-size:12px;line-height:1.45}.shared-rule-cockpit__error{color:#991b1b;font-weight:600}.shared-rule-cockpit__actions{display:flex;flex-wrap:wrap;gap:8px;margin-top:12px}.shared-rule-cockpit__facts{display:grid;grid-template-columns:repeat(3,minmax(0,1fr));gap:8px;margin:12px 0 0}.shared-rule-cockpit__facts div{min-width:0;padding:8px;border-radius:10px;background:#ffffffb8}.shared-rule-cockpit__facts dt{color:#64748b;font-size:11px;font-weight:700;text-transform:uppercase;letter-spacing:.04em}.shared-rule-cockpit__facts dd{margin:4px 0 0;color:#0f172a;font-size:12px;overflow-wrap:anywhere}.shared-rule-cockpit__enforcement-matrix{display:grid;gap:10px;margin-top:12px;padding:10px;border:1px solid rgba(30,64,175,.14);border-radius:12px;background:#ffffff94}.shared-rule-cockpit__matrix-header{display:flex;align-items:flex-start;justify-content:space-between;gap:10px}.shared-rule-cockpit__matrix-header div{display:grid;gap:2px}.shared-rule-cockpit__matrix-header strong{color:#0f172a;font-size:12px}.shared-rule-cockpit__matrix-header span,.shared-rule-cockpit__matrix-source{color:#475569;font-size:11px;line-height:1.35;overflow-wrap:anywhere}.shared-rule-cockpit__matrix-badge{flex:0 0 auto;padding:3px 8px;border-radius:999px;background:#16a34a1f;color:#166534;font-weight:800;white-space:nowrap}.shared-rule-cockpit__projection-grid{display:grid;grid-template-columns:repeat(2,minmax(0,1fr));gap:8px}.shared-rule-cockpit__projection{display:grid;gap:3px;min-width:0;padding:9px;border:1px solid rgba(15,23,42,.08);border-radius:11px;background:#f8fafcd1}.shared-rule-cockpit__projection[data-status=ready]{border-color:#16a34a33;background:#f0fdf4d1}.shared-rule-cockpit__projection span{color:#1d4ed8;font-size:10px;font-weight:800;letter-spacing:.04em;text-transform:uppercase;overflow-wrap:anywhere}.shared-rule-cockpit__projection strong{color:#0f172a;font-size:12px}.shared-rule-cockpit__projection small,.shared-rule-cockpit__projection em{color:#475569;font-size:11px;font-style:normal;overflow-wrap:anywhere}.shared-rule-cockpit__matrix-source{margin:0}.shared-rule-cockpit__timeline{display:grid;gap:8px;max-height:190px;margin:12px 0 0;padding:0;overflow:auto;list-style:none}.shared-rule-cockpit__timeline-item{display:grid;grid-template-columns:auto minmax(0,1fr);gap:10px;padding:10px;border:1px solid rgba(30,64,175,.12);border-radius:12px;background:#ffffffc2}.shared-rule-cockpit__timeline-icon{display:grid;width:24px;height:24px;place-items:center;border-radius:999px;background:#1e40af1a;color:#1e3a8a;font-family:Material Icons;font-size:16px;line-height:1}.shared-rule-cockpit__timeline-item strong{color:#0f172a;font-size:12px;line-height:1.35}.shared-rule-cockpit__timeline-item p,.shared-rule-cockpit__timeline-item small,.shared-rule-cockpit__timeline-item time,.shared-rule-cockpit__timeline-empty{display:block;margin:3px 0 0;color:#475569;font-size:11px;line-height:1.35;overflow-wrap:anywhere}.shared-rule-cockpit__timeline-badge{display:inline-flex;margin-left:6px;padding:2px 6px;border-radius:999px;background:#0ea5e91f;color:#075985;font-size:10px;font-weight:700}.shared-rule-cockpit__timeline-empty{padding:10px;border-radius:12px;background:#ffffffa3}@media(max-width:720px){.shared-rule-cockpit{bottom:72px;max-height:calc(100vh - 112px)}.shared-rule-cockpit__facts,.shared-rule-cockpit__projection-grid{grid-template-columns:1fr}}\n"], dependencies: [{ kind: "ngmodule", type: MatButtonModule }, { kind: "component", type: i2.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: i2.MatMiniFabButton, selector: "button[mat-mini-fab], a[mat-mini-fab], button[matMiniFab], a[matMiniFab]", exportAs: ["matButton", "matAnchor"] }, { kind: "ngmodule", type: MatIconModule }, { kind: "component", type: i2$1.MatIcon, selector: "mat-icon", inputs: ["color", "inline", "svgIcon", "fontSet", "fontIcon"], exportAs: ["matIcon"] }, { kind: "ngmodule", type: MatTooltipModule }, { kind: "directive", type: i3.MatTooltip, selector: "[matTooltip]", inputs: ["matTooltipPosition", "matTooltipPositionAtOrigin", "matTooltipDisabled", "matTooltipShowDelay", "matTooltipHideDelay", "matTooltipTouchGestures", "matTooltip", "matTooltipClass"], exportAs: ["matTooltip"] }, { kind: "directive", type: PraxisIconDirective, selector: "mat-icon[praxisIcon]", inputs: ["praxisIcon"] }, { kind: "component", type: DynamicWidgetPageComponent, selector: "praxis-dynamic-page", inputs: ["page", "context", "strictValidation", "enableCustomization", "showPageSettingsButton", "shellEditorComponent", "pageEditorComponent", "autoPersist", "pageIdentity", "componentInstanceId", "showWidgetAssistantButton"], outputs: ["pageChange", "widgetEvent", "widgetSelectionChange", "widgetAssistantRequested", "widgetDiagnosticsChange"] }, { kind: "component", type: FloatingToolbarComponent, selector: "praxis-floating-toolbar", inputs: ["visible", "canUndo", "canRedo", "showSave", "showPreview"], outputs: ["add", "undo", "redo", "settings", "preview", "save"] }, { kind: "component", type: ConnectionEditorComponent, selector: "praxis-connection-editor", inputs: ["open", "page"], outputs: ["pageChange", "focusWidget", "openPageSettings"] }, { kind: "component", type: PraxisAiAssistantShellComponent, selector: "praxis-ai-assistant-shell", inputs: ["labels", "mode", "state", "contextItems", "attachments", "messages", "quickReplies", "prompt", "statusText", "errorText", "testIdPrefix", "panelTestId", "submitTestId", "applyTestId", "primaryAction", "secondaryActions", "governanceActions", "busy", "canSubmit", "canApply", "submitOnEnter", "showAttachAction", "enablePastedAttachments", "enableFileAttachments", "attachmentAccept", "attachmentMultiple", "draggable", "resizable", "minWidth", "minHeight", "margin", "layout"], outputs: ["promptChange", "submitPrompt", "apply", "retryTurn", "cancelTurn", "shellAction", "close", "attach", "attachmentsPasted", "attachmentsSelected", "removeAttachment", "messageAction", "editMessage", "resendMessage", "quickReply", "layoutChange"] }] });
18085
18245
  }
18086
- i0.ɵɵngDeclareClassMetadata({ minVersion: "12.0.0", version: "20.3.17", ngImport: i0, type: DynamicPageBuilderComponent, decorators: [{
18246
+ i0.ɵɵngDeclareClassMetadata({ minVersion: "12.0.0", version: "21.2.14", ngImport: i0, type: DynamicPageBuilderComponent, decorators: [{
18087
18247
  type: Component,
18088
18248
  args: [{ selector: 'praxis-dynamic-page-builder', standalone: true, imports: [
18089
- CommonModule,
18090
18249
  MatButtonModule,
18091
18250
  MatIconModule,
18092
18251
  MatTooltipModule,
@@ -18094,7 +18253,7 @@ i0.ɵɵngDeclareClassMetadata({ minVersion: "12.0.0", version: "20.3.17", ngImpo
18094
18253
  DynamicWidgetPageComponent,
18095
18254
  FloatingToolbarComponent,
18096
18255
  ConnectionEditorComponent,
18097
- PraxisAiAssistantShellComponent,
18256
+ PraxisAiAssistantShellComponent
18098
18257
  ], providers: [
18099
18258
  providePraxisPageBuilderI18n(),
18100
18259
  { provide: DYNAMIC_PAGE_SHELL_EDITOR, useValue: WidgetShellEditorComponent },
@@ -18102,7 +18261,7 @@ i0.ɵɵngDeclareClassMetadata({ minVersion: "12.0.0", version: "20.3.17", ngImpo
18102
18261
  <div
18103
18262
  class="builder-shell"
18104
18263
  [class.builder-shell--agentic-review-rail]="agenticAuthoringReviewRailActive()"
18105
- >
18264
+ >
18106
18265
  <praxis-dynamic-page
18107
18266
  #runtime
18108
18267
  [page]="currentPage()"
@@ -18119,325 +18278,338 @@ i0.ɵɵngDeclareClassMetadata({ minVersion: "12.0.0", version: "20.3.17", ngImpo
18119
18278
  (widgetEvent)="onRuntimeWidgetEvent($event)"
18120
18279
  (widgetSelectionChange)="onRuntimeWidgetSelectionChange($event)"
18121
18280
  (widgetAssistantRequested)="openAgenticAuthoringForWidget($event)"
18122
- />
18123
-
18281
+ />
18282
+
18124
18283
  <praxis-connection-editor
18125
18284
  [open]="showSettings() && connectionsViewerOpen()"
18126
18285
  [page]="currentPage()"
18127
18286
  (pageChange)="onConnectionEditorPageChange($event)"
18128
18287
  (focusWidget)="focusCanvasWidget($event)"
18129
18288
  (openPageSettings)="openPageSettings()"
18130
- />
18131
-
18132
- <praxis-ai-assistant-shell
18133
- *ngIf="showSettings() && enableAgenticAuthoring && agenticAuthoringOpen()"
18134
- panelTestId="page-builder-agentic-authoring-panel"
18135
- testIdPrefix="page-builder-agentic"
18136
- submitTestId="page-builder-agentic-preview"
18137
- applyTestId="page-builder-agentic-persist"
18138
- [labels]="agenticAuthoringShellLabels()"
18139
- mode="agentic-authoring"
18140
- [state]="agenticAuthoringShellState()"
18141
- [contextItems]="agenticAuthoringContextItems()"
18142
- [attachments]="agenticAuthoringAttachments()"
18143
- [messages]="agenticAuthoringConversation()"
18144
- [quickReplies]="agenticAuthoringQuickReplies()"
18145
- [prompt]="agenticAuthoringPrompt()"
18146
- [statusText]="agenticAuthoringStatus()"
18147
- [errorText]="agenticAuthoringError()"
18148
- [busy]="agenticAuthoringBusy()"
18149
- [canApply]="agenticAuthoringCanApply()"
18150
- [primaryAction]="agenticAuthoringSubmitAction()"
18151
- [showAttachAction]="false"
18152
- [enablePastedAttachments]="false"
18153
- [layout]="agenticAuthoringPanelLayout()"
18154
- [minWidth]="320"
18155
- [minHeight]="280"
18156
- [margin]="8"
18157
- (promptChange)="agenticAuthoringPrompt.set($event)"
18158
- (submitPrompt)="agenticAuthoringPrompt.set($event); previewAgenticAuthoring()"
18159
- (apply)="persistAgenticAuthoring()"
18160
- (retryTurn)="retryAgenticAuthoring()"
18161
- (cancelTurn)="cancelAgenticAuthoring()"
18162
- (quickReply)="submitAgenticQuickReply($event)"
18163
- (attach)="attachAgenticContext()"
18164
- (removeAttachment)="removeAgenticAttachment($event)"
18165
- (editMessage)="editAgenticMessage($event)"
18166
- (resendMessage)="resendAgenticMessage($event)"
18167
- (layoutChange)="onAgenticAuthoringLayoutChange($event)"
18168
- (close)="minimizeAgenticAuthoring()"
18169
- />
18170
-
18171
- <section
18172
- *ngIf="agenticAuthoringIncludeLlmDiagnostics && agenticAuthoringLlmDiagnosticsText()"
18173
- class="agentic-diagnostics-panel"
18174
- [class.agentic-diagnostics-panel--collapsed]="agenticAuthoringLlmDiagnosticsCollapsed()"
18175
- data-testid="page-builder-agentic-llm-diagnostics"
18176
- role="region"
18177
- [attr.aria-label]="tx('agentic.diagnostics.title', 'LLM diagnostics')"
18178
- [style.top.px]="agenticAuthoringDiagnosticsTop()"
18179
- >
18180
- <header class="agentic-diagnostics-panel__header">
18181
- <span>{{ tx('agentic.diagnostics.title', 'LLM diagnostics') }}</span>
18182
- <div class="agentic-diagnostics-panel__header-actions">
18183
- <span class="agentic-diagnostics-panel__badge">
18184
- {{ tx('agentic.diagnostics.badge', 'Debug') }}
18185
- </span>
18186
- <button
18187
- class="agentic-diagnostics-panel__toggle"
18188
- data-testid="page-builder-agentic-llm-diagnostics-toggle"
18189
- type="button"
18190
- [attr.aria-expanded]="!agenticAuthoringLlmDiagnosticsCollapsed()"
18191
- (click)="toggleAgenticAuthoringLlmDiagnostics()"
18192
- >
18193
- {{ agenticAuthoringLlmDiagnosticsCollapsed()
18289
+ />
18290
+
18291
+ @if (showSettings() && enableAgenticAuthoring && agenticAuthoringOpen()) {
18292
+ <praxis-ai-assistant-shell
18293
+ panelTestId="page-builder-agentic-authoring-panel"
18294
+ testIdPrefix="page-builder-agentic"
18295
+ submitTestId="page-builder-agentic-preview"
18296
+ applyTestId="page-builder-agentic-persist"
18297
+ [labels]="agenticAuthoringShellLabels()"
18298
+ mode="agentic-authoring"
18299
+ [state]="agenticAuthoringShellState()"
18300
+ [contextItems]="agenticAuthoringContextItems()"
18301
+ [attachments]="agenticAuthoringAttachments()"
18302
+ [messages]="agenticAuthoringConversation()"
18303
+ [quickReplies]="agenticAuthoringQuickReplies()"
18304
+ [prompt]="agenticAuthoringPrompt()"
18305
+ [statusText]="agenticAuthoringStatus()"
18306
+ [errorText]="agenticAuthoringError()"
18307
+ [busy]="agenticAuthoringBusy()"
18308
+ [canApply]="agenticAuthoringCanApply()"
18309
+ [primaryAction]="agenticAuthoringSubmitAction()"
18310
+ [showAttachAction]="false"
18311
+ [enablePastedAttachments]="false"
18312
+ [layout]="agenticAuthoringPanelLayout()"
18313
+ [minWidth]="320"
18314
+ [minHeight]="280"
18315
+ [margin]="8"
18316
+ (promptChange)="agenticAuthoringPrompt.set($event)"
18317
+ (submitPrompt)="agenticAuthoringPrompt.set($event); previewAgenticAuthoring()"
18318
+ (apply)="persistAgenticAuthoring()"
18319
+ (retryTurn)="retryAgenticAuthoring()"
18320
+ (cancelTurn)="cancelAgenticAuthoring()"
18321
+ (quickReply)="submitAgenticQuickReply($event)"
18322
+ (attach)="attachAgenticContext()"
18323
+ (removeAttachment)="removeAgenticAttachment($event)"
18324
+ (editMessage)="editAgenticMessage($event)"
18325
+ (resendMessage)="resendAgenticMessage($event)"
18326
+ (layoutChange)="onAgenticAuthoringLayoutChange($event)"
18327
+ (close)="minimizeAgenticAuthoring()"
18328
+ />
18329
+ }
18330
+
18331
+ @if (agenticAuthoringIncludeLlmDiagnostics && agenticAuthoringLlmDiagnosticsText()) {
18332
+ <section
18333
+ class="agentic-diagnostics-panel"
18334
+ [class.agentic-diagnostics-panel--collapsed]="agenticAuthoringLlmDiagnosticsCollapsed()"
18335
+ data-testid="page-builder-agentic-llm-diagnostics"
18336
+ role="region"
18337
+ [attr.aria-label]="tx('agentic.diagnostics.title', 'LLM diagnostics')"
18338
+ [style.top.px]="agenticAuthoringDiagnosticsTop()"
18339
+ >
18340
+ <header class="agentic-diagnostics-panel__header">
18341
+ <span>{{ tx('agentic.diagnostics.title', 'LLM diagnostics') }}</span>
18342
+ <div class="agentic-diagnostics-panel__header-actions">
18343
+ <span class="agentic-diagnostics-panel__badge">
18344
+ {{ tx('agentic.diagnostics.badge', 'Debug') }}
18345
+ </span>
18346
+ <button
18347
+ class="agentic-diagnostics-panel__toggle"
18348
+ data-testid="page-builder-agentic-llm-diagnostics-toggle"
18349
+ type="button"
18350
+ [attr.aria-expanded]="!agenticAuthoringLlmDiagnosticsCollapsed()"
18351
+ (click)="toggleAgenticAuthoringLlmDiagnostics()"
18352
+ >
18353
+ {{ agenticAuthoringLlmDiagnosticsCollapsed()
18194
18354
  ? tx('agentic.diagnostics.expand', 'Expand')
18195
18355
  : tx('agentic.diagnostics.collapse', 'Collapse') }}
18196
- </button>
18197
- </div>
18198
- </header>
18199
- <ng-container *ngIf="!agenticAuthoringLlmDiagnosticsCollapsed()">
18200
- <p class="agentic-diagnostics-panel__description">
18201
- {{ tx('agentic.diagnostics.description', 'Prompt, context bundle, and tool catalog returned by the backend for this turn.') }}
18202
- </p>
18203
- <pre>{{ agenticAuthoringLlmDiagnosticsText() }}</pre>
18204
- </ng-container>
18205
- </section>
18206
-
18207
- <section
18208
- *ngIf="agenticAuthoringSharedRuleHandoffState() as handoff"
18209
- class="shared-rule-cockpit"
18210
- [class.shared-rule-cockpit--collapsed]="sharedRuleCockpitCollapsed()"
18211
- data-testid="page-builder-shared-rule-cockpit"
18212
- role="region"
18213
- [attr.aria-label]="tx('agentic.sharedRuleCockpit.title', 'Shared-rule governed actions')"
18214
- >
18215
- <header class="shared-rule-cockpit__header">
18216
- <div>
18217
- <strong>{{ tx('agentic.sharedRuleCockpit.title', 'Shared-rule governed actions') }}</strong>
18218
- <span>{{ handoff.ruleKey || handoff.recommendedRuleType || handoff.flowId }}</span>
18219
- </div>
18220
- <div class="shared-rule-cockpit__header-actions">
18221
- <span class="shared-rule-cockpit__badge">{{ handoff.routeGateStatus || handoff.previewDisposition }}</span>
18222
- <button
18223
- class="shared-rule-cockpit__toggle"
18224
- data-testid="shared-rule-cockpit-toggle"
18225
- type="button"
18226
- [attr.aria-expanded]="!sharedRuleCockpitCollapsed()"
18227
- (click)="toggleSharedRuleCockpit()"
18228
- >
18229
- {{ sharedRuleCockpitCollapsed()
18356
+ </button>
18357
+ </div>
18358
+ </header>
18359
+ @if (!agenticAuthoringLlmDiagnosticsCollapsed()) {
18360
+ <p class="agentic-diagnostics-panel__description">
18361
+ {{ tx('agentic.diagnostics.description', 'Prompt, context bundle, and tool catalog returned by the backend for this turn.') }}
18362
+ </p>
18363
+ <pre>{{ agenticAuthoringLlmDiagnosticsText() }}</pre>
18364
+ }
18365
+ </section>
18366
+ }
18367
+
18368
+ @if (agenticAuthoringSharedRuleHandoffState(); as handoff) {
18369
+ <section
18370
+ class="shared-rule-cockpit"
18371
+ [class.shared-rule-cockpit--collapsed]="sharedRuleCockpitCollapsed()"
18372
+ data-testid="page-builder-shared-rule-cockpit"
18373
+ role="region"
18374
+ [attr.aria-label]="tx('agentic.sharedRuleCockpit.title', 'Shared-rule governed actions')"
18375
+ >
18376
+ <header class="shared-rule-cockpit__header">
18377
+ <div>
18378
+ <strong>{{ tx('agentic.sharedRuleCockpit.title', 'Shared-rule governed actions') }}</strong>
18379
+ <span>{{ handoff.ruleKey || handoff.recommendedRuleType || handoff.flowId }}</span>
18380
+ </div>
18381
+ <div class="shared-rule-cockpit__header-actions">
18382
+ <span class="shared-rule-cockpit__badge">{{ handoff.routeGateStatus || handoff.previewDisposition }}</span>
18383
+ <button
18384
+ class="shared-rule-cockpit__toggle"
18385
+ data-testid="shared-rule-cockpit-toggle"
18386
+ type="button"
18387
+ [attr.aria-expanded]="!sharedRuleCockpitCollapsed()"
18388
+ (click)="toggleSharedRuleCockpit()"
18389
+ >
18390
+ {{ sharedRuleCockpitCollapsed()
18230
18391
  ? tx('agentic.sharedRuleCockpit.expand', 'Expand')
18231
18392
  : tx('agentic.sharedRuleCockpit.collapse', 'Collapse') }}
18232
- </button>
18233
- </div>
18234
- </header>
18235
-
18236
- <ng-container *ngIf="!sharedRuleCockpitCollapsed()">
18237
- <p class="shared-rule-cockpit__description">
18238
- {{ tx('agentic.sharedRuleCockpit.description', 'Continue the semantic decision in the governed domain-rules lifecycle. The cockpit calls canonical backend actions and only displays derived materializations.') }}
18239
- </p>
18240
-
18241
- <div class="shared-rule-cockpit__actions">
18242
- <button
18243
- *ngFor="let action of sharedRuleGovernedContinuationActions(); trackBy: trackGovernedContinuationAction"
18244
- mat-stroked-button
18245
- type="button"
18246
- [attr.data-testid]="governedContinuationActionTestId(action)"
18247
- [attr.data-action-kind]="action.kind"
18248
- [disabled]="!action.enabled"
18249
- [matTooltip]="governedContinuationActionTooltip(action)"
18250
- (click)="runSharedRuleGovernedContinuationAction(action)"
18251
- >
18252
- {{ tx(action.labelKey, action.labelFallback) }}
18253
- </button>
18254
- </div>
18255
-
18256
- <p *ngIf="sharedRuleCockpitBusyAction() as action" class="shared-rule-cockpit__status" data-testid="shared-rule-cockpit-busy">
18257
- {{ tx('agentic.sharedRuleCockpit.running', 'Running governed action') }}: {{ action }}
18258
- </p>
18259
- <p *ngIf="sharedRuleCockpitError()" class="shared-rule-cockpit__error" data-testid="shared-rule-cockpit-error">
18260
- {{ sharedRuleCockpitError() }}
18261
- </p>
18262
-
18263
- <dl class="shared-rule-cockpit__facts">
18264
- <div>
18265
- <dt>{{ tx('agentic.sharedRuleCockpit.definitionId', 'Definition') }}</dt>
18266
- <dd data-testid="shared-rule-cockpit-definition-id">{{ handoff.ruleDefinitionId || tx('agentic.sharedRuleCockpit.pending', 'pending') }}</dd>
18267
- </div>
18268
- <div>
18269
- <dt>{{ tx('agentic.sharedRuleCockpit.simulation', 'Simulation') }}</dt>
18270
- <dd data-testid="shared-rule-cockpit-simulation-result">{{ sharedRuleCockpitSimulation()?.result || tx('agentic.sharedRuleCockpit.pending', 'pending') }}</dd>
18271
- </div>
18272
- <div>
18273
- <dt>{{ tx('agentic.sharedRuleCockpit.publication', 'Publication') }}</dt>
18274
- <dd data-testid="shared-rule-cockpit-publication-status">{{ sharedRuleCockpitPublication()?.publicationStatus || tx('agentic.sharedRuleCockpit.pending', 'pending') }}</dd>
18275
- </div>
18276
- <div>
18277
- <dt>{{ tx('agentic.sharedRuleCockpit.materializations', 'Materializations') }}</dt>
18278
- <dd data-testid="shared-rule-cockpit-materialization-count">{{ sharedRuleCockpitMaterializations().length }}</dd>
18279
- </div>
18280
- <div>
18281
- <dt>{{ tx('agentic.sharedRuleCockpit.timeline', 'Governed timeline') }}</dt>
18282
- <dd data-testid="shared-rule-cockpit-timeline-count">{{ sharedRuleCockpitTimeline()?.events?.length || 0 }}</dd>
18283
- </div>
18284
- <div>
18285
- <dt>{{ tx('agentic.sharedRuleCockpit.enforcementState', 'Runtime enforcement') }}</dt>
18286
- <dd data-testid="shared-rule-cockpit-enforcement-status">{{ sharedRuleCockpitEnforcement()?.status || tx('agentic.sharedRuleCockpit.pending', 'pending') }}</dd>
18287
- </div>
18288
- </dl>
18289
-
18290
- <section
18291
- *ngIf="sharedRuleCockpitEnforcement() as enforcement"
18292
- class="shared-rule-cockpit__enforcement-matrix"
18293
- data-testid="shared-rule-cockpit-enforcement-matrix"
18294
- [attr.aria-label]="tx('agentic.sharedRuleCockpit.enforcementMatrix', 'Runtime enforcement matrix')"
18393
+ </button>
18394
+ </div>
18395
+ </header>
18396
+ @if (!sharedRuleCockpitCollapsed()) {
18397
+ <p class="shared-rule-cockpit__description">
18398
+ {{ tx('agentic.sharedRuleCockpit.description', 'Continue the semantic decision in the governed domain-rules lifecycle. The cockpit calls canonical backend actions and only displays derived materializations.') }}
18399
+ </p>
18400
+ <div class="shared-rule-cockpit__actions">
18401
+ @for (action of sharedRuleGovernedContinuationActions(); track trackGovernedContinuationAction($index, action)) {
18402
+ <button
18403
+ mat-stroked-button
18404
+ type="button"
18405
+ [attr.data-testid]="governedContinuationActionTestId(action)"
18406
+ [attr.data-action-kind]="action.kind"
18407
+ [disabled]="!action.enabled"
18408
+ [matTooltip]="governedContinuationActionTooltip(action)"
18409
+ (click)="runSharedRuleGovernedContinuationAction(action)"
18410
+ >
18411
+ {{ tx(action.labelKey, action.labelFallback) }}
18412
+ </button>
18413
+ }
18414
+ </div>
18415
+ @if (sharedRuleCockpitBusyAction(); as action) {
18416
+ <p class="shared-rule-cockpit__status" data-testid="shared-rule-cockpit-busy">
18417
+ {{ tx('agentic.sharedRuleCockpit.running', 'Running governed action') }}: {{ action }}
18418
+ </p>
18419
+ }
18420
+ @if (sharedRuleCockpitError()) {
18421
+ <p class="shared-rule-cockpit__error" data-testid="shared-rule-cockpit-error">
18422
+ {{ sharedRuleCockpitError() }}
18423
+ </p>
18424
+ }
18425
+ <dl class="shared-rule-cockpit__facts">
18426
+ <div>
18427
+ <dt>{{ tx('agentic.sharedRuleCockpit.definitionId', 'Definition') }}</dt>
18428
+ <dd data-testid="shared-rule-cockpit-definition-id">{{ handoff.ruleDefinitionId || tx('agentic.sharedRuleCockpit.pending', 'pending') }}</dd>
18429
+ </div>
18430
+ <div>
18431
+ <dt>{{ tx('agentic.sharedRuleCockpit.simulation', 'Simulation') }}</dt>
18432
+ <dd data-testid="shared-rule-cockpit-simulation-result">{{ sharedRuleCockpitSimulation()?.result || tx('agentic.sharedRuleCockpit.pending', 'pending') }}</dd>
18433
+ </div>
18434
+ <div>
18435
+ <dt>{{ tx('agentic.sharedRuleCockpit.publication', 'Publication') }}</dt>
18436
+ <dd data-testid="shared-rule-cockpit-publication-status">{{ sharedRuleCockpitPublication()?.publicationStatus || tx('agentic.sharedRuleCockpit.pending', 'pending') }}</dd>
18437
+ </div>
18438
+ <div>
18439
+ <dt>{{ tx('agentic.sharedRuleCockpit.materializations', 'Materializations') }}</dt>
18440
+ <dd data-testid="shared-rule-cockpit-materialization-count">{{ sharedRuleCockpitMaterializations().length }}</dd>
18441
+ </div>
18442
+ <div>
18443
+ <dt>{{ tx('agentic.sharedRuleCockpit.timeline', 'Governed timeline') }}</dt>
18444
+ <dd data-testid="shared-rule-cockpit-timeline-count">{{ sharedRuleCockpitTimeline()?.events?.length || 0 }}</dd>
18445
+ </div>
18446
+ <div>
18447
+ <dt>{{ tx('agentic.sharedRuleCockpit.enforcementState', 'Runtime enforcement') }}</dt>
18448
+ <dd data-testid="shared-rule-cockpit-enforcement-status">{{ sharedRuleCockpitEnforcement()?.status || tx('agentic.sharedRuleCockpit.pending', 'pending') }}</dd>
18449
+ </div>
18450
+ </dl>
18451
+ @if (sharedRuleCockpitEnforcement(); as enforcement) {
18452
+ <section
18453
+ class="shared-rule-cockpit__enforcement-matrix"
18454
+ data-testid="shared-rule-cockpit-enforcement-matrix"
18455
+ [attr.aria-label]="tx('agentic.sharedRuleCockpit.enforcementMatrix', 'Runtime enforcement matrix')"
18456
+ >
18457
+ <header class="shared-rule-cockpit__matrix-header">
18458
+ <div>
18459
+ <strong>{{ tx('agentic.sharedRuleCockpit.enforcementMatrix', 'Runtime enforcement matrix') }}</strong>
18460
+ <span>{{ tx('agentic.sharedRuleCockpit.enforcementMatrixDescription', 'Derived projections that the runtime can enforce after publication.') }}</span>
18461
+ </div>
18462
+ <span class="shared-rule-cockpit__matrix-badge" data-testid="shared-rule-cockpit-enforcement-counts">
18463
+ {{ enforcement.appliedCount }} {{ tx('agentic.sharedRuleCockpit.applied', 'applied') }} /
18464
+ {{ enforcement.pendingCount }} {{ tx('agentic.sharedRuleCockpit.waiting', 'waiting') }}
18465
+ </span>
18466
+ </header>
18467
+ <div class="shared-rule-cockpit__projection-grid">
18468
+ @for (projection of enforcement.projections; track trackSharedRuleEnforcementProjection($index, projection)) {
18469
+ <article
18470
+ class="shared-rule-cockpit__projection"
18471
+ [attr.data-status]="projection.status"
18472
+ data-testid="shared-rule-cockpit-enforcement-projection"
18473
+ >
18474
+ <span data-testid="shared-rule-cockpit-enforcement-layer">{{ projection.targetLayer }}</span>
18475
+ <strong>{{ projection.targetLayerLabel }}</strong>
18476
+ <small>{{ projection.targetArtifact || tx('agentic.sharedRuleCockpit.artifactPending', 'artifact pending') }}</small>
18477
+ <em>{{ projection.sourceHash || tx('agentic.sharedRuleCockpit.sourceHashPending', 'source hash pending') }}</em>
18478
+ </article>
18479
+ }
18480
+ </div>
18481
+ <p class="shared-rule-cockpit__matrix-source" data-testid="shared-rule-cockpit-enforcement-sourcehash">
18482
+ <strong>{{ tx('agentic.sharedRuleCockpit.sourceHashes', 'Source hashes') }}:</strong>
18483
+ {{ enforcement.sourceHashes.length ? enforcement.sourceHashes.join(', ') : tx('agentic.sharedRuleCockpit.sourceHashPending', 'source hash pending') }}
18484
+ </p>
18485
+ </section>
18486
+ }
18487
+ }
18488
+ </section>
18489
+ }
18490
+
18491
+ @if (agenticAuthoringProjectKnowledgeAudit(); as audit) {
18492
+ <section
18493
+ class="project-knowledge-cockpit shared-rule-cockpit"
18494
+ [class.shared-rule-cockpit--collapsed]="projectKnowledgeCockpitCollapsed()"
18495
+ data-testid="page-builder-project-knowledge-cockpit"
18496
+ role="region"
18497
+ [attr.aria-label]="tx('agentic.projectKnowledgeCockpit.title', 'Project Knowledge governed actions')"
18295
18498
  >
18296
- <header class="shared-rule-cockpit__matrix-header">
18499
+ <header class="shared-rule-cockpit__header">
18297
18500
  <div>
18298
- <strong>{{ tx('agentic.sharedRuleCockpit.enforcementMatrix', 'Runtime enforcement matrix') }}</strong>
18299
- <span>{{ tx('agentic.sharedRuleCockpit.enforcementMatrixDescription', 'Derived projections that the runtime can enforce after publication.') }}</span>
18501
+ <strong>{{ tx('agentic.projectKnowledgeCockpit.title', 'Project Knowledge governed actions') }}</strong>
18502
+ <span>{{ tx('agentic.projectKnowledgeCockpit.subtitle', 'Continue cited knowledge as a governed Domain Knowledge change-set.') }}</span>
18300
18503
  </div>
18301
- <span class="shared-rule-cockpit__matrix-badge" data-testid="shared-rule-cockpit-enforcement-counts">
18302
- {{ enforcement.appliedCount }} {{ tx('agentic.sharedRuleCockpit.applied', 'applied') }} /
18303
- {{ enforcement.pendingCount }} {{ tx('agentic.sharedRuleCockpit.waiting', 'waiting') }}
18304
- </span>
18305
- </header>
18306
-
18307
- <div class="shared-rule-cockpit__projection-grid">
18308
- <article
18309
- *ngFor="let projection of enforcement.projections; trackBy: trackSharedRuleEnforcementProjection"
18310
- class="shared-rule-cockpit__projection"
18311
- [attr.data-status]="projection.status"
18312
- data-testid="shared-rule-cockpit-enforcement-projection"
18313
- >
18314
- <span data-testid="shared-rule-cockpit-enforcement-layer">{{ projection.targetLayer }}</span>
18315
- <strong>{{ projection.targetLayerLabel }}</strong>
18316
- <small>{{ projection.targetArtifact || tx('agentic.sharedRuleCockpit.artifactPending', 'artifact pending') }}</small>
18317
- <em>{{ projection.sourceHash || tx('agentic.sharedRuleCockpit.sourceHashPending', 'source hash pending') }}</em>
18318
- </article>
18319
- </div>
18320
-
18321
- <p class="shared-rule-cockpit__matrix-source" data-testid="shared-rule-cockpit-enforcement-sourcehash">
18322
- <strong>{{ tx('agentic.sharedRuleCockpit.sourceHashes', 'Source hashes') }}:</strong>
18323
- {{ enforcement.sourceHashes.length ? enforcement.sourceHashes.join(', ') : tx('agentic.sharedRuleCockpit.sourceHashPending', 'source hash pending') }}
18324
- </p>
18325
- </section>
18326
- </ng-container>
18327
- </section>
18328
-
18329
- <section
18330
- *ngIf="agenticAuthoringProjectKnowledgeAudit() as audit"
18331
- class="project-knowledge-cockpit shared-rule-cockpit"
18332
- [class.shared-rule-cockpit--collapsed]="projectKnowledgeCockpitCollapsed()"
18333
- data-testid="page-builder-project-knowledge-cockpit"
18334
- role="region"
18335
- [attr.aria-label]="tx('agentic.projectKnowledgeCockpit.title', 'Project Knowledge governed actions')"
18336
- >
18337
- <header class="shared-rule-cockpit__header">
18338
- <div>
18339
- <strong>{{ tx('agentic.projectKnowledgeCockpit.title', 'Project Knowledge governed actions') }}</strong>
18340
- <span>{{ tx('agentic.projectKnowledgeCockpit.subtitle', 'Continue cited knowledge as a governed Domain Knowledge change-set.') }}</span>
18341
- </div>
18342
- <div class="shared-rule-cockpit__header-actions">
18343
- <span class="shared-rule-cockpit__badge">{{ audit.citationPolicy || audit.source || 'governed' }}</span>
18344
- <button
18345
- class="shared-rule-cockpit__toggle"
18346
- data-testid="project-knowledge-cockpit-toggle"
18347
- type="button"
18348
- [attr.aria-expanded]="!projectKnowledgeCockpitCollapsed()"
18349
- (click)="toggleProjectKnowledgeCockpit()"
18350
- >
18351
- {{ projectKnowledgeCockpitCollapsed()
18504
+ <div class="shared-rule-cockpit__header-actions">
18505
+ <span class="shared-rule-cockpit__badge">{{ audit.citationPolicy || audit.source || 'governed' }}</span>
18506
+ <button
18507
+ class="shared-rule-cockpit__toggle"
18508
+ data-testid="project-knowledge-cockpit-toggle"
18509
+ type="button"
18510
+ [attr.aria-expanded]="!projectKnowledgeCockpitCollapsed()"
18511
+ (click)="toggleProjectKnowledgeCockpit()"
18512
+ >
18513
+ {{ projectKnowledgeCockpitCollapsed()
18352
18514
  ? tx('agentic.projectKnowledgeCockpit.expand', 'Expand')
18353
18515
  : tx('agentic.projectKnowledgeCockpit.collapse', 'Collapse') }}
18354
- </button>
18355
- </div>
18356
- </header>
18357
-
18358
- <ng-container *ngIf="!projectKnowledgeCockpitCollapsed()">
18359
- <p class="shared-rule-cockpit__description">
18360
- {{ tx('agentic.projectKnowledgeCockpit.description', 'The cockpit proposes reviewed evidence through canonical Domain Knowledge change-set endpoints. It displays only safe status summaries and does not materialize knowledge locally.') }}
18361
- </p>
18362
-
18363
- <div class="shared-rule-cockpit__actions">
18364
- <button
18365
- *ngFor="let action of projectKnowledgeGovernedContinuationActions(); trackBy: trackGovernedContinuationAction"
18366
- mat-stroked-button
18367
- type="button"
18368
- [attr.data-testid]="governedContinuationActionTestId(action)"
18369
- [attr.data-action-kind]="action.kind"
18370
- [disabled]="!action.enabled"
18371
- [matTooltip]="governedContinuationActionTooltip(action)"
18372
- (click)="runProjectKnowledgeGovernedContinuationAction(action)"
18373
- >
18374
- {{ tx(action.labelKey, action.labelFallback) }}
18375
- </button>
18376
- </div>
18377
-
18378
- <p *ngIf="projectKnowledgeCockpitBusyAction() as action" class="shared-rule-cockpit__status" data-testid="project-knowledge-cockpit-busy">
18379
- {{ tx('agentic.projectKnowledgeCockpit.running', 'Running governed Project Knowledge action') }}: {{ action }}
18380
- </p>
18381
- <p *ngIf="projectKnowledgeCockpitError()" class="shared-rule-cockpit__error" data-testid="project-knowledge-cockpit-error">
18382
- {{ projectKnowledgeCockpitError() }}
18383
- </p>
18384
-
18385
- <dl class="shared-rule-cockpit__facts">
18386
- <div>
18387
- <dt>{{ tx('agentic.projectKnowledgeCockpit.audit', 'Audit') }}</dt>
18388
- <dd data-testid="project-knowledge-cockpit-audit-status">
18389
- {{ audit.citedCount || 0 }}/{{ audit.influenceCount || 0 }} {{ tx('agentic.projectKnowledgeCockpit.cited', 'cited') }}
18390
- </dd>
18391
- </div>
18392
- <div>
18393
- <dt>{{ tx('agentic.projectKnowledgeCockpit.changeSet', 'Change-set') }}</dt>
18394
- <dd data-testid="project-knowledge-cockpit-change-set-id">{{ projectKnowledgeCockpitChangeSet()?.id || tx('agentic.sharedRuleCockpit.pending', 'pending') }}</dd>
18395
- </div>
18396
- <div>
18397
- <dt>{{ tx('agentic.projectKnowledgeCockpit.validation', 'Validation') }}</dt>
18398
- <dd data-testid="project-knowledge-cockpit-validation-status">{{ projectKnowledgeCockpitValidation()?.validationStatus || projectKnowledgeCockpitChangeSet()?.validationStatus || tx('agentic.sharedRuleCockpit.pending', 'pending') }}</dd>
18399
- </div>
18400
- <div>
18401
- <dt>{{ tx('agentic.projectKnowledgeCockpit.status', 'Status') }}</dt>
18402
- <dd data-testid="project-knowledge-cockpit-change-set-status">{{ projectKnowledgeCockpitChangeSet()?.status || tx('agentic.sharedRuleCockpit.pending', 'pending') }}</dd>
18403
- </div>
18404
- <div>
18405
- <dt>{{ tx('agentic.projectKnowledgeCockpit.safeOperations', 'Safe operations') }}</dt>
18406
- <dd data-testid="project-knowledge-cockpit-safe-operation-count">{{ projectKnowledgeCockpitChangeSet()?.safeOperationSummary?.length || 0 }}</dd>
18407
- </div>
18408
- <div>
18409
- <dt>{{ tx('agentic.projectKnowledgeCockpit.timeline', 'Safe timeline') }}</dt>
18410
- <dd data-testid="project-knowledge-cockpit-timeline-count">{{ projectKnowledgeCockpitTimeline()?.events?.length || 0 }}</dd>
18411
- </div>
18412
- </dl>
18413
-
18414
- <ol
18415
- *ngIf="projectKnowledgeTimelineItems().length; else projectKnowledgeTimelineEmpty"
18416
- class="shared-rule-cockpit__timeline"
18417
- data-testid="project-knowledge-cockpit-timeline-body"
18418
- >
18419
- <li
18420
- *ngFor="let item of projectKnowledgeTimelineItems(); trackBy: trackProjectKnowledgeTimelineItem"
18421
- class="shared-rule-cockpit__timeline-item"
18422
- >
18423
- <span class="shared-rule-cockpit__timeline-icon" aria-hidden="true">{{ item.icon || 'timeline' }}</span>
18424
- <div>
18425
- <strong>{{ item.title }}</strong>
18426
- <span *ngIf="item.badge" class="shared-rule-cockpit__timeline-badge">{{ item.badge }}</span>
18427
- <p *ngIf="item.subtitle">{{ item.subtitle }}</p>
18428
- <small *ngIf="item.meta">{{ item.meta }}</small>
18429
- <time *ngIf="item.opposite">{{ item.opposite }}</time>
18516
+ </button>
18430
18517
  </div>
18431
- </li>
18432
- </ol>
18433
- <ng-template #projectKnowledgeTimelineEmpty>
18434
- <p class="shared-rule-cockpit__timeline-empty" data-testid="project-knowledge-cockpit-timeline-empty">
18435
- {{ tx('agentic.projectKnowledgeCockpit.timelineEmpty', 'No safe timeline events published for this change-set yet.') }}
18518
+ </header>
18519
+ @if (!projectKnowledgeCockpitCollapsed()) {
18520
+ <p class="shared-rule-cockpit__description">
18521
+ {{ tx('agentic.projectKnowledgeCockpit.description', 'The cockpit proposes reviewed evidence through canonical Domain Knowledge change-set endpoints. It displays only safe status summaries and does not materialize knowledge locally.') }}
18436
18522
  </p>
18437
- </ng-template>
18438
- </ng-container>
18439
- </section>
18440
-
18523
+ <div class="shared-rule-cockpit__actions">
18524
+ @for (action of projectKnowledgeGovernedContinuationActions(); track trackGovernedContinuationAction($index, action)) {
18525
+ <button
18526
+ mat-stroked-button
18527
+ type="button"
18528
+ [attr.data-testid]="governedContinuationActionTestId(action)"
18529
+ [attr.data-action-kind]="action.kind"
18530
+ [disabled]="!action.enabled"
18531
+ [matTooltip]="governedContinuationActionTooltip(action)"
18532
+ (click)="runProjectKnowledgeGovernedContinuationAction(action)"
18533
+ >
18534
+ {{ tx(action.labelKey, action.labelFallback) }}
18535
+ </button>
18536
+ }
18537
+ </div>
18538
+ @if (projectKnowledgeCockpitBusyAction(); as action) {
18539
+ <p class="shared-rule-cockpit__status" data-testid="project-knowledge-cockpit-busy">
18540
+ {{ tx('agentic.projectKnowledgeCockpit.running', 'Running governed Project Knowledge action') }}: {{ action }}
18541
+ </p>
18542
+ }
18543
+ @if (projectKnowledgeCockpitError()) {
18544
+ <p class="shared-rule-cockpit__error" data-testid="project-knowledge-cockpit-error">
18545
+ {{ projectKnowledgeCockpitError() }}
18546
+ </p>
18547
+ }
18548
+ <dl class="shared-rule-cockpit__facts">
18549
+ <div>
18550
+ <dt>{{ tx('agentic.projectKnowledgeCockpit.audit', 'Audit') }}</dt>
18551
+ <dd data-testid="project-knowledge-cockpit-audit-status">
18552
+ {{ audit.citedCount || 0 }}/{{ audit.influenceCount || 0 }} {{ tx('agentic.projectKnowledgeCockpit.cited', 'cited') }}
18553
+ </dd>
18554
+ </div>
18555
+ <div>
18556
+ <dt>{{ tx('agentic.projectKnowledgeCockpit.changeSet', 'Change-set') }}</dt>
18557
+ <dd data-testid="project-knowledge-cockpit-change-set-id">{{ projectKnowledgeCockpitChangeSet()?.id || tx('agentic.sharedRuleCockpit.pending', 'pending') }}</dd>
18558
+ </div>
18559
+ <div>
18560
+ <dt>{{ tx('agentic.projectKnowledgeCockpit.validation', 'Validation') }}</dt>
18561
+ <dd data-testid="project-knowledge-cockpit-validation-status">{{ projectKnowledgeCockpitValidation()?.validationStatus || projectKnowledgeCockpitChangeSet()?.validationStatus || tx('agentic.sharedRuleCockpit.pending', 'pending') }}</dd>
18562
+ </div>
18563
+ <div>
18564
+ <dt>{{ tx('agentic.projectKnowledgeCockpit.status', 'Status') }}</dt>
18565
+ <dd data-testid="project-knowledge-cockpit-change-set-status">{{ projectKnowledgeCockpitChangeSet()?.status || tx('agentic.sharedRuleCockpit.pending', 'pending') }}</dd>
18566
+ </div>
18567
+ <div>
18568
+ <dt>{{ tx('agentic.projectKnowledgeCockpit.safeOperations', 'Safe operations') }}</dt>
18569
+ <dd data-testid="project-knowledge-cockpit-safe-operation-count">{{ projectKnowledgeCockpitChangeSet()?.safeOperationSummary?.length || 0 }}</dd>
18570
+ </div>
18571
+ <div>
18572
+ <dt>{{ tx('agentic.projectKnowledgeCockpit.timeline', 'Safe timeline') }}</dt>
18573
+ <dd data-testid="project-knowledge-cockpit-timeline-count">{{ projectKnowledgeCockpitTimeline()?.events?.length || 0 }}</dd>
18574
+ </div>
18575
+ </dl>
18576
+ @if (projectKnowledgeTimelineItems().length) {
18577
+ <ol
18578
+ class="shared-rule-cockpit__timeline"
18579
+ data-testid="project-knowledge-cockpit-timeline-body"
18580
+ >
18581
+ @for (item of projectKnowledgeTimelineItems(); track trackProjectKnowledgeTimelineItem($index, item)) {
18582
+ <li
18583
+ class="shared-rule-cockpit__timeline-item"
18584
+ >
18585
+ <span class="shared-rule-cockpit__timeline-icon" aria-hidden="true">{{ item.icon || 'timeline' }}</span>
18586
+ <div>
18587
+ <strong>{{ item.title }}</strong>
18588
+ @if (item.badge) {
18589
+ <span class="shared-rule-cockpit__timeline-badge">{{ item.badge }}</span>
18590
+ }
18591
+ @if (item.subtitle) {
18592
+ <p>{{ item.subtitle }}</p>
18593
+ }
18594
+ @if (item.meta) {
18595
+ <small>{{ item.meta }}</small>
18596
+ }
18597
+ @if (item.opposite) {
18598
+ <time>{{ item.opposite }}</time>
18599
+ }
18600
+ </div>
18601
+ </li>
18602
+ }
18603
+ </ol>
18604
+ } @else {
18605
+ <p class="shared-rule-cockpit__timeline-empty" data-testid="project-knowledge-cockpit-timeline-empty">
18606
+ {{ tx('agentic.projectKnowledgeCockpit.timelineEmpty', 'No safe timeline events published for this change-set yet.') }}
18607
+ </p>
18608
+ }
18609
+ }
18610
+ </section>
18611
+ }
18612
+
18441
18613
  <praxis-floating-toolbar
18442
18614
  [visible]="showSettings()"
18443
18615
  [canUndo]="false"
@@ -18448,64 +18620,68 @@ i0.ɵɵngDeclareClassMetadata({ minVersion: "12.0.0", version: "20.3.17", ngImpo
18448
18620
  (settings)="openPageSettings()"
18449
18621
  (save)="saveCurrentPage()"
18450
18622
  (preview)="togglePreview()"
18451
- >
18452
- <button
18453
- *ngIf="showPageLifecycleActions && hasPageWidgets()"
18454
- pdx-toolbar-extra
18455
- mat-mini-fab
18456
- type="button"
18457
- [attr.data-testid]="'page-builder-restart-page'"
18458
- [disabled]="pageLifecycleBusy"
18459
- [matTooltip]="tx('pageLifecycle.restart', 'Restart page')"
18460
- [attr.aria-label]="tx('pageLifecycle.restartAria', 'Restart current page locally')"
18461
- (click)="pageRestart.emit()"
18462
- >
18463
- <mat-icon [praxisIcon]="'restart_alt'"></mat-icon>
18464
- </button>
18465
- <button
18466
- *ngIf="showPageLifecycleActions && canDeleteSavedPage"
18467
- pdx-toolbar-extra
18468
- mat-mini-fab
18469
- color="warn"
18470
- type="button"
18471
- [attr.data-testid]="'page-builder-delete-saved-page'"
18472
- [disabled]="pageLifecycleBusy"
18473
- [matTooltip]="tx('pageLifecycle.deleteSaved', 'Delete saved page')"
18474
- [attr.aria-label]="tx('pageLifecycle.deleteSavedAria', 'Delete persisted page and restart')"
18475
- (click)="savedPageDeleteRequested.emit()"
18476
- >
18477
- <mat-icon [praxisIcon]="'delete'"></mat-icon>
18478
- </button>
18479
- <button
18480
- *ngIf="enableAgenticAuthoring"
18481
- pdx-toolbar-extra
18482
- mat-mini-fab
18483
- type="button"
18484
- class="builder-shell__agentic-toggle"
18485
- [class.builder-shell__agentic-toggle--open]="agenticAuthoringOpen()"
18486
- [class.builder-shell__agentic-toggle--minimized]="agenticAuthoringMinimized()"
18487
- [attr.data-testid]="'page-builder-agentic-toggle'"
18488
- [matTooltip]="agenticAuthoringToggleLabel()"
18489
- [attr.aria-label]="agenticAuthoringToggleLabel()"
18490
- (click)="toggleAgenticAuthoring()"
18491
- >
18492
- <mat-icon [praxisIcon]="'auto_awesome'"></mat-icon>
18493
- </button>
18494
- <button
18495
- *ngIf="hasPageWidgets()"
18496
- pdx-toolbar-extra
18497
- mat-mini-fab
18498
- type="button"
18499
- [attr.data-testid]="'page-builder-connections-toggle'"
18500
- [matTooltip]="tx('connections.toggle', 'Edit connections')"
18501
- [attr.aria-label]="tx('connections.toggleAria', 'Edit connections')"
18502
- (click)="toggleConnectionsViewer()"
18503
18623
  >
18504
- <mat-icon [praxisIcon]="'hub'"></mat-icon>
18505
- </button>
18624
+ @if (showPageLifecycleActions && hasPageWidgets()) {
18625
+ <button
18626
+ pdx-toolbar-extra
18627
+ mat-mini-fab
18628
+ type="button"
18629
+ [attr.data-testid]="'page-builder-restart-page'"
18630
+ [disabled]="pageLifecycleBusy"
18631
+ [matTooltip]="tx('pageLifecycle.restart', 'Restart page')"
18632
+ [attr.aria-label]="tx('pageLifecycle.restartAria', 'Restart current page locally')"
18633
+ (click)="pageRestart.emit()"
18634
+ >
18635
+ <mat-icon [praxisIcon]="'restart_alt'"></mat-icon>
18636
+ </button>
18637
+ }
18638
+ @if (showPageLifecycleActions && canDeleteSavedPage) {
18639
+ <button
18640
+ pdx-toolbar-extra
18641
+ mat-mini-fab
18642
+ color="warn"
18643
+ type="button"
18644
+ [attr.data-testid]="'page-builder-delete-saved-page'"
18645
+ [disabled]="pageLifecycleBusy"
18646
+ [matTooltip]="tx('pageLifecycle.deleteSaved', 'Delete saved page')"
18647
+ [attr.aria-label]="tx('pageLifecycle.deleteSavedAria', 'Delete persisted page and restart')"
18648
+ (click)="savedPageDeleteRequested.emit()"
18649
+ >
18650
+ <mat-icon [praxisIcon]="'delete'"></mat-icon>
18651
+ </button>
18652
+ }
18653
+ @if (enableAgenticAuthoring) {
18654
+ <button
18655
+ pdx-toolbar-extra
18656
+ mat-mini-fab
18657
+ type="button"
18658
+ class="builder-shell__agentic-toggle"
18659
+ [class.builder-shell__agentic-toggle--open]="agenticAuthoringOpen()"
18660
+ [class.builder-shell__agentic-toggle--minimized]="agenticAuthoringMinimized()"
18661
+ [attr.data-testid]="'page-builder-agentic-toggle'"
18662
+ [matTooltip]="agenticAuthoringToggleLabel()"
18663
+ [attr.aria-label]="agenticAuthoringToggleLabel()"
18664
+ (click)="toggleAgenticAuthoring()"
18665
+ >
18666
+ <mat-icon [praxisIcon]="'auto_awesome'"></mat-icon>
18667
+ </button>
18668
+ }
18669
+ @if (hasPageWidgets()) {
18670
+ <button
18671
+ pdx-toolbar-extra
18672
+ mat-mini-fab
18673
+ type="button"
18674
+ [attr.data-testid]="'page-builder-connections-toggle'"
18675
+ [matTooltip]="tx('connections.toggle', 'Edit connections')"
18676
+ [attr.aria-label]="tx('connections.toggleAria', 'Edit connections')"
18677
+ (click)="toggleConnectionsViewer()"
18678
+ >
18679
+ <mat-icon [praxisIcon]="'hub'"></mat-icon>
18680
+ </button>
18681
+ }
18506
18682
  </praxis-floating-toolbar>
18507
18683
  </div>
18508
- `, styles: [":host{display:block;position:relative;min-height:var(--pdx-page-builder-min-height, 420px)}.builder-shell{display:block;position:relative;min-height:inherit;height:100%}.builder-shell:has(.pdx-shell.fullscreen) praxis-floating-toolbar{display:none}.agentic-diagnostics-panel{position:absolute;z-index:21;right:16px;width:min(520px,calc(100% - 32px));max-height:min(440px,calc(100% - 32px));overflow:auto;padding:12px;border:1px solid rgba(107,114,128,.28);border-radius:8px;background:#fffffff5;color:#111827;box-shadow:0 14px 36px #0000003d}.agentic-diagnostics-panel--collapsed{width:min(280px,calc(100% - 32px));max-height:58px;overflow:hidden;padding:10px 12px;pointer-events:auto}.agentic-diagnostics-panel__header{display:flex;align-items:center;justify-content:space-between;gap:12px;font-size:13px;font-weight:700}.agentic-diagnostics-panel__header-actions{display:flex;align-items:center;gap:8px}.agentic-diagnostics-panel__badge{padding:2px 6px;border:1px solid rgba(107,114,128,.28);border-radius:8px;font-size:11px;font-weight:600;color:#4b5563}.agentic-diagnostics-panel__toggle,.shared-rule-cockpit__toggle{appearance:none;border:1px solid rgba(30,64,175,.18);border-radius:999px;background:#ffffffd6;color:#1e3a8a;cursor:pointer;font-size:11px;font-weight:700;line-height:1;padding:6px 9px;white-space:nowrap}.agentic-diagnostics-panel__description{margin:8px 0 10px;color:#4b5563;font-size:12px;line-height:1.4}.agentic-diagnostics-panel pre{margin:0;white-space:pre-wrap;overflow-wrap:anywhere;font-size:11px;line-height:1.45;color:#1f2937}praxis-ai-assistant-shell{position:relative;z-index:140}@media(min-width:1100px){.builder-shell--agentic-review-rail{box-sizing:border-box;padding-right:464px}}.builder-shell__agentic-toggle{position:relative}.builder-shell__agentic-toggle--open,.builder-shell__agentic-toggle--minimized{outline:2px solid rgba(96,165,250,.52);outline-offset:2px}.builder-shell__agentic-toggle--minimized:after{content:\"\";position:absolute;top:6px;right:6px;width:8px;height:8px;border:2px solid var(--md-sys-color-surface, #111827);border-radius:999px;background:#34d399}.shared-rule-cockpit{position:absolute;z-index:120;left:16px;bottom:88px;width:min(720px,calc(100% - 32px));max-height:min(560px,calc(100vh - 140px));padding:14px;border:1px solid rgba(30,64,175,.22);border-radius:12px;background:linear-gradient(135deg,#eff6fffa,#fffbebf5);color:#172554;box-shadow:0 18px 46px #0f172a38;overflow:auto;overscroll-behavior:contain}.shared-rule-cockpit--collapsed{width:min(360px,calc(100% - 32px));max-height:72px;overflow:hidden;padding:10px 12px}.shared-rule-cockpit__header{display:flex;align-items:flex-start;justify-content:space-between;gap:12px}.shared-rule-cockpit__header-actions{display:flex;align-items:center;gap:8px}.shared-rule-cockpit__header div{display:grid;gap:2px}.shared-rule-cockpit__header strong{font-size:14px;line-height:1.2}.shared-rule-cockpit__header span{color:#475569;font-size:12px;overflow-wrap:anywhere}.shared-rule-cockpit__badge{flex:0 0 auto;max-width:220px;padding:3px 8px;border:1px solid rgba(30,64,175,.2);border-radius:999px;background:#ffffffbd;color:#1e3a8a;font-size:11px;font-weight:700;overflow:hidden;text-overflow:ellipsis;white-space:nowrap}.shared-rule-cockpit__description,.shared-rule-cockpit__status,.shared-rule-cockpit__error{margin:10px 0 0;color:#334155;font-size:12px;line-height:1.45}.shared-rule-cockpit__error{color:#991b1b;font-weight:600}.shared-rule-cockpit__actions{display:flex;flex-wrap:wrap;gap:8px;margin-top:12px}.shared-rule-cockpit__facts{display:grid;grid-template-columns:repeat(3,minmax(0,1fr));gap:8px;margin:12px 0 0}.shared-rule-cockpit__facts div{min-width:0;padding:8px;border-radius:10px;background:#ffffffb8}.shared-rule-cockpit__facts dt{color:#64748b;font-size:11px;font-weight:700;text-transform:uppercase;letter-spacing:.04em}.shared-rule-cockpit__facts dd{margin:4px 0 0;color:#0f172a;font-size:12px;overflow-wrap:anywhere}.shared-rule-cockpit__enforcement-matrix{display:grid;gap:10px;margin-top:12px;padding:10px;border:1px solid rgba(30,64,175,.14);border-radius:12px;background:#ffffff94}.shared-rule-cockpit__matrix-header{display:flex;align-items:flex-start;justify-content:space-between;gap:10px}.shared-rule-cockpit__matrix-header div{display:grid;gap:2px}.shared-rule-cockpit__matrix-header strong{color:#0f172a;font-size:12px}.shared-rule-cockpit__matrix-header span,.shared-rule-cockpit__matrix-source{color:#475569;font-size:11px;line-height:1.35;overflow-wrap:anywhere}.shared-rule-cockpit__matrix-badge{flex:0 0 auto;padding:3px 8px;border-radius:999px;background:#16a34a1f;color:#166534;font-weight:800;white-space:nowrap}.shared-rule-cockpit__projection-grid{display:grid;grid-template-columns:repeat(2,minmax(0,1fr));gap:8px}.shared-rule-cockpit__projection{display:grid;gap:3px;min-width:0;padding:9px;border:1px solid rgba(15,23,42,.08);border-radius:11px;background:#f8fafcd1}.shared-rule-cockpit__projection[data-status=ready]{border-color:#16a34a33;background:#f0fdf4d1}.shared-rule-cockpit__projection span{color:#1d4ed8;font-size:10px;font-weight:800;letter-spacing:.04em;text-transform:uppercase;overflow-wrap:anywhere}.shared-rule-cockpit__projection strong{color:#0f172a;font-size:12px}.shared-rule-cockpit__projection small,.shared-rule-cockpit__projection em{color:#475569;font-size:11px;font-style:normal;overflow-wrap:anywhere}.shared-rule-cockpit__matrix-source{margin:0}.shared-rule-cockpit__timeline{display:grid;gap:8px;max-height:190px;margin:12px 0 0;padding:0;overflow:auto;list-style:none}.shared-rule-cockpit__timeline-item{display:grid;grid-template-columns:auto minmax(0,1fr);gap:10px;padding:10px;border:1px solid rgba(30,64,175,.12);border-radius:12px;background:#ffffffc2}.shared-rule-cockpit__timeline-icon{display:grid;width:24px;height:24px;place-items:center;border-radius:999px;background:#1e40af1a;color:#1e3a8a;font-family:Material Icons;font-size:16px;line-height:1}.shared-rule-cockpit__timeline-item strong{color:#0f172a;font-size:12px;line-height:1.35}.shared-rule-cockpit__timeline-item p,.shared-rule-cockpit__timeline-item small,.shared-rule-cockpit__timeline-item time,.shared-rule-cockpit__timeline-empty{display:block;margin:3px 0 0;color:#475569;font-size:11px;line-height:1.35;overflow-wrap:anywhere}.shared-rule-cockpit__timeline-badge{display:inline-flex;margin-left:6px;padding:2px 6px;border-radius:999px;background:#0ea5e91f;color:#075985;font-size:10px;font-weight:700}.shared-rule-cockpit__timeline-empty{padding:10px;border-radius:12px;background:#ffffffa3}@media(max-width:720px){.shared-rule-cockpit{bottom:72px;max-height:calc(100vh - 112px)}.shared-rule-cockpit__facts,.shared-rule-cockpit__projection-grid{grid-template-columns:1fr}}\n"] }]
18684
+ `, styles: [":host{display:block;position:relative;min-height:var(--pdx-page-builder-min-height, 420px)}.builder-shell{display:block;position:relative;min-height:inherit;height:100%}.builder-shell:has(.pdx-shell.fullscreen) praxis-floating-toolbar{display:none}.agentic-diagnostics-panel{position:absolute;z-index:21;right:16px;width:min(520px,calc(100% - 32px));max-height:min(440px,calc(100% - 32px));overflow:auto;padding:12px;border:1px solid rgba(107,114,128,.28);border-radius:8px;background:#fffffff5;color:#111827;box-shadow:0 14px 36px #0000003d}.agentic-diagnostics-panel--collapsed{width:min(280px,calc(100% - 32px));max-height:58px;overflow:hidden;padding:10px 12px;pointer-events:auto}.agentic-diagnostics-panel__header{display:flex;align-items:center;justify-content:space-between;gap:12px;font-size:13px;font-weight:700}.agentic-diagnostics-panel__header-actions{display:flex;align-items:center;gap:8px}.agentic-diagnostics-panel__badge{padding:2px 6px;border:1px solid rgba(107,114,128,.28);border-radius:8px;font-size:11px;font-weight:600;color:#4b5563}.agentic-diagnostics-panel__toggle,.shared-rule-cockpit__toggle{appearance:none;border:1px solid rgba(30,64,175,.18);border-radius:999px;background:#ffffffd6;color:#1e3a8a;cursor:pointer;font-size:11px;font-weight:700;line-height:1;padding:6px 9px;white-space:nowrap}.agentic-diagnostics-panel__description{margin:8px 0 10px;color:#4b5563;font-size:12px;line-height:1.4}.agentic-diagnostics-panel pre{margin:0;white-space:pre-wrap;overflow-wrap:anywhere;font-size:11px;line-height:1.45;color:#1f2937}praxis-ai-assistant-shell{position:relative;z-index:140}@media(min-width:1100px){.builder-shell--agentic-review-rail{box-sizing:border-box;padding-right:464px}}.builder-shell__agentic-toggle{position:relative}.builder-shell__agentic-toggle--open,.builder-shell__agentic-toggle--minimized{outline:2px solid rgba(96,165,250,.52);outline-offset:2px}.builder-shell__agentic-toggle--minimized:after{content:\"\";position:absolute;top:6px;right:6px;width:8px;height:8px;border:2px solid var(--md-sys-color-surface, #111827);border-radius:999px;background:#34d399}.shared-rule-cockpit{position:absolute;z-index:120;left:16px;bottom:88px;width:min(720px,calc(100% - 32px));max-height:min(560px,calc(100vh - 140px));padding:14px;border:1px solid rgba(30,64,175,.22);border-radius:12px;background:linear-gradient(135deg,#eff6fffa,#fffbebf5);color:#172554;box-shadow:0 18px 46px #0f172a38;overflow:auto;overscroll-behavior:contain}.shared-rule-cockpit--collapsed{width:min(360px,calc(100% - 32px));max-height:72px;overflow:hidden;padding:10px 12px}.shared-rule-cockpit__header{display:flex;align-items:flex-start;justify-content:space-between;gap:12px}.shared-rule-cockpit__header-actions{display:flex;align-items:center;gap:8px}.shared-rule-cockpit__header div{display:grid;gap:2px}.shared-rule-cockpit__header strong{font-size:14px;line-height:1.2}.shared-rule-cockpit__header span{color:#475569;font-size:12px;overflow-wrap:anywhere}.shared-rule-cockpit__badge{flex:0 0 auto;max-width:220px;padding:3px 8px;border:1px solid rgba(30,64,175,.2);border-radius:999px;background:#ffffffbd;color:#1e3a8a;font-size:11px;font-weight:700;overflow:hidden;text-overflow:ellipsis;white-space:nowrap}.shared-rule-cockpit__description,.shared-rule-cockpit__status,.shared-rule-cockpit__error{margin:10px 0 0;color:#334155;font-size:12px;line-height:1.45}.shared-rule-cockpit__error{color:#991b1b;font-weight:600}.shared-rule-cockpit__actions{display:flex;flex-wrap:wrap;gap:8px;margin-top:12px}.shared-rule-cockpit__facts{display:grid;grid-template-columns:repeat(3,minmax(0,1fr));gap:8px;margin:12px 0 0}.shared-rule-cockpit__facts div{min-width:0;padding:8px;border-radius:10px;background:#ffffffb8}.shared-rule-cockpit__facts dt{color:#64748b;font-size:11px;font-weight:700;text-transform:uppercase;letter-spacing:.04em}.shared-rule-cockpit__facts dd{margin:4px 0 0;color:#0f172a;font-size:12px;overflow-wrap:anywhere}.shared-rule-cockpit__enforcement-matrix{display:grid;gap:10px;margin-top:12px;padding:10px;border:1px solid rgba(30,64,175,.14);border-radius:12px;background:#ffffff94}.shared-rule-cockpit__matrix-header{display:flex;align-items:flex-start;justify-content:space-between;gap:10px}.shared-rule-cockpit__matrix-header div{display:grid;gap:2px}.shared-rule-cockpit__matrix-header strong{color:#0f172a;font-size:12px}.shared-rule-cockpit__matrix-header span,.shared-rule-cockpit__matrix-source{color:#475569;font-size:11px;line-height:1.35;overflow-wrap:anywhere}.shared-rule-cockpit__matrix-badge{flex:0 0 auto;padding:3px 8px;border-radius:999px;background:#16a34a1f;color:#166534;font-weight:800;white-space:nowrap}.shared-rule-cockpit__projection-grid{display:grid;grid-template-columns:repeat(2,minmax(0,1fr));gap:8px}.shared-rule-cockpit__projection{display:grid;gap:3px;min-width:0;padding:9px;border:1px solid rgba(15,23,42,.08);border-radius:11px;background:#f8fafcd1}.shared-rule-cockpit__projection[data-status=ready]{border-color:#16a34a33;background:#f0fdf4d1}.shared-rule-cockpit__projection span{color:#1d4ed8;font-size:10px;font-weight:800;letter-spacing:.04em;text-transform:uppercase;overflow-wrap:anywhere}.shared-rule-cockpit__projection strong{color:#0f172a;font-size:12px}.shared-rule-cockpit__projection small,.shared-rule-cockpit__projection em{color:#475569;font-size:11px;font-style:normal;overflow-wrap:anywhere}.shared-rule-cockpit__matrix-source{margin:0}.shared-rule-cockpit__timeline{display:grid;gap:8px;max-height:190px;margin:12px 0 0;padding:0;overflow:auto;list-style:none}.shared-rule-cockpit__timeline-item{display:grid;grid-template-columns:auto minmax(0,1fr);gap:10px;padding:10px;border:1px solid rgba(30,64,175,.12);border-radius:12px;background:#ffffffc2}.shared-rule-cockpit__timeline-icon{display:grid;width:24px;height:24px;place-items:center;border-radius:999px;background:#1e40af1a;color:#1e3a8a;font-family:Material Icons;font-size:16px;line-height:1}.shared-rule-cockpit__timeline-item strong{color:#0f172a;font-size:12px;line-height:1.35}.shared-rule-cockpit__timeline-item p,.shared-rule-cockpit__timeline-item small,.shared-rule-cockpit__timeline-item time,.shared-rule-cockpit__timeline-empty{display:block;margin:3px 0 0;color:#475569;font-size:11px;line-height:1.35;overflow-wrap:anywhere}.shared-rule-cockpit__timeline-badge{display:inline-flex;margin-left:6px;padding:2px 6px;border-radius:999px;background:#0ea5e91f;color:#075985;font-size:10px;font-weight:700}.shared-rule-cockpit__timeline-empty{padding:10px;border-radius:12px;background:#ffffffa3}@media(max-width:720px){.shared-rule-cockpit{bottom:72px;max-height:calc(100vh - 112px)}.shared-rule-cockpit__facts,.shared-rule-cockpit__projection-grid{grid-template-columns:1fr}}\n"] }]
18509
18685
  }], ctorParameters: () => [{ type: i1.MatDialog }, { type: undefined, decorators: [{
18510
18686
  type: Optional
18511
18687
  }, {