@praxisui/page-builder 8.0.0-beta.30 → 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">
@@ -11253,31 +11396,25 @@ class PageBuilderAgenticAuthoringService {
11253
11396
  let source = null;
11254
11397
  let closed = false;
11255
11398
  let streamTimeout = null;
11256
- let connectionErrorTimer = null;
11257
- const connectionErrorGraceMs = Math.max(0, this.options?.streamConnectionErrorGraceMs ?? 1500);
11258
11399
  const streamTimeoutMs = this.streamTurnTimeoutMs();
11259
11400
  let probeAbort = typeof AbortController !== 'undefined'
11260
11401
  ? new AbortController()
11261
11402
  : null;
11403
+ let streamAbort = null;
11262
11404
  const clearStreamTimeout = () => {
11263
11405
  if (streamTimeout) {
11264
11406
  clearTimeout(streamTimeout);
11265
11407
  streamTimeout = null;
11266
11408
  }
11267
11409
  };
11268
- const clearConnectionErrorTimer = () => {
11269
- if (connectionErrorTimer) {
11270
- clearTimeout(connectionErrorTimer);
11271
- connectionErrorTimer = null;
11272
- }
11273
- };
11274
11410
  const closeSource = () => {
11275
11411
  if (closed) {
11276
11412
  return;
11277
11413
  }
11278
11414
  closed = true;
11279
11415
  clearStreamTimeout();
11280
- clearConnectionErrorTimer();
11416
+ streamAbort?.abort();
11417
+ streamAbort = null;
11281
11418
  source?.close();
11282
11419
  };
11283
11420
  streamTimeout = setTimeout(() => {
@@ -11291,26 +11428,20 @@ class PageBuilderAgenticAuthoringService {
11291
11428
  });
11292
11429
  closeSource();
11293
11430
  }, streamTimeoutMs);
11294
- const failConnection = (event) => {
11295
- if (closed) {
11296
- return;
11297
- }
11298
- observer.error(this.streamConnectionError(event));
11299
- closeSource();
11300
- };
11301
11431
  const handleMessage = (event) => {
11432
+ let parsed;
11302
11433
  try {
11303
- clearConnectionErrorTimer();
11304
- const parsed = JSON.parse(event.data);
11305
- observer.next(parsed);
11306
- if (parsed.type === 'result' || parsed.type === 'error' || parsed.type === 'cancelled') {
11307
- observer.complete();
11308
- closeSource();
11309
- }
11434
+ parsed = JSON.parse(event.data);
11310
11435
  }
11311
11436
  catch (error) {
11312
11437
  observer.error(this.streamConnectionError(error));
11313
11438
  closeSource();
11439
+ return;
11440
+ }
11441
+ observer.next(parsed);
11442
+ if (parsed.type === 'result' || parsed.type === 'error' || parsed.type === 'cancelled') {
11443
+ observer.complete();
11444
+ closeSource();
11314
11445
  }
11315
11446
  };
11316
11447
  void this.probeTurnStreamEndpoint(probeUrl, probeAbort)
@@ -11324,6 +11455,17 @@ class PageBuilderAgenticAuthoringService {
11324
11455
  observer.error(this.streamConnectionError({ status }));
11325
11456
  return;
11326
11457
  }
11458
+ if (!this.options?.eventSourceFactory && typeof fetch === 'function' && typeof TextDecoder !== 'undefined') {
11459
+ streamAbort = typeof AbortController !== 'undefined' ? new AbortController() : null;
11460
+ void this.consumeFetchTurnStream(url, streamAbort, handleMessage, () => closed).catch((error) => {
11461
+ if (closed) {
11462
+ return;
11463
+ }
11464
+ observer.error(this.streamConnectionError(error));
11465
+ closeSource();
11466
+ });
11467
+ return;
11468
+ }
11327
11469
  try {
11328
11470
  source = this.createEventSource(url);
11329
11471
  }
@@ -11339,14 +11481,13 @@ class PageBuilderAgenticAuthoringService {
11339
11481
  }
11340
11482
  }
11341
11483
  source.onerror = (event) => {
11342
- if (closed || connectionErrorTimer) {
11484
+ if (closed) {
11343
11485
  return;
11344
11486
  }
11345
- if (connectionErrorGraceMs === 0) {
11346
- failConnection(event);
11347
- return;
11487
+ if (source?.readyState === EventSource.CLOSED) {
11488
+ observer.error(this.streamConnectionError(event));
11489
+ closeSource();
11348
11490
  }
11349
- connectionErrorTimer = setTimeout(() => failConnection(event), connectionErrorGraceMs);
11350
11491
  };
11351
11492
  })
11352
11493
  .catch((error) => {
@@ -11364,17 +11505,80 @@ class PageBuilderAgenticAuthoringService {
11364
11505
  return;
11365
11506
  }
11366
11507
  closed = true;
11508
+ streamAbort?.abort();
11509
+ streamAbort = null;
11367
11510
  clearStreamTimeout();
11368
- clearConnectionErrorTimer();
11369
11511
  };
11370
11512
  });
11371
11513
  }
11372
- streamStartTimeoutMs() {
11373
- return Math.max(1, this.options?.streamStartTimeoutMs ?? DEFAULT_TURN_STREAM_START_TIMEOUT_MS);
11374
- }
11375
- streamTurnTimeoutMs() {
11376
- return Math.max(1, this.options?.streamTurnTimeoutMs ?? DEFAULT_TURN_STREAM_TIMEOUT_MS);
11377
- }
11514
+ async consumeFetchTurnStream(url, abort, handleMessage, closed) {
11515
+ const response = await fetch(url, {
11516
+ method: 'GET',
11517
+ headers: { Accept: 'text/event-stream' },
11518
+ credentials: 'include',
11519
+ cache: 'no-store',
11520
+ signal: abort?.signal,
11521
+ });
11522
+ if (!response.ok) {
11523
+ throw { status: response.status };
11524
+ }
11525
+ if (!response.body) {
11526
+ throw new Error('Agentic authoring stream response does not expose a readable body.');
11527
+ }
11528
+ const reader = response.body.getReader();
11529
+ const decoder = new TextDecoder();
11530
+ let buffer = '';
11531
+ try {
11532
+ while (!closed()) {
11533
+ const { value, done } = await reader.read();
11534
+ if (done) {
11535
+ break;
11536
+ }
11537
+ buffer += decoder.decode(value, { stream: true });
11538
+ buffer = this.consumeBufferedSseFrames(buffer, handleMessage);
11539
+ }
11540
+ buffer += decoder.decode();
11541
+ this.consumeBufferedSseFrames(`${buffer}\n\n`, handleMessage);
11542
+ }
11543
+ finally {
11544
+ reader.releaseLock();
11545
+ }
11546
+ }
11547
+ consumeBufferedSseFrames(buffer, handleMessage) {
11548
+ let remaining = buffer;
11549
+ let boundary = this.findSseFrameBoundary(remaining);
11550
+ while (boundary) {
11551
+ const frame = remaining.slice(0, boundary.index);
11552
+ remaining = remaining.slice(boundary.index + boundary.length);
11553
+ const data = frame
11554
+ .split(/\r?\n/)
11555
+ .filter((line) => line.startsWith('data:'))
11556
+ .map((line) => line.slice(5).trimStart())
11557
+ .join('\n');
11558
+ if (data) {
11559
+ handleMessage({ data });
11560
+ }
11561
+ boundary = this.findSseFrameBoundary(remaining);
11562
+ }
11563
+ return remaining;
11564
+ }
11565
+ findSseFrameBoundary(buffer) {
11566
+ const lf = buffer.indexOf('\n\n');
11567
+ const crlf = buffer.indexOf('\r\n\r\n');
11568
+ if (lf < 0 && crlf < 0) {
11569
+ return null;
11570
+ }
11571
+ if (lf >= 0 && (crlf < 0 || lf < crlf)) {
11572
+ return { index: lf, length: 2 };
11573
+ }
11574
+ return { index: crlf, length: 4 };
11575
+ }
11576
+ streamStartTimeoutMs() {
11577
+ return Math.max(1, this.options?.streamStartTimeoutMs ?? DEFAULT_TURN_STREAM_START_TIMEOUT_MS);
11578
+ }
11579
+ streamTurnTimeoutMs() {
11580
+ return Math.max(1, this.options?.streamTurnTimeoutMs ?? DEFAULT_TURN_STREAM_TIMEOUT_MS);
11581
+ }
11378
11582
  requestTimeoutMs() {
11379
11583
  return Math.max(1, this.options?.requestTimeoutMs ?? DEFAULT_AGENTIC_AUTHORING_REQUEST_TIMEOUT_MS);
11380
11584
  }
@@ -11460,10 +11664,10 @@ class PageBuilderAgenticAuthoringService {
11460
11664
  }
11461
11665
  return [];
11462
11666
  }
11463
- static ɵfac = i0.ɵɵngDeclareFactory({ minVersion: "12.0.0", version: "20.3.17", ngImport: i0, type: PageBuilderAgenticAuthoringService, deps: [], target: i0.ɵɵFactoryTarget.Injectable });
11464
- 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' });
11465
11669
  }
11466
- 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: [{
11467
11671
  type: Injectable,
11468
11672
  args: [{ providedIn: 'root' }]
11469
11673
  }] });
@@ -15025,48 +15229,48 @@ class DynamicPageBuilderComponent {
15025
15229
  agenticAuthoringSharedRuleHandoff = new EventEmitter();
15026
15230
  pageRestart = new EventEmitter();
15027
15231
  savedPageDeleteRequested = new EventEmitter();
15028
- currentPage = signal({ widgets: [] }, ...(ngDevMode ? [{ debugName: "currentPage" }] : []));
15029
- hasPageWidgets = computed(() => (this.currentPage().widgets || []).length > 0, ...(ngDevMode ? [{ debugName: "hasPageWidgets" }] : []));
15030
- connectionsViewerOpen = signal(false, ...(ngDevMode ? [{ debugName: "connectionsViewerOpen" }] : []));
15031
- agenticAuthoringOpen = signal(false, ...(ngDevMode ? [{ debugName: "agenticAuthoringOpen" }] : []));
15032
- agenticAuthoringPrompt = signal('', ...(ngDevMode ? [{ debugName: "agenticAuthoringPrompt" }] : []));
15033
- agenticAuthoringBusy = signal(false, ...(ngDevMode ? [{ debugName: "agenticAuthoringBusy" }] : []));
15034
- agenticAuthoringStatus = signal('', ...(ngDevMode ? [{ debugName: "agenticAuthoringStatus" }] : []));
15035
- agenticAuthoringError = signal('', ...(ngDevMode ? [{ debugName: "agenticAuthoringError" }] : []));
15036
- agenticAuthoringPreviewResult = signal(null, ...(ngDevMode ? [{ debugName: "agenticAuthoringPreviewResult" }] : []));
15037
- agenticAuthoringSemanticDecision = signal(null, ...(ngDevMode ? [{ debugName: "agenticAuthoringSemanticDecision" }] : []));
15038
- agenticAuthoringCanApply = signal(false, ...(ngDevMode ? [{ debugName: "agenticAuthoringCanApply" }] : []));
15039
- agenticAuthoringLastEtag = signal(null, ...(ngDevMode ? [{ debugName: "agenticAuthoringLastEtag" }] : []));
15040
- agenticAuthoringConversation = signal([], ...(ngDevMode ? [{ debugName: "agenticAuthoringConversation" }] : []));
15041
- agenticAuthoringQuickReplies = signal([], ...(ngDevMode ? [{ debugName: "agenticAuthoringQuickReplies" }] : []));
15042
- agenticAuthoringAttachments = signal([], ...(ngDevMode ? [{ debugName: "agenticAuthoringAttachments" }] : []));
15043
- agenticAuthoringSharedRuleHandoffState = signal(null, ...(ngDevMode ? [{ debugName: "agenticAuthoringSharedRuleHandoffState" }] : []));
15044
- sharedRuleCockpitBusyAction = signal(null, ...(ngDevMode ? [{ debugName: "sharedRuleCockpitBusyAction" }] : []));
15045
- sharedRuleCockpitError = signal('', ...(ngDevMode ? [{ debugName: "sharedRuleCockpitError" }] : []));
15046
- sharedRuleCockpitDefinition = signal(null, ...(ngDevMode ? [{ debugName: "sharedRuleCockpitDefinition" }] : []));
15047
- sharedRuleCockpitSimulation = signal(null, ...(ngDevMode ? [{ debugName: "sharedRuleCockpitSimulation" }] : []));
15048
- sharedRuleCockpitTimeline = signal(null, ...(ngDevMode ? [{ debugName: "sharedRuleCockpitTimeline" }] : []));
15049
- sharedRuleCockpitPublication = signal(null, ...(ngDevMode ? [{ debugName: "sharedRuleCockpitPublication" }] : []));
15050
- sharedRuleCockpitMaterializations = signal([], ...(ngDevMode ? [{ debugName: "sharedRuleCockpitMaterializations" }] : []));
15051
- sharedRuleCockpitEnforcement = signal(null, ...(ngDevMode ? [{ debugName: "sharedRuleCockpitEnforcement" }] : []));
15052
- projectKnowledgeCockpitBusyAction = signal(null, ...(ngDevMode ? [{ debugName: "projectKnowledgeCockpitBusyAction" }] : []));
15053
- projectKnowledgeCockpitError = signal('', ...(ngDevMode ? [{ debugName: "projectKnowledgeCockpitError" }] : []));
15054
- projectKnowledgeCockpitChangeSet = signal(null, ...(ngDevMode ? [{ debugName: "projectKnowledgeCockpitChangeSet" }] : []));
15055
- projectKnowledgeCockpitValidation = signal(null, ...(ngDevMode ? [{ debugName: "projectKnowledgeCockpitValidation" }] : []));
15056
- projectKnowledgeCockpitTimeline = signal(null, ...(ngDevMode ? [{ debugName: "projectKnowledgeCockpitTimeline" }] : []));
15057
- agenticAuthoringLlmDiagnostics = signal(null, ...(ngDevMode ? [{ debugName: "agenticAuthoringLlmDiagnostics" }] : []));
15058
- agenticAuthoringLlmDiagnosticsCollapsed = signal(true, ...(ngDevMode ? [{ debugName: "agenticAuthoringLlmDiagnosticsCollapsed" }] : []));
15059
- sharedRuleCockpitCollapsed = signal(false, ...(ngDevMode ? [{ debugName: "sharedRuleCockpitCollapsed" }] : []));
15060
- projectKnowledgeCockpitCollapsed = signal(true, ...(ngDevMode ? [{ debugName: "projectKnowledgeCockpitCollapsed" }] : []));
15061
- agenticAuthoringEditingMessageId = signal(null, ...(ngDevMode ? [{ debugName: "agenticAuthoringEditingMessageId" }] : []));
15062
- selectedWidgetKey = signal(null, ...(ngDevMode ? [{ debugName: "selectedWidgetKey" }] : []));
15063
- 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 */ []));
15064
15268
  agenticAuthoringPanelLayout = signal(createPraxisAssistantViewportLayout({
15065
15269
  width: 440,
15066
15270
  height: 620,
15067
15271
  top: 96,
15068
15272
  margin: 24,
15069
- }), ...(ngDevMode ? [{ debugName: "agenticAuthoringPanelLayout" }] : []));
15273
+ }), ...(ngDevMode ? [{ debugName: "agenticAuthoringPanelLayout" }] : /* istanbul ignore next */ []));
15070
15274
  previewMode = false;
15071
15275
  agenticComponentCapabilities;
15072
15276
  agenticComponentCapabilitiesPromise;
@@ -17609,15 +17813,15 @@ class DynamicPageBuilderComponent {
17609
17813
  tx(key, fallback) {
17610
17814
  return resolvePraxisPageBuilderText(this.i18n, key, fallback);
17611
17815
  }
17612
- 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 });
17613
- 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: [
17614
17818
  providePraxisPageBuilderI18n(),
17615
17819
  { provide: DYNAMIC_PAGE_SHELL_EDITOR, useValue: WidgetShellEditorComponent },
17616
17820
  ], viewQueries: [{ propertyName: "runtime", first: true, predicate: ["runtime"], descendants: true }], usesOnChanges: true, ngImport: i0, template: `
17617
17821
  <div
17618
17822
  class="builder-shell"
17619
17823
  [class.builder-shell--agentic-review-rail]="agenticAuthoringReviewRailActive()"
17620
- >
17824
+ >
17621
17825
  <praxis-dynamic-page
17622
17826
  #runtime
17623
17827
  [page]="currentPage()"
@@ -17634,325 +17838,338 @@ class DynamicPageBuilderComponent {
17634
17838
  (widgetEvent)="onRuntimeWidgetEvent($event)"
17635
17839
  (widgetSelectionChange)="onRuntimeWidgetSelectionChange($event)"
17636
17840
  (widgetAssistantRequested)="openAgenticAuthoringForWidget($event)"
17637
- />
17638
-
17841
+ />
17842
+
17639
17843
  <praxis-connection-editor
17640
17844
  [open]="showSettings() && connectionsViewerOpen()"
17641
17845
  [page]="currentPage()"
17642
17846
  (pageChange)="onConnectionEditorPageChange($event)"
17643
17847
  (focusWidget)="focusCanvasWidget($event)"
17644
17848
  (openPageSettings)="openPageSettings()"
17645
- />
17646
-
17647
- <praxis-ai-assistant-shell
17648
- *ngIf="showSettings() && enableAgenticAuthoring && agenticAuthoringOpen()"
17649
- panelTestId="page-builder-agentic-authoring-panel"
17650
- testIdPrefix="page-builder-agentic"
17651
- submitTestId="page-builder-agentic-preview"
17652
- applyTestId="page-builder-agentic-persist"
17653
- [labels]="agenticAuthoringShellLabels()"
17654
- mode="agentic-authoring"
17655
- [state]="agenticAuthoringShellState()"
17656
- [contextItems]="agenticAuthoringContextItems()"
17657
- [attachments]="agenticAuthoringAttachments()"
17658
- [messages]="agenticAuthoringConversation()"
17659
- [quickReplies]="agenticAuthoringQuickReplies()"
17660
- [prompt]="agenticAuthoringPrompt()"
17661
- [statusText]="agenticAuthoringStatus()"
17662
- [errorText]="agenticAuthoringError()"
17663
- [busy]="agenticAuthoringBusy()"
17664
- [canApply]="agenticAuthoringCanApply()"
17665
- [primaryAction]="agenticAuthoringSubmitAction()"
17666
- [showAttachAction]="false"
17667
- [enablePastedAttachments]="false"
17668
- [layout]="agenticAuthoringPanelLayout()"
17669
- [minWidth]="320"
17670
- [minHeight]="280"
17671
- [margin]="8"
17672
- (promptChange)="agenticAuthoringPrompt.set($event)"
17673
- (submitPrompt)="agenticAuthoringPrompt.set($event); previewAgenticAuthoring()"
17674
- (apply)="persistAgenticAuthoring()"
17675
- (retryTurn)="retryAgenticAuthoring()"
17676
- (cancelTurn)="cancelAgenticAuthoring()"
17677
- (quickReply)="submitAgenticQuickReply($event)"
17678
- (attach)="attachAgenticContext()"
17679
- (removeAttachment)="removeAgenticAttachment($event)"
17680
- (editMessage)="editAgenticMessage($event)"
17681
- (resendMessage)="resendAgenticMessage($event)"
17682
- (layoutChange)="onAgenticAuthoringLayoutChange($event)"
17683
- (close)="minimizeAgenticAuthoring()"
17684
- />
17685
-
17686
- <section
17687
- *ngIf="agenticAuthoringIncludeLlmDiagnostics && agenticAuthoringLlmDiagnosticsText()"
17688
- class="agentic-diagnostics-panel"
17689
- [class.agentic-diagnostics-panel--collapsed]="agenticAuthoringLlmDiagnosticsCollapsed()"
17690
- data-testid="page-builder-agentic-llm-diagnostics"
17691
- role="region"
17692
- [attr.aria-label]="tx('agentic.diagnostics.title', 'LLM diagnostics')"
17693
- [style.top.px]="agenticAuthoringDiagnosticsTop()"
17694
- >
17695
- <header class="agentic-diagnostics-panel__header">
17696
- <span>{{ tx('agentic.diagnostics.title', 'LLM diagnostics') }}</span>
17697
- <div class="agentic-diagnostics-panel__header-actions">
17698
- <span class="agentic-diagnostics-panel__badge">
17699
- {{ tx('agentic.diagnostics.badge', 'Debug') }}
17700
- </span>
17701
- <button
17702
- class="agentic-diagnostics-panel__toggle"
17703
- data-testid="page-builder-agentic-llm-diagnostics-toggle"
17704
- type="button"
17705
- [attr.aria-expanded]="!agenticAuthoringLlmDiagnosticsCollapsed()"
17706
- (click)="toggleAgenticAuthoringLlmDiagnostics()"
17707
- >
17708
- {{ 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()
17709
17914
  ? tx('agentic.diagnostics.expand', 'Expand')
17710
17915
  : tx('agentic.diagnostics.collapse', 'Collapse') }}
17711
- </button>
17712
- </div>
17713
- </header>
17714
- <ng-container *ngIf="!agenticAuthoringLlmDiagnosticsCollapsed()">
17715
- <p class="agentic-diagnostics-panel__description">
17716
- {{ tx('agentic.diagnostics.description', 'Prompt, context bundle, and tool catalog returned by the backend for this turn.') }}
17717
- </p>
17718
- <pre>{{ agenticAuthoringLlmDiagnosticsText() }}</pre>
17719
- </ng-container>
17720
- </section>
17721
-
17722
- <section
17723
- *ngIf="agenticAuthoringSharedRuleHandoffState() as handoff"
17724
- class="shared-rule-cockpit"
17725
- [class.shared-rule-cockpit--collapsed]="sharedRuleCockpitCollapsed()"
17726
- data-testid="page-builder-shared-rule-cockpit"
17727
- role="region"
17728
- [attr.aria-label]="tx('agentic.sharedRuleCockpit.title', 'Shared-rule governed actions')"
17729
- >
17730
- <header class="shared-rule-cockpit__header">
17731
- <div>
17732
- <strong>{{ tx('agentic.sharedRuleCockpit.title', 'Shared-rule governed actions') }}</strong>
17733
- <span>{{ handoff.ruleKey || handoff.recommendedRuleType || handoff.flowId }}</span>
17734
- </div>
17735
- <div class="shared-rule-cockpit__header-actions">
17736
- <span class="shared-rule-cockpit__badge">{{ handoff.routeGateStatus || handoff.previewDisposition }}</span>
17737
- <button
17738
- class="shared-rule-cockpit__toggle"
17739
- data-testid="shared-rule-cockpit-toggle"
17740
- type="button"
17741
- [attr.aria-expanded]="!sharedRuleCockpitCollapsed()"
17742
- (click)="toggleSharedRuleCockpit()"
17743
- >
17744
- {{ 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()
17745
17951
  ? tx('agentic.sharedRuleCockpit.expand', 'Expand')
17746
17952
  : tx('agentic.sharedRuleCockpit.collapse', 'Collapse') }}
17747
- </button>
17748
- </div>
17749
- </header>
17750
-
17751
- <ng-container *ngIf="!sharedRuleCockpitCollapsed()">
17752
- <p class="shared-rule-cockpit__description">
17753
- {{ 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.') }}
17754
- </p>
17755
-
17756
- <div class="shared-rule-cockpit__actions">
17757
- <button
17758
- *ngFor="let action of sharedRuleGovernedContinuationActions(); trackBy: trackGovernedContinuationAction"
17759
- mat-stroked-button
17760
- type="button"
17761
- [attr.data-testid]="governedContinuationActionTestId(action)"
17762
- [attr.data-action-kind]="action.kind"
17763
- [disabled]="!action.enabled"
17764
- [matTooltip]="governedContinuationActionTooltip(action)"
17765
- (click)="runSharedRuleGovernedContinuationAction(action)"
17766
- >
17767
- {{ tx(action.labelKey, action.labelFallback) }}
17768
- </button>
17769
- </div>
17770
-
17771
- <p *ngIf="sharedRuleCockpitBusyAction() as action" class="shared-rule-cockpit__status" data-testid="shared-rule-cockpit-busy">
17772
- {{ tx('agentic.sharedRuleCockpit.running', 'Running governed action') }}: {{ action }}
17773
- </p>
17774
- <p *ngIf="sharedRuleCockpitError()" class="shared-rule-cockpit__error" data-testid="shared-rule-cockpit-error">
17775
- {{ sharedRuleCockpitError() }}
17776
- </p>
17777
-
17778
- <dl class="shared-rule-cockpit__facts">
17779
- <div>
17780
- <dt>{{ tx('agentic.sharedRuleCockpit.definitionId', 'Definition') }}</dt>
17781
- <dd data-testid="shared-rule-cockpit-definition-id">{{ handoff.ruleDefinitionId || tx('agentic.sharedRuleCockpit.pending', 'pending') }}</dd>
17782
- </div>
17783
- <div>
17784
- <dt>{{ tx('agentic.sharedRuleCockpit.simulation', 'Simulation') }}</dt>
17785
- <dd data-testid="shared-rule-cockpit-simulation-result">{{ sharedRuleCockpitSimulation()?.result || tx('agentic.sharedRuleCockpit.pending', 'pending') }}</dd>
17786
- </div>
17787
- <div>
17788
- <dt>{{ tx('agentic.sharedRuleCockpit.publication', 'Publication') }}</dt>
17789
- <dd data-testid="shared-rule-cockpit-publication-status">{{ sharedRuleCockpitPublication()?.publicationStatus || tx('agentic.sharedRuleCockpit.pending', 'pending') }}</dd>
17790
- </div>
17791
- <div>
17792
- <dt>{{ tx('agentic.sharedRuleCockpit.materializations', 'Materializations') }}</dt>
17793
- <dd data-testid="shared-rule-cockpit-materialization-count">{{ sharedRuleCockpitMaterializations().length }}</dd>
17794
- </div>
17795
- <div>
17796
- <dt>{{ tx('agentic.sharedRuleCockpit.timeline', 'Governed timeline') }}</dt>
17797
- <dd data-testid="shared-rule-cockpit-timeline-count">{{ sharedRuleCockpitTimeline()?.events?.length || 0 }}</dd>
17798
- </div>
17799
- <div>
17800
- <dt>{{ tx('agentic.sharedRuleCockpit.enforcementState', 'Runtime enforcement') }}</dt>
17801
- <dd data-testid="shared-rule-cockpit-enforcement-status">{{ sharedRuleCockpitEnforcement()?.status || tx('agentic.sharedRuleCockpit.pending', 'pending') }}</dd>
17802
- </div>
17803
- </dl>
17804
-
17805
- <section
17806
- *ngIf="sharedRuleCockpitEnforcement() as enforcement"
17807
- class="shared-rule-cockpit__enforcement-matrix"
17808
- data-testid="shared-rule-cockpit-enforcement-matrix"
17809
- [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')"
17810
18058
  >
17811
- <header class="shared-rule-cockpit__matrix-header">
18059
+ <header class="shared-rule-cockpit__header">
17812
18060
  <div>
17813
- <strong>{{ tx('agentic.sharedRuleCockpit.enforcementMatrix', 'Runtime enforcement matrix') }}</strong>
17814
- <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>
17815
18063
  </div>
17816
- <span class="shared-rule-cockpit__matrix-badge" data-testid="shared-rule-cockpit-enforcement-counts">
17817
- {{ enforcement.appliedCount }} {{ tx('agentic.sharedRuleCockpit.applied', 'applied') }} /
17818
- {{ enforcement.pendingCount }} {{ tx('agentic.sharedRuleCockpit.waiting', 'waiting') }}
17819
- </span>
17820
- </header>
17821
-
17822
- <div class="shared-rule-cockpit__projection-grid">
17823
- <article
17824
- *ngFor="let projection of enforcement.projections; trackBy: trackSharedRuleEnforcementProjection"
17825
- class="shared-rule-cockpit__projection"
17826
- [attr.data-status]="projection.status"
17827
- data-testid="shared-rule-cockpit-enforcement-projection"
17828
- >
17829
- <span data-testid="shared-rule-cockpit-enforcement-layer">{{ projection.targetLayer }}</span>
17830
- <strong>{{ projection.targetLayerLabel }}</strong>
17831
- <small>{{ projection.targetArtifact || tx('agentic.sharedRuleCockpit.artifactPending', 'artifact pending') }}</small>
17832
- <em>{{ projection.sourceHash || tx('agentic.sharedRuleCockpit.sourceHashPending', 'source hash pending') }}</em>
17833
- </article>
17834
- </div>
17835
-
17836
- <p class="shared-rule-cockpit__matrix-source" data-testid="shared-rule-cockpit-enforcement-sourcehash">
17837
- <strong>{{ tx('agentic.sharedRuleCockpit.sourceHashes', 'Source hashes') }}:</strong>
17838
- {{ enforcement.sourceHashes.length ? enforcement.sourceHashes.join(', ') : tx('agentic.sharedRuleCockpit.sourceHashPending', 'source hash pending') }}
17839
- </p>
17840
- </section>
17841
- </ng-container>
17842
- </section>
17843
-
17844
- <section
17845
- *ngIf="agenticAuthoringProjectKnowledgeAudit() as audit"
17846
- class="project-knowledge-cockpit shared-rule-cockpit"
17847
- [class.shared-rule-cockpit--collapsed]="projectKnowledgeCockpitCollapsed()"
17848
- data-testid="page-builder-project-knowledge-cockpit"
17849
- role="region"
17850
- [attr.aria-label]="tx('agentic.projectKnowledgeCockpit.title', 'Project Knowledge governed actions')"
17851
- >
17852
- <header class="shared-rule-cockpit__header">
17853
- <div>
17854
- <strong>{{ tx('agentic.projectKnowledgeCockpit.title', 'Project Knowledge governed actions') }}</strong>
17855
- <span>{{ tx('agentic.projectKnowledgeCockpit.subtitle', 'Continue cited knowledge as a governed Domain Knowledge change-set.') }}</span>
17856
- </div>
17857
- <div class="shared-rule-cockpit__header-actions">
17858
- <span class="shared-rule-cockpit__badge">{{ audit.citationPolicy || audit.source || 'governed' }}</span>
17859
- <button
17860
- class="shared-rule-cockpit__toggle"
17861
- data-testid="project-knowledge-cockpit-toggle"
17862
- type="button"
17863
- [attr.aria-expanded]="!projectKnowledgeCockpitCollapsed()"
17864
- (click)="toggleProjectKnowledgeCockpit()"
17865
- >
17866
- {{ 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()
17867
18074
  ? tx('agentic.projectKnowledgeCockpit.expand', 'Expand')
17868
18075
  : tx('agentic.projectKnowledgeCockpit.collapse', 'Collapse') }}
17869
- </button>
17870
- </div>
17871
- </header>
17872
-
17873
- <ng-container *ngIf="!projectKnowledgeCockpitCollapsed()">
17874
- <p class="shared-rule-cockpit__description">
17875
- {{ 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.') }}
17876
- </p>
17877
-
17878
- <div class="shared-rule-cockpit__actions">
17879
- <button
17880
- *ngFor="let action of projectKnowledgeGovernedContinuationActions(); trackBy: trackGovernedContinuationAction"
17881
- mat-stroked-button
17882
- type="button"
17883
- [attr.data-testid]="governedContinuationActionTestId(action)"
17884
- [attr.data-action-kind]="action.kind"
17885
- [disabled]="!action.enabled"
17886
- [matTooltip]="governedContinuationActionTooltip(action)"
17887
- (click)="runProjectKnowledgeGovernedContinuationAction(action)"
17888
- >
17889
- {{ tx(action.labelKey, action.labelFallback) }}
17890
- </button>
17891
- </div>
17892
-
17893
- <p *ngIf="projectKnowledgeCockpitBusyAction() as action" class="shared-rule-cockpit__status" data-testid="project-knowledge-cockpit-busy">
17894
- {{ tx('agentic.projectKnowledgeCockpit.running', 'Running governed Project Knowledge action') }}: {{ action }}
17895
- </p>
17896
- <p *ngIf="projectKnowledgeCockpitError()" class="shared-rule-cockpit__error" data-testid="project-knowledge-cockpit-error">
17897
- {{ projectKnowledgeCockpitError() }}
17898
- </p>
17899
-
17900
- <dl class="shared-rule-cockpit__facts">
17901
- <div>
17902
- <dt>{{ tx('agentic.projectKnowledgeCockpit.audit', 'Audit') }}</dt>
17903
- <dd data-testid="project-knowledge-cockpit-audit-status">
17904
- {{ audit.citedCount || 0 }}/{{ audit.influenceCount || 0 }} {{ tx('agentic.projectKnowledgeCockpit.cited', 'cited') }}
17905
- </dd>
17906
- </div>
17907
- <div>
17908
- <dt>{{ tx('agentic.projectKnowledgeCockpit.changeSet', 'Change-set') }}</dt>
17909
- <dd data-testid="project-knowledge-cockpit-change-set-id">{{ projectKnowledgeCockpitChangeSet()?.id || tx('agentic.sharedRuleCockpit.pending', 'pending') }}</dd>
17910
- </div>
17911
- <div>
17912
- <dt>{{ tx('agentic.projectKnowledgeCockpit.validation', 'Validation') }}</dt>
17913
- <dd data-testid="project-knowledge-cockpit-validation-status">{{ projectKnowledgeCockpitValidation()?.validationStatus || projectKnowledgeCockpitChangeSet()?.validationStatus || tx('agentic.sharedRuleCockpit.pending', 'pending') }}</dd>
17914
- </div>
17915
- <div>
17916
- <dt>{{ tx('agentic.projectKnowledgeCockpit.status', 'Status') }}</dt>
17917
- <dd data-testid="project-knowledge-cockpit-change-set-status">{{ projectKnowledgeCockpitChangeSet()?.status || tx('agentic.sharedRuleCockpit.pending', 'pending') }}</dd>
17918
- </div>
17919
- <div>
17920
- <dt>{{ tx('agentic.projectKnowledgeCockpit.safeOperations', 'Safe operations') }}</dt>
17921
- <dd data-testid="project-knowledge-cockpit-safe-operation-count">{{ projectKnowledgeCockpitChangeSet()?.safeOperationSummary?.length || 0 }}</dd>
17922
- </div>
17923
- <div>
17924
- <dt>{{ tx('agentic.projectKnowledgeCockpit.timeline', 'Safe timeline') }}</dt>
17925
- <dd data-testid="project-knowledge-cockpit-timeline-count">{{ projectKnowledgeCockpitTimeline()?.events?.length || 0 }}</dd>
17926
- </div>
17927
- </dl>
17928
-
17929
- <ol
17930
- *ngIf="projectKnowledgeTimelineItems().length; else projectKnowledgeTimelineEmpty"
17931
- class="shared-rule-cockpit__timeline"
17932
- data-testid="project-knowledge-cockpit-timeline-body"
17933
- >
17934
- <li
17935
- *ngFor="let item of projectKnowledgeTimelineItems(); trackBy: trackProjectKnowledgeTimelineItem"
17936
- class="shared-rule-cockpit__timeline-item"
17937
- >
17938
- <span class="shared-rule-cockpit__timeline-icon" aria-hidden="true">{{ item.icon || 'timeline' }}</span>
17939
- <div>
17940
- <strong>{{ item.title }}</strong>
17941
- <span *ngIf="item.badge" class="shared-rule-cockpit__timeline-badge">{{ item.badge }}</span>
17942
- <p *ngIf="item.subtitle">{{ item.subtitle }}</p>
17943
- <small *ngIf="item.meta">{{ item.meta }}</small>
17944
- <time *ngIf="item.opposite">{{ item.opposite }}</time>
18076
+ </button>
17945
18077
  </div>
17946
- </li>
17947
- </ol>
17948
- <ng-template #projectKnowledgeTimelineEmpty>
17949
- <p class="shared-rule-cockpit__timeline-empty" data-testid="project-knowledge-cockpit-timeline-empty">
17950
- {{ 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.') }}
17951
18082
  </p>
17952
- </ng-template>
17953
- </ng-container>
17954
- </section>
17955
-
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
+
17956
18173
  <praxis-floating-toolbar
17957
18174
  [visible]="showSettings()"
17958
18175
  [canUndo]="false"
@@ -17963,69 +18180,72 @@ class DynamicPageBuilderComponent {
17963
18180
  (settings)="openPageSettings()"
17964
18181
  (save)="saveCurrentPage()"
17965
18182
  (preview)="togglePreview()"
17966
- >
17967
- <button
17968
- *ngIf="showPageLifecycleActions && hasPageWidgets()"
17969
- pdx-toolbar-extra
17970
- mat-mini-fab
17971
- type="button"
17972
- [attr.data-testid]="'page-builder-restart-page'"
17973
- [disabled]="pageLifecycleBusy"
17974
- [matTooltip]="tx('pageLifecycle.restart', 'Restart page')"
17975
- [attr.aria-label]="tx('pageLifecycle.restartAria', 'Restart current page locally')"
17976
- (click)="pageRestart.emit()"
17977
- >
17978
- <mat-icon [praxisIcon]="'restart_alt'"></mat-icon>
17979
- </button>
17980
- <button
17981
- *ngIf="showPageLifecycleActions && canDeleteSavedPage"
17982
- pdx-toolbar-extra
17983
- mat-mini-fab
17984
- color="warn"
17985
- type="button"
17986
- [attr.data-testid]="'page-builder-delete-saved-page'"
17987
- [disabled]="pageLifecycleBusy"
17988
- [matTooltip]="tx('pageLifecycle.deleteSaved', 'Delete saved page')"
17989
- [attr.aria-label]="tx('pageLifecycle.deleteSavedAria', 'Delete persisted page and restart')"
17990
- (click)="savedPageDeleteRequested.emit()"
17991
- >
17992
- <mat-icon [praxisIcon]="'delete'"></mat-icon>
17993
- </button>
17994
- <button
17995
- *ngIf="enableAgenticAuthoring"
17996
- pdx-toolbar-extra
17997
- mat-mini-fab
17998
- type="button"
17999
- class="builder-shell__agentic-toggle"
18000
- [class.builder-shell__agentic-toggle--open]="agenticAuthoringOpen()"
18001
- [class.builder-shell__agentic-toggle--minimized]="agenticAuthoringMinimized()"
18002
- [attr.data-testid]="'page-builder-agentic-toggle'"
18003
- [matTooltip]="agenticAuthoringToggleLabel()"
18004
- [attr.aria-label]="agenticAuthoringToggleLabel()"
18005
- (click)="toggleAgenticAuthoring()"
18006
18183
  >
18007
- <mat-icon [praxisIcon]="'auto_awesome'"></mat-icon>
18008
- </button>
18009
- <button
18010
- *ngIf="hasPageWidgets()"
18011
- pdx-toolbar-extra
18012
- mat-mini-fab
18013
- type="button"
18014
- [attr.data-testid]="'page-builder-connections-toggle'"
18015
- [matTooltip]="tx('connections.toggle', 'Edit connections')"
18016
- [attr.aria-label]="tx('connections.toggleAria', 'Edit connections')"
18017
- (click)="toggleConnectionsViewer()"
18018
- >
18019
- <mat-icon [praxisIcon]="'hub'"></mat-icon>
18020
- </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
+ }
18021
18242
  </praxis-floating-toolbar>
18022
18243
  </div>
18023
- `, 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%}.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"] }] });
18024
18245
  }
18025
- 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: [{
18026
18247
  type: Component,
18027
18248
  args: [{ selector: 'praxis-dynamic-page-builder', standalone: true, imports: [
18028
- CommonModule,
18029
18249
  MatButtonModule,
18030
18250
  MatIconModule,
18031
18251
  MatTooltipModule,
@@ -18033,7 +18253,7 @@ i0.ɵɵngDeclareClassMetadata({ minVersion: "12.0.0", version: "20.3.17", ngImpo
18033
18253
  DynamicWidgetPageComponent,
18034
18254
  FloatingToolbarComponent,
18035
18255
  ConnectionEditorComponent,
18036
- PraxisAiAssistantShellComponent,
18256
+ PraxisAiAssistantShellComponent
18037
18257
  ], providers: [
18038
18258
  providePraxisPageBuilderI18n(),
18039
18259
  { provide: DYNAMIC_PAGE_SHELL_EDITOR, useValue: WidgetShellEditorComponent },
@@ -18041,7 +18261,7 @@ i0.ɵɵngDeclareClassMetadata({ minVersion: "12.0.0", version: "20.3.17", ngImpo
18041
18261
  <div
18042
18262
  class="builder-shell"
18043
18263
  [class.builder-shell--agentic-review-rail]="agenticAuthoringReviewRailActive()"
18044
- >
18264
+ >
18045
18265
  <praxis-dynamic-page
18046
18266
  #runtime
18047
18267
  [page]="currentPage()"
@@ -18058,325 +18278,338 @@ i0.ɵɵngDeclareClassMetadata({ minVersion: "12.0.0", version: "20.3.17", ngImpo
18058
18278
  (widgetEvent)="onRuntimeWidgetEvent($event)"
18059
18279
  (widgetSelectionChange)="onRuntimeWidgetSelectionChange($event)"
18060
18280
  (widgetAssistantRequested)="openAgenticAuthoringForWidget($event)"
18061
- />
18062
-
18281
+ />
18282
+
18063
18283
  <praxis-connection-editor
18064
18284
  [open]="showSettings() && connectionsViewerOpen()"
18065
18285
  [page]="currentPage()"
18066
18286
  (pageChange)="onConnectionEditorPageChange($event)"
18067
18287
  (focusWidget)="focusCanvasWidget($event)"
18068
18288
  (openPageSettings)="openPageSettings()"
18069
- />
18070
-
18071
- <praxis-ai-assistant-shell
18072
- *ngIf="showSettings() && enableAgenticAuthoring && agenticAuthoringOpen()"
18073
- panelTestId="page-builder-agentic-authoring-panel"
18074
- testIdPrefix="page-builder-agentic"
18075
- submitTestId="page-builder-agentic-preview"
18076
- applyTestId="page-builder-agentic-persist"
18077
- [labels]="agenticAuthoringShellLabels()"
18078
- mode="agentic-authoring"
18079
- [state]="agenticAuthoringShellState()"
18080
- [contextItems]="agenticAuthoringContextItems()"
18081
- [attachments]="agenticAuthoringAttachments()"
18082
- [messages]="agenticAuthoringConversation()"
18083
- [quickReplies]="agenticAuthoringQuickReplies()"
18084
- [prompt]="agenticAuthoringPrompt()"
18085
- [statusText]="agenticAuthoringStatus()"
18086
- [errorText]="agenticAuthoringError()"
18087
- [busy]="agenticAuthoringBusy()"
18088
- [canApply]="agenticAuthoringCanApply()"
18089
- [primaryAction]="agenticAuthoringSubmitAction()"
18090
- [showAttachAction]="false"
18091
- [enablePastedAttachments]="false"
18092
- [layout]="agenticAuthoringPanelLayout()"
18093
- [minWidth]="320"
18094
- [minHeight]="280"
18095
- [margin]="8"
18096
- (promptChange)="agenticAuthoringPrompt.set($event)"
18097
- (submitPrompt)="agenticAuthoringPrompt.set($event); previewAgenticAuthoring()"
18098
- (apply)="persistAgenticAuthoring()"
18099
- (retryTurn)="retryAgenticAuthoring()"
18100
- (cancelTurn)="cancelAgenticAuthoring()"
18101
- (quickReply)="submitAgenticQuickReply($event)"
18102
- (attach)="attachAgenticContext()"
18103
- (removeAttachment)="removeAgenticAttachment($event)"
18104
- (editMessage)="editAgenticMessage($event)"
18105
- (resendMessage)="resendAgenticMessage($event)"
18106
- (layoutChange)="onAgenticAuthoringLayoutChange($event)"
18107
- (close)="minimizeAgenticAuthoring()"
18108
- />
18109
-
18110
- <section
18111
- *ngIf="agenticAuthoringIncludeLlmDiagnostics && agenticAuthoringLlmDiagnosticsText()"
18112
- class="agentic-diagnostics-panel"
18113
- [class.agentic-diagnostics-panel--collapsed]="agenticAuthoringLlmDiagnosticsCollapsed()"
18114
- data-testid="page-builder-agentic-llm-diagnostics"
18115
- role="region"
18116
- [attr.aria-label]="tx('agentic.diagnostics.title', 'LLM diagnostics')"
18117
- [style.top.px]="agenticAuthoringDiagnosticsTop()"
18118
- >
18119
- <header class="agentic-diagnostics-panel__header">
18120
- <span>{{ tx('agentic.diagnostics.title', 'LLM diagnostics') }}</span>
18121
- <div class="agentic-diagnostics-panel__header-actions">
18122
- <span class="agentic-diagnostics-panel__badge">
18123
- {{ tx('agentic.diagnostics.badge', 'Debug') }}
18124
- </span>
18125
- <button
18126
- class="agentic-diagnostics-panel__toggle"
18127
- data-testid="page-builder-agentic-llm-diagnostics-toggle"
18128
- type="button"
18129
- [attr.aria-expanded]="!agenticAuthoringLlmDiagnosticsCollapsed()"
18130
- (click)="toggleAgenticAuthoringLlmDiagnostics()"
18131
- >
18132
- {{ 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()
18133
18354
  ? tx('agentic.diagnostics.expand', 'Expand')
18134
18355
  : tx('agentic.diagnostics.collapse', 'Collapse') }}
18135
- </button>
18136
- </div>
18137
- </header>
18138
- <ng-container *ngIf="!agenticAuthoringLlmDiagnosticsCollapsed()">
18139
- <p class="agentic-diagnostics-panel__description">
18140
- {{ tx('agentic.diagnostics.description', 'Prompt, context bundle, and tool catalog returned by the backend for this turn.') }}
18141
- </p>
18142
- <pre>{{ agenticAuthoringLlmDiagnosticsText() }}</pre>
18143
- </ng-container>
18144
- </section>
18145
-
18146
- <section
18147
- *ngIf="agenticAuthoringSharedRuleHandoffState() as handoff"
18148
- class="shared-rule-cockpit"
18149
- [class.shared-rule-cockpit--collapsed]="sharedRuleCockpitCollapsed()"
18150
- data-testid="page-builder-shared-rule-cockpit"
18151
- role="region"
18152
- [attr.aria-label]="tx('agentic.sharedRuleCockpit.title', 'Shared-rule governed actions')"
18153
- >
18154
- <header class="shared-rule-cockpit__header">
18155
- <div>
18156
- <strong>{{ tx('agentic.sharedRuleCockpit.title', 'Shared-rule governed actions') }}</strong>
18157
- <span>{{ handoff.ruleKey || handoff.recommendedRuleType || handoff.flowId }}</span>
18158
- </div>
18159
- <div class="shared-rule-cockpit__header-actions">
18160
- <span class="shared-rule-cockpit__badge">{{ handoff.routeGateStatus || handoff.previewDisposition }}</span>
18161
- <button
18162
- class="shared-rule-cockpit__toggle"
18163
- data-testid="shared-rule-cockpit-toggle"
18164
- type="button"
18165
- [attr.aria-expanded]="!sharedRuleCockpitCollapsed()"
18166
- (click)="toggleSharedRuleCockpit()"
18167
- >
18168
- {{ 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()
18169
18391
  ? tx('agentic.sharedRuleCockpit.expand', 'Expand')
18170
18392
  : tx('agentic.sharedRuleCockpit.collapse', 'Collapse') }}
18171
- </button>
18172
- </div>
18173
- </header>
18174
-
18175
- <ng-container *ngIf="!sharedRuleCockpitCollapsed()">
18176
- <p class="shared-rule-cockpit__description">
18177
- {{ 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.') }}
18178
- </p>
18179
-
18180
- <div class="shared-rule-cockpit__actions">
18181
- <button
18182
- *ngFor="let action of sharedRuleGovernedContinuationActions(); trackBy: trackGovernedContinuationAction"
18183
- mat-stroked-button
18184
- type="button"
18185
- [attr.data-testid]="governedContinuationActionTestId(action)"
18186
- [attr.data-action-kind]="action.kind"
18187
- [disabled]="!action.enabled"
18188
- [matTooltip]="governedContinuationActionTooltip(action)"
18189
- (click)="runSharedRuleGovernedContinuationAction(action)"
18190
- >
18191
- {{ tx(action.labelKey, action.labelFallback) }}
18192
- </button>
18193
- </div>
18194
-
18195
- <p *ngIf="sharedRuleCockpitBusyAction() as action" class="shared-rule-cockpit__status" data-testid="shared-rule-cockpit-busy">
18196
- {{ tx('agentic.sharedRuleCockpit.running', 'Running governed action') }}: {{ action }}
18197
- </p>
18198
- <p *ngIf="sharedRuleCockpitError()" class="shared-rule-cockpit__error" data-testid="shared-rule-cockpit-error">
18199
- {{ sharedRuleCockpitError() }}
18200
- </p>
18201
-
18202
- <dl class="shared-rule-cockpit__facts">
18203
- <div>
18204
- <dt>{{ tx('agentic.sharedRuleCockpit.definitionId', 'Definition') }}</dt>
18205
- <dd data-testid="shared-rule-cockpit-definition-id">{{ handoff.ruleDefinitionId || tx('agentic.sharedRuleCockpit.pending', 'pending') }}</dd>
18206
- </div>
18207
- <div>
18208
- <dt>{{ tx('agentic.sharedRuleCockpit.simulation', 'Simulation') }}</dt>
18209
- <dd data-testid="shared-rule-cockpit-simulation-result">{{ sharedRuleCockpitSimulation()?.result || tx('agentic.sharedRuleCockpit.pending', 'pending') }}</dd>
18210
- </div>
18211
- <div>
18212
- <dt>{{ tx('agentic.sharedRuleCockpit.publication', 'Publication') }}</dt>
18213
- <dd data-testid="shared-rule-cockpit-publication-status">{{ sharedRuleCockpitPublication()?.publicationStatus || tx('agentic.sharedRuleCockpit.pending', 'pending') }}</dd>
18214
- </div>
18215
- <div>
18216
- <dt>{{ tx('agentic.sharedRuleCockpit.materializations', 'Materializations') }}</dt>
18217
- <dd data-testid="shared-rule-cockpit-materialization-count">{{ sharedRuleCockpitMaterializations().length }}</dd>
18218
- </div>
18219
- <div>
18220
- <dt>{{ tx('agentic.sharedRuleCockpit.timeline', 'Governed timeline') }}</dt>
18221
- <dd data-testid="shared-rule-cockpit-timeline-count">{{ sharedRuleCockpitTimeline()?.events?.length || 0 }}</dd>
18222
- </div>
18223
- <div>
18224
- <dt>{{ tx('agentic.sharedRuleCockpit.enforcementState', 'Runtime enforcement') }}</dt>
18225
- <dd data-testid="shared-rule-cockpit-enforcement-status">{{ sharedRuleCockpitEnforcement()?.status || tx('agentic.sharedRuleCockpit.pending', 'pending') }}</dd>
18226
- </div>
18227
- </dl>
18228
-
18229
- <section
18230
- *ngIf="sharedRuleCockpitEnforcement() as enforcement"
18231
- class="shared-rule-cockpit__enforcement-matrix"
18232
- data-testid="shared-rule-cockpit-enforcement-matrix"
18233
- [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')"
18234
18498
  >
18235
- <header class="shared-rule-cockpit__matrix-header">
18499
+ <header class="shared-rule-cockpit__header">
18236
18500
  <div>
18237
- <strong>{{ tx('agentic.sharedRuleCockpit.enforcementMatrix', 'Runtime enforcement matrix') }}</strong>
18238
- <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>
18239
18503
  </div>
18240
- <span class="shared-rule-cockpit__matrix-badge" data-testid="shared-rule-cockpit-enforcement-counts">
18241
- {{ enforcement.appliedCount }} {{ tx('agentic.sharedRuleCockpit.applied', 'applied') }} /
18242
- {{ enforcement.pendingCount }} {{ tx('agentic.sharedRuleCockpit.waiting', 'waiting') }}
18243
- </span>
18244
- </header>
18245
-
18246
- <div class="shared-rule-cockpit__projection-grid">
18247
- <article
18248
- *ngFor="let projection of enforcement.projections; trackBy: trackSharedRuleEnforcementProjection"
18249
- class="shared-rule-cockpit__projection"
18250
- [attr.data-status]="projection.status"
18251
- data-testid="shared-rule-cockpit-enforcement-projection"
18252
- >
18253
- <span data-testid="shared-rule-cockpit-enforcement-layer">{{ projection.targetLayer }}</span>
18254
- <strong>{{ projection.targetLayerLabel }}</strong>
18255
- <small>{{ projection.targetArtifact || tx('agentic.sharedRuleCockpit.artifactPending', 'artifact pending') }}</small>
18256
- <em>{{ projection.sourceHash || tx('agentic.sharedRuleCockpit.sourceHashPending', 'source hash pending') }}</em>
18257
- </article>
18258
- </div>
18259
-
18260
- <p class="shared-rule-cockpit__matrix-source" data-testid="shared-rule-cockpit-enforcement-sourcehash">
18261
- <strong>{{ tx('agentic.sharedRuleCockpit.sourceHashes', 'Source hashes') }}:</strong>
18262
- {{ enforcement.sourceHashes.length ? enforcement.sourceHashes.join(', ') : tx('agentic.sharedRuleCockpit.sourceHashPending', 'source hash pending') }}
18263
- </p>
18264
- </section>
18265
- </ng-container>
18266
- </section>
18267
-
18268
- <section
18269
- *ngIf="agenticAuthoringProjectKnowledgeAudit() as audit"
18270
- class="project-knowledge-cockpit shared-rule-cockpit"
18271
- [class.shared-rule-cockpit--collapsed]="projectKnowledgeCockpitCollapsed()"
18272
- data-testid="page-builder-project-knowledge-cockpit"
18273
- role="region"
18274
- [attr.aria-label]="tx('agentic.projectKnowledgeCockpit.title', 'Project Knowledge governed actions')"
18275
- >
18276
- <header class="shared-rule-cockpit__header">
18277
- <div>
18278
- <strong>{{ tx('agentic.projectKnowledgeCockpit.title', 'Project Knowledge governed actions') }}</strong>
18279
- <span>{{ tx('agentic.projectKnowledgeCockpit.subtitle', 'Continue cited knowledge as a governed Domain Knowledge change-set.') }}</span>
18280
- </div>
18281
- <div class="shared-rule-cockpit__header-actions">
18282
- <span class="shared-rule-cockpit__badge">{{ audit.citationPolicy || audit.source || 'governed' }}</span>
18283
- <button
18284
- class="shared-rule-cockpit__toggle"
18285
- data-testid="project-knowledge-cockpit-toggle"
18286
- type="button"
18287
- [attr.aria-expanded]="!projectKnowledgeCockpitCollapsed()"
18288
- (click)="toggleProjectKnowledgeCockpit()"
18289
- >
18290
- {{ 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()
18291
18514
  ? tx('agentic.projectKnowledgeCockpit.expand', 'Expand')
18292
18515
  : tx('agentic.projectKnowledgeCockpit.collapse', 'Collapse') }}
18293
- </button>
18294
- </div>
18295
- </header>
18296
-
18297
- <ng-container *ngIf="!projectKnowledgeCockpitCollapsed()">
18298
- <p class="shared-rule-cockpit__description">
18299
- {{ 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.') }}
18300
- </p>
18301
-
18302
- <div class="shared-rule-cockpit__actions">
18303
- <button
18304
- *ngFor="let action of projectKnowledgeGovernedContinuationActions(); trackBy: trackGovernedContinuationAction"
18305
- mat-stroked-button
18306
- type="button"
18307
- [attr.data-testid]="governedContinuationActionTestId(action)"
18308
- [attr.data-action-kind]="action.kind"
18309
- [disabled]="!action.enabled"
18310
- [matTooltip]="governedContinuationActionTooltip(action)"
18311
- (click)="runProjectKnowledgeGovernedContinuationAction(action)"
18312
- >
18313
- {{ tx(action.labelKey, action.labelFallback) }}
18314
- </button>
18315
- </div>
18316
-
18317
- <p *ngIf="projectKnowledgeCockpitBusyAction() as action" class="shared-rule-cockpit__status" data-testid="project-knowledge-cockpit-busy">
18318
- {{ tx('agentic.projectKnowledgeCockpit.running', 'Running governed Project Knowledge action') }}: {{ action }}
18319
- </p>
18320
- <p *ngIf="projectKnowledgeCockpitError()" class="shared-rule-cockpit__error" data-testid="project-knowledge-cockpit-error">
18321
- {{ projectKnowledgeCockpitError() }}
18322
- </p>
18323
-
18324
- <dl class="shared-rule-cockpit__facts">
18325
- <div>
18326
- <dt>{{ tx('agentic.projectKnowledgeCockpit.audit', 'Audit') }}</dt>
18327
- <dd data-testid="project-knowledge-cockpit-audit-status">
18328
- {{ audit.citedCount || 0 }}/{{ audit.influenceCount || 0 }} {{ tx('agentic.projectKnowledgeCockpit.cited', 'cited') }}
18329
- </dd>
18330
- </div>
18331
- <div>
18332
- <dt>{{ tx('agentic.projectKnowledgeCockpit.changeSet', 'Change-set') }}</dt>
18333
- <dd data-testid="project-knowledge-cockpit-change-set-id">{{ projectKnowledgeCockpitChangeSet()?.id || tx('agentic.sharedRuleCockpit.pending', 'pending') }}</dd>
18334
- </div>
18335
- <div>
18336
- <dt>{{ tx('agentic.projectKnowledgeCockpit.validation', 'Validation') }}</dt>
18337
- <dd data-testid="project-knowledge-cockpit-validation-status">{{ projectKnowledgeCockpitValidation()?.validationStatus || projectKnowledgeCockpitChangeSet()?.validationStatus || tx('agentic.sharedRuleCockpit.pending', 'pending') }}</dd>
18338
- </div>
18339
- <div>
18340
- <dt>{{ tx('agentic.projectKnowledgeCockpit.status', 'Status') }}</dt>
18341
- <dd data-testid="project-knowledge-cockpit-change-set-status">{{ projectKnowledgeCockpitChangeSet()?.status || tx('agentic.sharedRuleCockpit.pending', 'pending') }}</dd>
18342
- </div>
18343
- <div>
18344
- <dt>{{ tx('agentic.projectKnowledgeCockpit.safeOperations', 'Safe operations') }}</dt>
18345
- <dd data-testid="project-knowledge-cockpit-safe-operation-count">{{ projectKnowledgeCockpitChangeSet()?.safeOperationSummary?.length || 0 }}</dd>
18346
- </div>
18347
- <div>
18348
- <dt>{{ tx('agentic.projectKnowledgeCockpit.timeline', 'Safe timeline') }}</dt>
18349
- <dd data-testid="project-knowledge-cockpit-timeline-count">{{ projectKnowledgeCockpitTimeline()?.events?.length || 0 }}</dd>
18350
- </div>
18351
- </dl>
18352
-
18353
- <ol
18354
- *ngIf="projectKnowledgeTimelineItems().length; else projectKnowledgeTimelineEmpty"
18355
- class="shared-rule-cockpit__timeline"
18356
- data-testid="project-knowledge-cockpit-timeline-body"
18357
- >
18358
- <li
18359
- *ngFor="let item of projectKnowledgeTimelineItems(); trackBy: trackProjectKnowledgeTimelineItem"
18360
- class="shared-rule-cockpit__timeline-item"
18361
- >
18362
- <span class="shared-rule-cockpit__timeline-icon" aria-hidden="true">{{ item.icon || 'timeline' }}</span>
18363
- <div>
18364
- <strong>{{ item.title }}</strong>
18365
- <span *ngIf="item.badge" class="shared-rule-cockpit__timeline-badge">{{ item.badge }}</span>
18366
- <p *ngIf="item.subtitle">{{ item.subtitle }}</p>
18367
- <small *ngIf="item.meta">{{ item.meta }}</small>
18368
- <time *ngIf="item.opposite">{{ item.opposite }}</time>
18516
+ </button>
18369
18517
  </div>
18370
- </li>
18371
- </ol>
18372
- <ng-template #projectKnowledgeTimelineEmpty>
18373
- <p class="shared-rule-cockpit__timeline-empty" data-testid="project-knowledge-cockpit-timeline-empty">
18374
- {{ 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.') }}
18375
18522
  </p>
18376
- </ng-template>
18377
- </ng-container>
18378
- </section>
18379
-
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
+
18380
18613
  <praxis-floating-toolbar
18381
18614
  [visible]="showSettings()"
18382
18615
  [canUndo]="false"
@@ -18387,64 +18620,68 @@ i0.ɵɵngDeclareClassMetadata({ minVersion: "12.0.0", version: "20.3.17", ngImpo
18387
18620
  (settings)="openPageSettings()"
18388
18621
  (save)="saveCurrentPage()"
18389
18622
  (preview)="togglePreview()"
18390
- >
18391
- <button
18392
- *ngIf="showPageLifecycleActions && hasPageWidgets()"
18393
- pdx-toolbar-extra
18394
- mat-mini-fab
18395
- type="button"
18396
- [attr.data-testid]="'page-builder-restart-page'"
18397
- [disabled]="pageLifecycleBusy"
18398
- [matTooltip]="tx('pageLifecycle.restart', 'Restart page')"
18399
- [attr.aria-label]="tx('pageLifecycle.restartAria', 'Restart current page locally')"
18400
- (click)="pageRestart.emit()"
18401
- >
18402
- <mat-icon [praxisIcon]="'restart_alt'"></mat-icon>
18403
- </button>
18404
- <button
18405
- *ngIf="showPageLifecycleActions && canDeleteSavedPage"
18406
- pdx-toolbar-extra
18407
- mat-mini-fab
18408
- color="warn"
18409
- type="button"
18410
- [attr.data-testid]="'page-builder-delete-saved-page'"
18411
- [disabled]="pageLifecycleBusy"
18412
- [matTooltip]="tx('pageLifecycle.deleteSaved', 'Delete saved page')"
18413
- [attr.aria-label]="tx('pageLifecycle.deleteSavedAria', 'Delete persisted page and restart')"
18414
- (click)="savedPageDeleteRequested.emit()"
18415
- >
18416
- <mat-icon [praxisIcon]="'delete'"></mat-icon>
18417
- </button>
18418
- <button
18419
- *ngIf="enableAgenticAuthoring"
18420
- pdx-toolbar-extra
18421
- mat-mini-fab
18422
- type="button"
18423
- class="builder-shell__agentic-toggle"
18424
- [class.builder-shell__agentic-toggle--open]="agenticAuthoringOpen()"
18425
- [class.builder-shell__agentic-toggle--minimized]="agenticAuthoringMinimized()"
18426
- [attr.data-testid]="'page-builder-agentic-toggle'"
18427
- [matTooltip]="agenticAuthoringToggleLabel()"
18428
- [attr.aria-label]="agenticAuthoringToggleLabel()"
18429
- (click)="toggleAgenticAuthoring()"
18430
18623
  >
18431
- <mat-icon [praxisIcon]="'auto_awesome'"></mat-icon>
18432
- </button>
18433
- <button
18434
- *ngIf="hasPageWidgets()"
18435
- pdx-toolbar-extra
18436
- mat-mini-fab
18437
- type="button"
18438
- [attr.data-testid]="'page-builder-connections-toggle'"
18439
- [matTooltip]="tx('connections.toggle', 'Edit connections')"
18440
- [attr.aria-label]="tx('connections.toggleAria', 'Edit connections')"
18441
- (click)="toggleConnectionsViewer()"
18442
- >
18443
- <mat-icon [praxisIcon]="'hub'"></mat-icon>
18444
- </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
+ }
18445
18682
  </praxis-floating-toolbar>
18446
18683
  </div>
18447
- `, 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%}.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"] }]
18448
18685
  }], ctorParameters: () => [{ type: i1.MatDialog }, { type: undefined, decorators: [{
18449
18686
  type: Optional
18450
18687
  }, {