@forgeroute/ui 0.4.34 → 0.4.36

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.
@@ -4360,6 +4360,7 @@ var TooltipDirective = class TooltipDirective {
4360
4360
  this.host = inject(ElementRef).nativeElement;
4361
4361
  this.doc = inject(DOCUMENT);
4362
4362
  this.bubble = null;
4363
+ this.previousDescribedBy = null;
4363
4364
  this.id = `ui-tooltip-${nextTooltipId++}`;
4364
4365
  inject(DestroyRef).onDestroy(() => this.hide());
4365
4366
  }
@@ -4392,7 +4393,8 @@ var TooltipDirective = class TooltipDirective {
4392
4393
  });
4393
4394
  this.doc.body.appendChild(el);
4394
4395
  this.bubble = el;
4395
- this.host.setAttribute("aria-describedby", this.id);
4396
+ this.previousDescribedBy = this.host.getAttribute("aria-describedby");
4397
+ this.host.setAttribute("aria-describedby", this.previousDescribedBy ? `${this.previousDescribedBy} ${this.id}` : this.id);
4396
4398
  const r = this.host.getBoundingClientRect();
4397
4399
  const b = el.getBoundingClientRect();
4398
4400
  const gap = 6;
@@ -4405,10 +4407,13 @@ var TooltipDirective = class TooltipDirective {
4405
4407
  el.style.visibility = "visible";
4406
4408
  }
4407
4409
  hide() {
4408
- this.bubble?.remove();
4410
+ if (!this.bubble) return;
4411
+ this.bubble.remove();
4409
4412
  this.bubble = null;
4410
4413
  if (openTooltip?.owner === this) openTooltip = null;
4411
- this.host.removeAttribute("aria-describedby");
4414
+ if (this.previousDescribedBy) this.host.setAttribute("aria-describedby", this.previousDescribedBy);
4415
+ else this.host.removeAttribute("aria-describedby");
4416
+ this.previousDescribedBy = null;
4412
4417
  }
4413
4418
  static {
4414
4419
  this.ɵfac = i0.ɵɵngDeclareFactory({
@@ -8728,22 +8733,30 @@ i0.ɵɵngDeclareClassMetadata({
8728
8733
  }]
8729
8734
  }
8730
8735
  });
8731
- var ImportSourceGridComponent = class ImportSourceGridComponent {
8736
+ var OptionCardComponent = class OptionCardComponent {
8732
8737
  constructor() {
8733
- this.sources = input.required(...ngDevMode ? [{ debugName: "sources" }] : /* istanbul ignore next */ []);
8734
- this.selected = input("", ...ngDevMode ? [{ debugName: "selected" }] : /* istanbul ignore next */ []);
8735
- this.appearance = input("tile", ...ngDevMode ? [{ debugName: "appearance" }] : /* istanbul ignore next */ []);
8738
+ this.title = input.required(...ngDevMode ? [{ debugName: "title" }] : /* istanbul ignore next */ []);
8739
+ this.description = input("", ...ngDevMode ? [{ debugName: "description" }] : /* istanbul ignore next */ []);
8740
+ this.letter = input("", ...ngDevMode ? [{ debugName: "letter" }] : /* istanbul ignore next */ []);
8741
+ this.icon = input("", ...ngDevMode ? [{ debugName: "icon" }] : /* istanbul ignore next */ []);
8742
+ this.color = input("#64748b", ...ngDevMode ? [{ debugName: "color" }] : /* istanbul ignore next */ []);
8743
+ this.actionLabel = input("", ...ngDevMode ? [{ debugName: "actionLabel" }] : /* istanbul ignore next */ []);
8744
+ this.actionVariant = input("secondary", ...ngDevMode ? [{ debugName: "actionVariant" }] : /* istanbul ignore next */ []);
8745
+ this.actionAriaLabel = input("", ...ngDevMode ? [{ debugName: "actionAriaLabel" }] : /* istanbul ignore next */ []);
8746
+ this.actionTestId = input("", ...ngDevMode ? [{ debugName: "actionTestId" }] : /* istanbul ignore next */ []);
8747
+ this.actionLoading = input(false, ...ngDevMode ? [{ debugName: "actionLoading" }] : /* istanbul ignore next */ []);
8736
8748
  this.disabled = input(false, ...ngDevMode ? [{ debugName: "disabled" }] : /* istanbul ignore next */ []);
8737
- this.actionLabel = input("Select", ...ngDevMode ? [{ debugName: "actionLabel" }] : /* istanbul ignore next */ []);
8738
- this.ariaLabel = input("", ...ngDevMode ? [{ debugName: "ariaLabel" }] : /* istanbul ignore next */ []);
8739
- this.sourceSelect = output();
8749
+ this.action = output();
8750
+ }
8751
+ iconD() {
8752
+ return this.icon() ? iconPath(this.icon()) ?? null : null;
8740
8753
  }
8741
8754
  static {
8742
8755
  this.ɵfac = i0.ɵɵngDeclareFactory({
8743
8756
  minVersion: "12.0.0",
8744
8757
  version: "22.2.2",
8745
8758
  ngImport: i0,
8746
- type: ImportSourceGridComponent,
8759
+ type: OptionCardComponent,
8747
8760
  deps: [],
8748
8761
  target: i0.ɵɵFactoryTarget.Component
8749
8762
  });
@@ -8752,34 +8765,41 @@ var ImportSourceGridComponent = class ImportSourceGridComponent {
8752
8765
  this.ɵcmp = i0.ɵɵngDeclareComponent({
8753
8766
  minVersion: "17.0.0",
8754
8767
  version: "22.2.2",
8755
- type: ImportSourceGridComponent,
8768
+ type: OptionCardComponent,
8756
8769
  isStandalone: true,
8757
- selector: "ui-import-source-grid",
8770
+ selector: "ui-option-card",
8758
8771
  inputs: {
8759
- sources: {
8760
- classPropertyName: "sources",
8761
- publicName: "sources",
8772
+ title: {
8773
+ classPropertyName: "title",
8774
+ publicName: "title",
8762
8775
  isSignal: true,
8763
8776
  isRequired: true,
8764
8777
  transformFunction: null
8765
8778
  },
8766
- selected: {
8767
- classPropertyName: "selected",
8768
- publicName: "selected",
8779
+ description: {
8780
+ classPropertyName: "description",
8781
+ publicName: "description",
8769
8782
  isSignal: true,
8770
8783
  isRequired: false,
8771
8784
  transformFunction: null
8772
8785
  },
8773
- appearance: {
8774
- classPropertyName: "appearance",
8775
- publicName: "appearance",
8786
+ letter: {
8787
+ classPropertyName: "letter",
8788
+ publicName: "letter",
8776
8789
  isSignal: true,
8777
8790
  isRequired: false,
8778
8791
  transformFunction: null
8779
8792
  },
8780
- disabled: {
8781
- classPropertyName: "disabled",
8782
- publicName: "disabled",
8793
+ icon: {
8794
+ classPropertyName: "icon",
8795
+ publicName: "icon",
8796
+ isSignal: true,
8797
+ isRequired: false,
8798
+ transformFunction: null
8799
+ },
8800
+ color: {
8801
+ classPropertyName: "color",
8802
+ publicName: "color",
8783
8803
  isSignal: true,
8784
8804
  isRequired: false,
8785
8805
  transformFunction: null
@@ -8791,53 +8811,64 @@ var ImportSourceGridComponent = class ImportSourceGridComponent {
8791
8811
  isRequired: false,
8792
8812
  transformFunction: null
8793
8813
  },
8794
- ariaLabel: {
8795
- classPropertyName: "ariaLabel",
8796
- publicName: "ariaLabel",
8814
+ actionVariant: {
8815
+ classPropertyName: "actionVariant",
8816
+ publicName: "actionVariant",
8817
+ isSignal: true,
8818
+ isRequired: false,
8819
+ transformFunction: null
8820
+ },
8821
+ actionAriaLabel: {
8822
+ classPropertyName: "actionAriaLabel",
8823
+ publicName: "actionAriaLabel",
8824
+ isSignal: true,
8825
+ isRequired: false,
8826
+ transformFunction: null
8827
+ },
8828
+ actionTestId: {
8829
+ classPropertyName: "actionTestId",
8830
+ publicName: "actionTestId",
8831
+ isSignal: true,
8832
+ isRequired: false,
8833
+ transformFunction: null
8834
+ },
8835
+ actionLoading: {
8836
+ classPropertyName: "actionLoading",
8837
+ publicName: "actionLoading",
8838
+ isSignal: true,
8839
+ isRequired: false,
8840
+ transformFunction: null
8841
+ },
8842
+ disabled: {
8843
+ classPropertyName: "disabled",
8844
+ publicName: "disabled",
8797
8845
  isSignal: true,
8798
8846
  isRequired: false,
8799
8847
  transformFunction: null
8800
8848
  }
8801
8849
  },
8802
- outputs: { sourceSelect: "sourceSelect" },
8850
+ outputs: { action: "action" },
8803
8851
  ngImport: i0,
8804
8852
  template: `
8805
- <div class="ie-source-grid" [attr.role]="appearance() === 'card' ? 'group' : 'list'" [class.ie-source-grid--cards]="appearance() === 'card'" [attr.aria-label]="ariaLabel() || null">
8806
- @for (src of sources(); track src.value) {
8807
- @if (appearance() === 'card') {
8808
- <ui-detail-card class="ie-source-detail" [showHeader]="false" [fill]="true" [ariaLabel]="src.label" [attr.data-testid]="'source-' + src.value">
8809
- <div class="ie-source-detail-row">
8810
- @if (src.letter) {
8811
- <span class="ie-source-letter" [style.background]="src.color || '#64748b'" aria-hidden="true">{{ src.letter }}</span>
8812
- }
8813
- <span class="ie-source-detail-text">
8814
- <span class="ie-source-label">{{ src.label }}</span>
8815
- @if (src.desc) { <span class="ie-source-desc">{{ src.desc }}</span> }
8816
- </span>
8817
- <ui-button variant="secondary" size="xs" [attr.data-testid]="'source-pick-' + src.value" [disabled]="disabled()" [ariaLabel]="actionLabel() + ' ' + src.label" (click)="sourceSelect.emit(src.value)">{{ actionLabel() }}</ui-button>
8818
- </div>
8819
- </ui-detail-card>
8820
- } @else {
8821
- <button
8822
- class="ie-source-card"
8823
- role="listitem"
8824
- type="button"
8825
- [class.ie-source-card--active]="selected() === src.value"
8826
- [attr.aria-pressed]="selected() === src.value"
8827
- [attr.data-testid]="'source-' + src.value"
8828
- (click)="sourceSelect.emit(src.value)">
8829
- @if (src.letter) {
8830
- <span class="ie-source-letter" [style.background]="src.color || '#64748b'" aria-hidden="true">{{ src.letter }}</span>
8831
- }
8832
- <span class="ie-source-label">{{ src.label }}</span>
8833
- @if (src.desc) { <span class="ie-source-desc">{{ src.desc }}</span> }
8834
- </button>
8853
+ <ui-detail-card class="oc" [showHeader]="false" [ariaLabel]="title()">
8854
+ <div class="oc-row">
8855
+ <span class="oc-tile" [style.background]="color()" aria-hidden="true">
8856
+ @if (letter()) { {{ letter() }} } @else if (iconD(); as d) { <svg width="18" height="18" viewBox="0 0 24 24" fill="none" stroke="currentColor" stroke-width="2" stroke-linecap="round" stroke-linejoin="round" focusable="false"><path [attr.d]="d" /></svg> }
8857
+ </span>
8858
+ <span class="oc-text">
8859
+ <span class="oc-title">{{ title() }}</span>
8860
+ @if (description()) { <span class="oc-desc">{{ description() }}</span> }
8861
+ </span>
8862
+ @if (actionLabel()) {
8863
+ <ui-button size="xs" [variant]="actionVariant()" [disabled]="disabled()" [loading]="actionLoading()" [attr.data-testid]="actionTestId() || null"
8864
+ [ariaLabel]="actionAriaLabel() || (actionLabel() + ' ' + title())" (click)="action.emit()">{{ actionLabel() }}</ui-button>
8835
8865
  }
8836
- }
8837
- </div>
8866
+ </div>
8867
+ <ng-content />
8868
+ </ui-detail-card>
8838
8869
  `,
8839
8870
  isInline: true,
8840
- styles: ["ui-import-source-grid{display:block}.ie-source-grid{display:grid;grid-template-columns:repeat(3,1fr);gap:10px}@media(max-width:520px){.ie-source-grid{grid-template-columns:repeat(2,1fr)}}.ie-source-card{display:flex;flex-direction:column;align-items:flex-start;gap:4px;padding:12px;border:1px solid #e2e8f0;border-radius:10px;background:#fff;cursor:pointer;font-family:inherit;text-align:left;transition:all .15s}.ie-source-card:hover{border-color:#94a3b8;background:#f8fafc}.ie-source-card.ie-source-card--active{border-color:#3b82f6;background:#eff6ff}.ie-source-card:focus-visible{outline:2px solid #60a5fa;outline-offset:2px}.ie-source-letter{width:36px;height:36px;border-radius:8px;color:#fff;font-size:1rem;font-weight:700;display:flex;align-items:center;justify-content:center;flex-shrink:0}.ie-source-label{font-size:.8125rem;font-weight:600;color:#1e293b;line-height:1.2}.ie-source-desc{font-size:.75rem;color:#64748b}.ie-source-grid--cards{grid-template-columns:repeat(2,1fr)}@media(max-width:520px){.ie-source-grid--cards{grid-template-columns:1fr}}ui-import-source-grid .ie-source-detail.ie-source-detail{margin-bottom:0}.ie-source-detail-row{display:flex;align-items:center;gap:12px}.ie-source-detail-text{display:flex;flex-direction:column;gap:2px;flex:1;min-width:0}\n"],
8871
+ styles: ["ui-option-card{display:block}ui-option-card .oc{margin-bottom:0}.oc-row{display:flex;align-items:center;gap:12px}.oc-tile{width:36px;height:36px;border-radius:8px;color:#fff;font-size:1rem;font-weight:700;display:flex;align-items:center;justify-content:center;flex-shrink:0}.oc-text{display:flex;flex-direction:column;gap:2px;flex:1;min-width:0}.oc-title{font-size:.8125rem;font-weight:600;color:#1e293b;line-height:1.2}.oc-desc{font-size:.75rem;color:#64748b;overflow-wrap:anywhere}\n"],
8841
8872
  dependencies: [{
8842
8873
  kind: "component",
8843
8874
  type: ButtonComponent,
@@ -8907,6 +8938,259 @@ var ImportSourceGridComponent = class ImportSourceGridComponent {
8907
8938
  });
8908
8939
  }
8909
8940
  };
8941
+ i0.ɵɵngDeclareClassMetadata({
8942
+ minVersion: "12.0.0",
8943
+ version: "22.2.2",
8944
+ ngImport: i0,
8945
+ type: OptionCardComponent,
8946
+ decorators: [{
8947
+ type: Component,
8948
+ args: [{
8949
+ selector: "ui-option-card",
8950
+ standalone: true,
8951
+ changeDetection: ChangeDetectionStrategy.OnPush,
8952
+ encapsulation: ViewEncapsulation.None,
8953
+ imports: [ButtonComponent, DetailCardComponent],
8954
+ template: `
8955
+ <ui-detail-card class="oc" [showHeader]="false" [ariaLabel]="title()">
8956
+ <div class="oc-row">
8957
+ <span class="oc-tile" [style.background]="color()" aria-hidden="true">
8958
+ @if (letter()) { {{ letter() }} } @else if (iconD(); as d) { <svg width="18" height="18" viewBox="0 0 24 24" fill="none" stroke="currentColor" stroke-width="2" stroke-linecap="round" stroke-linejoin="round" focusable="false"><path [attr.d]="d" /></svg> }
8959
+ </span>
8960
+ <span class="oc-text">
8961
+ <span class="oc-title">{{ title() }}</span>
8962
+ @if (description()) { <span class="oc-desc">{{ description() }}</span> }
8963
+ </span>
8964
+ @if (actionLabel()) {
8965
+ <ui-button size="xs" [variant]="actionVariant()" [disabled]="disabled()" [loading]="actionLoading()" [attr.data-testid]="actionTestId() || null"
8966
+ [ariaLabel]="actionAriaLabel() || (actionLabel() + ' ' + title())" (click)="action.emit()">{{ actionLabel() }}</ui-button>
8967
+ }
8968
+ </div>
8969
+ <ng-content />
8970
+ </ui-detail-card>
8971
+ `,
8972
+ styles: ["ui-option-card{display:block}ui-option-card .oc{margin-bottom:0}.oc-row{display:flex;align-items:center;gap:12px}.oc-tile{width:36px;height:36px;border-radius:8px;color:#fff;font-size:1rem;font-weight:700;display:flex;align-items:center;justify-content:center;flex-shrink:0}.oc-text{display:flex;flex-direction:column;gap:2px;flex:1;min-width:0}.oc-title{font-size:.8125rem;font-weight:600;color:#1e293b;line-height:1.2}.oc-desc{font-size:.75rem;color:#64748b;overflow-wrap:anywhere}\n"]
8973
+ }]
8974
+ }],
8975
+ propDecorators: {
8976
+ title: [{
8977
+ type: i0.Input,
8978
+ args: [{
8979
+ isSignal: true,
8980
+ alias: "title",
8981
+ required: true
8982
+ }]
8983
+ }],
8984
+ description: [{
8985
+ type: i0.Input,
8986
+ args: [{
8987
+ isSignal: true,
8988
+ alias: "description",
8989
+ required: false
8990
+ }]
8991
+ }],
8992
+ letter: [{
8993
+ type: i0.Input,
8994
+ args: [{
8995
+ isSignal: true,
8996
+ alias: "letter",
8997
+ required: false
8998
+ }]
8999
+ }],
9000
+ icon: [{
9001
+ type: i0.Input,
9002
+ args: [{
9003
+ isSignal: true,
9004
+ alias: "icon",
9005
+ required: false
9006
+ }]
9007
+ }],
9008
+ color: [{
9009
+ type: i0.Input,
9010
+ args: [{
9011
+ isSignal: true,
9012
+ alias: "color",
9013
+ required: false
9014
+ }]
9015
+ }],
9016
+ actionLabel: [{
9017
+ type: i0.Input,
9018
+ args: [{
9019
+ isSignal: true,
9020
+ alias: "actionLabel",
9021
+ required: false
9022
+ }]
9023
+ }],
9024
+ actionVariant: [{
9025
+ type: i0.Input,
9026
+ args: [{
9027
+ isSignal: true,
9028
+ alias: "actionVariant",
9029
+ required: false
9030
+ }]
9031
+ }],
9032
+ actionAriaLabel: [{
9033
+ type: i0.Input,
9034
+ args: [{
9035
+ isSignal: true,
9036
+ alias: "actionAriaLabel",
9037
+ required: false
9038
+ }]
9039
+ }],
9040
+ actionTestId: [{
9041
+ type: i0.Input,
9042
+ args: [{
9043
+ isSignal: true,
9044
+ alias: "actionTestId",
9045
+ required: false
9046
+ }]
9047
+ }],
9048
+ actionLoading: [{
9049
+ type: i0.Input,
9050
+ args: [{
9051
+ isSignal: true,
9052
+ alias: "actionLoading",
9053
+ required: false
9054
+ }]
9055
+ }],
9056
+ disabled: [{
9057
+ type: i0.Input,
9058
+ args: [{
9059
+ isSignal: true,
9060
+ alias: "disabled",
9061
+ required: false
9062
+ }]
9063
+ }],
9064
+ action: [{
9065
+ type: i0.Output,
9066
+ args: ["action"]
9067
+ }]
9068
+ }
9069
+ });
9070
+ var ImportSourceGridComponent = class ImportSourceGridComponent {
9071
+ constructor() {
9072
+ this.sources = input.required(...ngDevMode ? [{ debugName: "sources" }] : /* istanbul ignore next */ []);
9073
+ this.selected = input("", ...ngDevMode ? [{ debugName: "selected" }] : /* istanbul ignore next */ []);
9074
+ this.appearance = input("tile", ...ngDevMode ? [{ debugName: "appearance" }] : /* istanbul ignore next */ []);
9075
+ this.disabled = input(false, ...ngDevMode ? [{ debugName: "disabled" }] : /* istanbul ignore next */ []);
9076
+ this.actionLabel = input("Select", ...ngDevMode ? [{ debugName: "actionLabel" }] : /* istanbul ignore next */ []);
9077
+ this.ariaLabel = input("", ...ngDevMode ? [{ debugName: "ariaLabel" }] : /* istanbul ignore next */ []);
9078
+ this.sourceSelect = output();
9079
+ }
9080
+ static {
9081
+ this.ɵfac = i0.ɵɵngDeclareFactory({
9082
+ minVersion: "12.0.0",
9083
+ version: "22.2.2",
9084
+ ngImport: i0,
9085
+ type: ImportSourceGridComponent,
9086
+ deps: [],
9087
+ target: i0.ɵɵFactoryTarget.Component
9088
+ });
9089
+ }
9090
+ static {
9091
+ this.ɵcmp = i0.ɵɵngDeclareComponent({
9092
+ minVersion: "17.0.0",
9093
+ version: "22.2.2",
9094
+ type: ImportSourceGridComponent,
9095
+ isStandalone: true,
9096
+ selector: "ui-import-source-grid",
9097
+ inputs: {
9098
+ sources: {
9099
+ classPropertyName: "sources",
9100
+ publicName: "sources",
9101
+ isSignal: true,
9102
+ isRequired: true,
9103
+ transformFunction: null
9104
+ },
9105
+ selected: {
9106
+ classPropertyName: "selected",
9107
+ publicName: "selected",
9108
+ isSignal: true,
9109
+ isRequired: false,
9110
+ transformFunction: null
9111
+ },
9112
+ appearance: {
9113
+ classPropertyName: "appearance",
9114
+ publicName: "appearance",
9115
+ isSignal: true,
9116
+ isRequired: false,
9117
+ transformFunction: null
9118
+ },
9119
+ disabled: {
9120
+ classPropertyName: "disabled",
9121
+ publicName: "disabled",
9122
+ isSignal: true,
9123
+ isRequired: false,
9124
+ transformFunction: null
9125
+ },
9126
+ actionLabel: {
9127
+ classPropertyName: "actionLabel",
9128
+ publicName: "actionLabel",
9129
+ isSignal: true,
9130
+ isRequired: false,
9131
+ transformFunction: null
9132
+ },
9133
+ ariaLabel: {
9134
+ classPropertyName: "ariaLabel",
9135
+ publicName: "ariaLabel",
9136
+ isSignal: true,
9137
+ isRequired: false,
9138
+ transformFunction: null
9139
+ }
9140
+ },
9141
+ outputs: { sourceSelect: "sourceSelect" },
9142
+ ngImport: i0,
9143
+ template: `
9144
+ <div class="ie-source-grid" [attr.role]="appearance() === 'card' ? 'group' : 'list'" [class.ie-source-grid--cards]="appearance() === 'card'" [attr.aria-label]="ariaLabel() || null">
9145
+ @for (src of sources(); track src.value) {
9146
+ @if (appearance() === 'card') {
9147
+ <ui-option-card [attr.data-testid]="'source-' + src.value" [title]="src.label" [description]="src.desc || ''" [letter]="src.letter || ''" [color]="src.color || '#64748b'"
9148
+ [actionLabel]="actionLabel()" [actionTestId]="'source-pick-' + src.value" [disabled]="disabled()" (action)="sourceSelect.emit(src.value)" />
9149
+ } @else {
9150
+ <button
9151
+ class="ie-source-card"
9152
+ role="listitem"
9153
+ type="button"
9154
+ [class.ie-source-card--active]="selected() === src.value"
9155
+ [attr.aria-pressed]="selected() === src.value"
9156
+ [attr.data-testid]="'source-' + src.value"
9157
+ (click)="sourceSelect.emit(src.value)">
9158
+ @if (src.letter) {
9159
+ <span class="ie-source-letter" [style.background]="src.color || '#64748b'" aria-hidden="true">{{ src.letter }}</span>
9160
+ }
9161
+ <span class="ie-source-label">{{ src.label }}</span>
9162
+ @if (src.desc) { <span class="ie-source-desc">{{ src.desc }}</span> }
9163
+ </button>
9164
+ }
9165
+ }
9166
+ </div>
9167
+ `,
9168
+ isInline: true,
9169
+ styles: ["ui-import-source-grid{display:block}.ie-source-grid{display:grid;grid-template-columns:repeat(3,1fr);gap:10px}@media(max-width:520px){.ie-source-grid{grid-template-columns:repeat(2,1fr)}}.ie-source-card{display:flex;flex-direction:column;align-items:flex-start;gap:4px;padding:12px;border:1px solid #e2e8f0;border-radius:10px;background:#fff;cursor:pointer;font-family:inherit;text-align:left;transition:all .15s}.ie-source-card:hover{border-color:#94a3b8;background:#f8fafc}.ie-source-card.ie-source-card--active{border-color:#3b82f6;background:#eff6ff}.ie-source-card:focus-visible{outline:2px solid #60a5fa;outline-offset:2px}.ie-source-letter{width:36px;height:36px;border-radius:8px;color:#fff;font-size:1rem;font-weight:700;display:flex;align-items:center;justify-content:center;flex-shrink:0}.ie-source-label{font-size:.8125rem;font-weight:600;color:#1e293b;line-height:1.2}.ie-source-desc{font-size:.75rem;color:#64748b}.ie-source-grid--cards{grid-template-columns:repeat(2,1fr)}@media(max-width:520px){.ie-source-grid--cards{grid-template-columns:1fr}}\n"],
9170
+ dependencies: [{
9171
+ kind: "component",
9172
+ type: OptionCardComponent,
9173
+ selector: "ui-option-card",
9174
+ inputs: [
9175
+ "title",
9176
+ "description",
9177
+ "letter",
9178
+ "icon",
9179
+ "color",
9180
+ "actionLabel",
9181
+ "actionVariant",
9182
+ "actionAriaLabel",
9183
+ "actionTestId",
9184
+ "actionLoading",
9185
+ "disabled"
9186
+ ],
9187
+ outputs: ["action"]
9188
+ }],
9189
+ changeDetection: i0.ChangeDetectionStrategy.OnPush,
9190
+ encapsulation: i0.ViewEncapsulation.None
9191
+ });
9192
+ }
9193
+ };
8910
9194
  i0.ɵɵngDeclareClassMetadata({
8911
9195
  minVersion: "12.0.0",
8912
9196
  version: "22.2.2",
@@ -8919,23 +9203,13 @@ i0.ɵɵngDeclareClassMetadata({
8919
9203
  standalone: true,
8920
9204
  changeDetection: ChangeDetectionStrategy.OnPush,
8921
9205
  encapsulation: ViewEncapsulation.None,
8922
- imports: [ButtonComponent, DetailCardComponent],
9206
+ imports: [OptionCardComponent],
8923
9207
  template: `
8924
9208
  <div class="ie-source-grid" [attr.role]="appearance() === 'card' ? 'group' : 'list'" [class.ie-source-grid--cards]="appearance() === 'card'" [attr.aria-label]="ariaLabel() || null">
8925
9209
  @for (src of sources(); track src.value) {
8926
9210
  @if (appearance() === 'card') {
8927
- <ui-detail-card class="ie-source-detail" [showHeader]="false" [fill]="true" [ariaLabel]="src.label" [attr.data-testid]="'source-' + src.value">
8928
- <div class="ie-source-detail-row">
8929
- @if (src.letter) {
8930
- <span class="ie-source-letter" [style.background]="src.color || '#64748b'" aria-hidden="true">{{ src.letter }}</span>
8931
- }
8932
- <span class="ie-source-detail-text">
8933
- <span class="ie-source-label">{{ src.label }}</span>
8934
- @if (src.desc) { <span class="ie-source-desc">{{ src.desc }}</span> }
8935
- </span>
8936
- <ui-button variant="secondary" size="xs" [attr.data-testid]="'source-pick-' + src.value" [disabled]="disabled()" [ariaLabel]="actionLabel() + ' ' + src.label" (click)="sourceSelect.emit(src.value)">{{ actionLabel() }}</ui-button>
8937
- </div>
8938
- </ui-detail-card>
9211
+ <ui-option-card [attr.data-testid]="'source-' + src.value" [title]="src.label" [description]="src.desc || ''" [letter]="src.letter || ''" [color]="src.color || '#64748b'"
9212
+ [actionLabel]="actionLabel()" [actionTestId]="'source-pick-' + src.value" [disabled]="disabled()" (action)="sourceSelect.emit(src.value)" />
8939
9213
  } @else {
8940
9214
  <button
8941
9215
  class="ie-source-card"
@@ -8955,7 +9229,7 @@ i0.ɵɵngDeclareClassMetadata({
8955
9229
  }
8956
9230
  </div>
8957
9231
  `,
8958
- styles: ["ui-import-source-grid{display:block}.ie-source-grid{display:grid;grid-template-columns:repeat(3,1fr);gap:10px}@media(max-width:520px){.ie-source-grid{grid-template-columns:repeat(2,1fr)}}.ie-source-card{display:flex;flex-direction:column;align-items:flex-start;gap:4px;padding:12px;border:1px solid #e2e8f0;border-radius:10px;background:#fff;cursor:pointer;font-family:inherit;text-align:left;transition:all .15s}.ie-source-card:hover{border-color:#94a3b8;background:#f8fafc}.ie-source-card.ie-source-card--active{border-color:#3b82f6;background:#eff6ff}.ie-source-card:focus-visible{outline:2px solid #60a5fa;outline-offset:2px}.ie-source-letter{width:36px;height:36px;border-radius:8px;color:#fff;font-size:1rem;font-weight:700;display:flex;align-items:center;justify-content:center;flex-shrink:0}.ie-source-label{font-size:.8125rem;font-weight:600;color:#1e293b;line-height:1.2}.ie-source-desc{font-size:.75rem;color:#64748b}.ie-source-grid--cards{grid-template-columns:repeat(2,1fr)}@media(max-width:520px){.ie-source-grid--cards{grid-template-columns:1fr}}ui-import-source-grid .ie-source-detail.ie-source-detail{margin-bottom:0}.ie-source-detail-row{display:flex;align-items:center;gap:12px}.ie-source-detail-text{display:flex;flex-direction:column;gap:2px;flex:1;min-width:0}\n"]
9232
+ styles: ["ui-import-source-grid{display:block}.ie-source-grid{display:grid;grid-template-columns:repeat(3,1fr);gap:10px}@media(max-width:520px){.ie-source-grid{grid-template-columns:repeat(2,1fr)}}.ie-source-card{display:flex;flex-direction:column;align-items:flex-start;gap:4px;padding:12px;border:1px solid #e2e8f0;border-radius:10px;background:#fff;cursor:pointer;font-family:inherit;text-align:left;transition:all .15s}.ie-source-card:hover{border-color:#94a3b8;background:#f8fafc}.ie-source-card.ie-source-card--active{border-color:#3b82f6;background:#eff6ff}.ie-source-card:focus-visible{outline:2px solid #60a5fa;outline-offset:2px}.ie-source-letter{width:36px;height:36px;border-radius:8px;color:#fff;font-size:1rem;font-weight:700;display:flex;align-items:center;justify-content:center;flex-shrink:0}.ie-source-label{font-size:.8125rem;font-weight:600;color:#1e293b;line-height:1.2}.ie-source-desc{font-size:.75rem;color:#64748b}.ie-source-grid--cards{grid-template-columns:repeat(2,1fr)}@media(max-width:520px){.ie-source-grid--cards{grid-template-columns:1fr}}\n"]
8959
9233
  }]
8960
9234
  }],
8961
9235
  propDecorators: {
@@ -18784,7 +19058,7 @@ var ToggleBadgeComponent = class ToggleBadgeComponent {
18784
19058
  {{ label() }}
18785
19059
  </button>
18786
19060
  @if (actions().length > 0) {
18787
- <span class="tb-actions" role="group" [attr.aria-label]="label() + ' actions'">
19061
+ <span class="tb-actions" role="group" [attr.aria-label]="(label() + ' actions').trim()">
18788
19062
  <span class="tb-divider" aria-hidden="true"></span>
18789
19063
  @for (a of actions(); track a.id) {
18790
19064
  <button type="button" class="tb-action" [disabled]="a.disabled ?? false" [attr.aria-label]="a.label" [uiTooltip]="a.tooltip || a.label"
@@ -18797,7 +19071,7 @@ var ToggleBadgeComponent = class ToggleBadgeComponent {
18797
19071
  </span>
18798
19072
  `,
18799
19073
  isInline: true,
18800
- styles: [":host{display:inline-flex}.tb{display:inline-flex;align-items:center;border-radius:999px;border:1px solid #e2e8f0;background:#fff;color:#64748b;transition:all .15s ease}.tb:hover{background:#f8fafc;border-color:#94a3b8}.tb.active{background:#1e293b;color:#fff;border-color:#1e293b}.toggle-badge{display:inline-flex;align-items:center;gap:5px;padding:3px 10px;border-radius:999px;border:none;background:transparent;font-size:.75rem;font-weight:500;color:inherit;cursor:pointer;font-family:inherit;line-height:1}.toggle-badge:focus-visible,.tb-action:focus-visible{outline:2px solid #60a5fa;outline-offset:2px}.tb-has-actions .toggle-badge{padding-right:6px}.tb-actions{display:inline-flex;align-items:center;gap:1px;padding-right:4px}.tb-divider{width:1px;height:12px;background:currentColor;opacity:.25;margin-right:3px}.tb-action{display:inline-flex;align-items:center;justify-content:center;width:20px;height:20px;padding:0;border:none;border-radius:50%;background:transparent;color:inherit;cursor:pointer;opacity:.75;font-family:inherit;transition:background .15s ease,opacity .15s ease}.tb-action:hover:not(:disabled){opacity:1;background:#64748b2e}.tb.active .tb-action:hover:not(:disabled){background:#fff3}.tb-action:disabled{opacity:.35;cursor:not-allowed}@media(pointer:coarse){.tb-action{position:relative}.tb-action:after{content:\"\";position:absolute;inset:-12px}}\n"],
19074
+ styles: [":host{display:inline-flex}.tb{display:inline-flex;align-items:center;border-radius:999px;border:1px solid #e2e8f0;background:#fff;color:#64748b;transition:all .15s ease}.tb:hover{background:#f8fafc;border-color:#94a3b8}.tb.active{background:#1e293b;color:#fff;border-color:#1e293b}.toggle-badge{display:inline-flex;align-items:center;gap:5px;padding:var(--ui-toggle-badge-pad-y, 3px) var(--ui-toggle-badge-pad-x, 10px);border-radius:999px;border:none;background:transparent;font-size:.75rem;font-weight:500;color:inherit;cursor:pointer;font-family:inherit;line-height:1}.toggle-badge:focus-visible,.tb-action:focus-visible{outline:2px solid #60a5fa;outline-offset:2px}.tb-has-actions .toggle-badge{padding-right:6px}.tb-actions{display:inline-flex;align-items:center;gap:1px;padding-right:4px}.tb-divider{width:1px;height:12px;background:currentColor;opacity:.25;margin-right:3px}.tb-action{display:inline-flex;align-items:center;justify-content:center;width:20px;height:20px;padding:0;border:none;border-radius:50%;background:transparent;color:inherit;cursor:pointer;opacity:.75;font-family:inherit;transition:background .15s ease,opacity .15s ease}.tb-action:hover:not(:disabled){opacity:1;background:#64748b2e}.tb.active .tb-action:hover:not(:disabled){background:#fff3}.tb-action:disabled{opacity:.35;cursor:not-allowed}@media(pointer:coarse){.tb-action{position:relative}.tb-action:after{content:\"\";position:absolute;inset:-12px}}\n"],
18801
19075
  dependencies: [{
18802
19076
  kind: "directive",
18803
19077
  type: TooltipDirective,
@@ -18827,7 +19101,7 @@ i0.ɵɵngDeclareClassMetadata({
18827
19101
  {{ label() }}
18828
19102
  </button>
18829
19103
  @if (actions().length > 0) {
18830
- <span class="tb-actions" role="group" [attr.aria-label]="label() + ' actions'">
19104
+ <span class="tb-actions" role="group" [attr.aria-label]="(label() + ' actions').trim()">
18831
19105
  <span class="tb-divider" aria-hidden="true"></span>
18832
19106
  @for (a of actions(); track a.id) {
18833
19107
  <button type="button" class="tb-action" [disabled]="a.disabled ?? false" [attr.aria-label]="a.label" [uiTooltip]="a.tooltip || a.label"
@@ -18839,7 +19113,7 @@ i0.ɵɵngDeclareClassMetadata({
18839
19113
  }
18840
19114
  </span>
18841
19115
  `,
18842
- styles: [":host{display:inline-flex}.tb{display:inline-flex;align-items:center;border-radius:999px;border:1px solid #e2e8f0;background:#fff;color:#64748b;transition:all .15s ease}.tb:hover{background:#f8fafc;border-color:#94a3b8}.tb.active{background:#1e293b;color:#fff;border-color:#1e293b}.toggle-badge{display:inline-flex;align-items:center;gap:5px;padding:3px 10px;border-radius:999px;border:none;background:transparent;font-size:.75rem;font-weight:500;color:inherit;cursor:pointer;font-family:inherit;line-height:1}.toggle-badge:focus-visible,.tb-action:focus-visible{outline:2px solid #60a5fa;outline-offset:2px}.tb-has-actions .toggle-badge{padding-right:6px}.tb-actions{display:inline-flex;align-items:center;gap:1px;padding-right:4px}.tb-divider{width:1px;height:12px;background:currentColor;opacity:.25;margin-right:3px}.tb-action{display:inline-flex;align-items:center;justify-content:center;width:20px;height:20px;padding:0;border:none;border-radius:50%;background:transparent;color:inherit;cursor:pointer;opacity:.75;font-family:inherit;transition:background .15s ease,opacity .15s ease}.tb-action:hover:not(:disabled){opacity:1;background:#64748b2e}.tb.active .tb-action:hover:not(:disabled){background:#fff3}.tb-action:disabled{opacity:.35;cursor:not-allowed}@media(pointer:coarse){.tb-action{position:relative}.tb-action:after{content:\"\";position:absolute;inset:-12px}}\n"]
19116
+ styles: [":host{display:inline-flex}.tb{display:inline-flex;align-items:center;border-radius:999px;border:1px solid #e2e8f0;background:#fff;color:#64748b;transition:all .15s ease}.tb:hover{background:#f8fafc;border-color:#94a3b8}.tb.active{background:#1e293b;color:#fff;border-color:#1e293b}.toggle-badge{display:inline-flex;align-items:center;gap:5px;padding:var(--ui-toggle-badge-pad-y, 3px) var(--ui-toggle-badge-pad-x, 10px);border-radius:999px;border:none;background:transparent;font-size:.75rem;font-weight:500;color:inherit;cursor:pointer;font-family:inherit;line-height:1}.toggle-badge:focus-visible,.tb-action:focus-visible{outline:2px solid #60a5fa;outline-offset:2px}.tb-has-actions .toggle-badge{padding-right:6px}.tb-actions{display:inline-flex;align-items:center;gap:1px;padding-right:4px}.tb-divider{width:1px;height:12px;background:currentColor;opacity:.25;margin-right:3px}.tb-action{display:inline-flex;align-items:center;justify-content:center;width:20px;height:20px;padding:0;border:none;border-radius:50%;background:transparent;color:inherit;cursor:pointer;opacity:.75;font-family:inherit;transition:background .15s ease,opacity .15s ease}.tb-action:hover:not(:disabled){opacity:1;background:#64748b2e}.tb.active .tb-action:hover:not(:disabled){background:#fff3}.tb-action:disabled{opacity:.35;cursor:not-allowed}@media(pointer:coarse){.tb-action{position:relative}.tb-action:after{content:\"\";position:absolute;inset:-12px}}\n"]
18843
19117
  }]
18844
19118
  }],
18845
19119
  propDecorators: {
@@ -42636,6 +42910,8 @@ var SetupWizardComponent = class SetupWizardComponent {
42636
42910
  this.http = inject(HttpClient);
42637
42911
  this.apiBase = inject(FORGEROUTE_CONFIG, { optional: true })?.baseUrl ?? "/api";
42638
42912
  this.destroyRef = inject(DestroyRef);
42913
+ this.narrow = signal(false, ...ngDevMode ? [{ debugName: "narrow" }] : /* istanbul ignore next */ []);
42914
+ this.split = computed(() => this.current().kind !== "custom" && !!this.current().splitLayout && !!this.templateFor(this.current().key), ...ngDevMode ? [{ debugName: "split" }] : /* istanbul ignore next */ []);
42639
42915
  this.steps = input.required(...ngDevMode ? [{ debugName: "steps" }] : /* istanbul ignore next */ []);
42640
42916
  this.texts = input({}, ...ngDevMode ? [{ debugName: "texts" }] : /* istanbul ignore next */ []);
42641
42917
  this.finished = output();
@@ -42643,6 +42919,8 @@ var SetupWizardComponent = class SetupWizardComponent {
42643
42919
  this.stepChange = output();
42644
42920
  this.stepTemplates = contentChildren(SetupWizardStepDirective, ...ngDevMode ? [{ debugName: "stepTemplates" }] : /* istanbul ignore next */ []);
42645
42921
  this.headerTemplates = contentChildren(SetupWizardStepHeaderDirective, ...ngDevMode ? [{ debugName: "headerTemplates" }] : /* istanbul ignore next */ []);
42922
+ this.injector = inject(Injector);
42923
+ this.stepTitle = viewChild("stepTitle", ...ngDevMode ? [{ debugName: "stepTitle" }] : /* istanbul ignore next */ []);
42646
42924
  this.importers = viewChildren("importer", ...ngDevMode ? [{ debugName: "importers" }] : /* istanbul ignore next */ []);
42647
42925
  this.t = computed(() => ({
42648
42926
  ...DEFAULT_TEXTS,
@@ -42696,6 +42974,13 @@ var SetupWizardComponent = class SetupWizardComponent {
42696
42974
  variant: "slate"
42697
42975
  }
42698
42976
  })) }], ...ngDevMode ? [{ debugName: "summarySections" }] : /* istanbul ignore next */ []);
42977
+ if (typeof matchMedia === "function") {
42978
+ const mq = matchMedia("(max-width: 768px)");
42979
+ this.narrow.set(mq.matches);
42980
+ const on = (e) => this.narrow.set(e.matches);
42981
+ mq.addEventListener("change", on);
42982
+ this.destroyRef.onDestroy(() => mq.removeEventListener("change", on));
42983
+ }
42699
42984
  effect(() => {
42700
42985
  const steps = this.allSteps();
42701
42986
  untracked(() => {
@@ -42721,6 +43006,7 @@ var SetupWizardComponent = class SetupWizardComponent {
42721
43006
  if (step.kind === "integrations") this.loadStatuses(step.integrations ?? []);
42722
43007
  step.onEnter?.();
42723
43008
  this.stepChange.emit(key);
43009
+ afterNextRender(() => this.stepTitle()?.nativeElement.focus(), { injector: this.injector });
42724
43010
  }
42725
43011
  advanceFrom(key) {
42726
43012
  const steps = this.allSteps();
@@ -42837,6 +43123,20 @@ var SetupWizardComponent = class SetupWizardComponent {
42837
43123
  this.error.set("");
42838
43124
  this.areaCodeOpen.set("");
42839
43125
  this.areaCode.set("");
43126
+ if (!i.beforeConnect) {
43127
+ this.startConnect(i);
43128
+ return;
43129
+ }
43130
+ this.busy.set(true);
43131
+ this.run(i.beforeConnect()).then(() => {
43132
+ this.busy.set(false);
43133
+ this.startConnect(i);
43134
+ }, (e) => {
43135
+ this.busy.set(false);
43136
+ this.error.set(this.messageOf(e, this.t().connectIntegrationFailed(i.title)));
43137
+ });
43138
+ }
43139
+ startConnect(i) {
42840
43140
  if (i.connect.type === "area-code") {
42841
43141
  this.areaCodeOpen.set(i.key);
42842
43142
  return;
@@ -42923,6 +43223,12 @@ var SetupWizardComponent = class SetupWizardComponent {
42923
43223
  isSignal: true
42924
43224
  }],
42925
43225
  viewQueries: [{
43226
+ propertyName: "stepTitle",
43227
+ first: true,
43228
+ predicate: ["stepTitle"],
43229
+ descendants: true,
43230
+ isSignal: true
43231
+ }, {
42926
43232
  propertyName: "importers",
42927
43233
  predicate: ["importer"],
42928
43234
  descendants: true,
@@ -42931,7 +43237,7 @@ var SetupWizardComponent = class SetupWizardComponent {
42931
43237
  ngImport: i0,
42932
43238
  template: `
42933
43239
  <div class="sw-page" data-testid="setup-wizard-page">
42934
- <aside class="sw-sidebar">
43240
+ <aside class="sw-sidebar" [attr.aria-label]="t().brand">
42935
43241
  <div class="sw-sidebar-top">
42936
43242
  <div class="sw-brand">
42937
43243
  <ng-content select="[setup-wizard-logo]" />
@@ -42948,7 +43254,7 @@ var SetupWizardComponent = class SetupWizardComponent {
42948
43254
 
42949
43255
  <main class="sw-content">
42950
43256
  <div class="sw-content-header">
42951
- <h1 class="sw-step-title" data-testid="wizard-step-title">{{ current().label }}</h1>
43257
+ <h1 #stepTitle class="sw-step-title" tabindex="-1" data-testid="wizard-step-title">{{ current().label }}</h1>
42952
43258
  <ui-button variant="ghost" size="sm" data-testid="wizard-exit" (click)="exited.emit()"><svg class="sw-ico" width="14" height="14" viewBox="0 0 24 24" fill="none" stroke="currentColor" stroke-width="2" stroke-linecap="round" stroke-linejoin="round" aria-hidden="true" focusable="false"><path [attr.d]="iconD('close')" /></svg> {{ t().exit }}</ui-button>
42953
43259
  </div>
42954
43260
 
@@ -42960,15 +43266,22 @@ var SetupWizardComponent = class SetupWizardComponent {
42960
43266
  <ui-button variant="primary" size="sm" data-testid="wizard-finish" (click)="finished.emit()"><svg class="sw-ico" width="14" height="14" viewBox="0 0 24 24" fill="none" stroke="currentColor" stroke-width="2" stroke-linecap="round" stroke-linejoin="round" aria-hidden="true" focusable="false"><path [attr.d]="iconD('check')" /></svg> {{ t().finish }}</ui-button>
42961
43267
  </div>
42962
43268
  } @else {
42963
- <div class="sw-step-content" [attr.data-step]="current().key">
43269
+ <div class="sw-step-content" [class.sw-wide]="split()" [attr.aria-busy]="busy()" [attr.data-step]="current().key">
42964
43270
  @if (intro(); as i) { <ui-section-header class="sw-intro" data-testid="wizard-step-intro" size="lg" background="#eaf3ff" [title]="i.title" [description]="i.text"><span section-header-icon class="sw-step-number" data-testid="wizard-step-number">{{ index() + 1 }}</span></ui-section-header> }
42965
43271
 
43272
+ <div class="sw-body" [class.sw-split]="split()" data-testid="wizard-body">
43273
+ @if (split() && templateFor(current().key); as left) {
43274
+ <ui-detail-card class="sw-card sw-extra-card" [title]="current().extraTitle ?? ''" [showHeader]="!!current().extraTitle" [headingLevel]="3" [collapsible]="false"
43275
+ [ariaLabel]="current().extraTitle || current().label" headerBackground="rgb(248, 250, 252)" data-testid="wizard-extra-card">
43276
+ <ng-container [ngTemplateOutlet]="left" [ngTemplateOutletContext]="{ $implicit: api }" />
43277
+ </ui-detail-card>
43278
+ }
42966
43279
  <ui-detail-card class="sw-card" [showHeader]="!!current().cardTitle || !!headerTemplateFor(current().key)" [title]="current().cardTitle ?? ''" [headingLevel]="3" [collapsible]="false"
42967
43280
  [ariaLabel]="current().label" headerBackground="rgb(248, 250, 252)" footerBackground="rgb(248, 250, 252)" data-testid="wizard-step-card">
42968
43281
  @if (headerTemplateFor(current().key); as ht) {
42969
43282
  <div card-header-action class="sw-header-action" data-testid="wizard-card-header-action"><ng-container [ngTemplateOutlet]="ht" [ngTemplateOutletContext]="{ $implicit: api }" /></div>
42970
43283
  }
42971
- @if (current().kind !== 'custom' && templateFor(current().key); as extra) {
43284
+ @if (!split() && current().kind !== 'custom' && templateFor(current().key); as extra) {
42972
43285
  <ng-container [ngTemplateOutlet]="extra" [ngTemplateOutletContext]="{ $implicit: api }" />
42973
43286
  }
42974
43287
  @switch (current().kind) {
@@ -43002,22 +43315,16 @@ var SetupWizardComponent = class SetupWizardComponent {
43002
43315
  @case ('integrations') {
43003
43316
  <div class="sw-provider-grid">
43004
43317
  @for (it of current().integrations ?? []; track it.key) {
43005
- <ui-detail-card class="sw-integration" [attr.data-testid]="'integration-' + it.key" [showHeader]="false" [fill]="true" [ariaLabel]="it.title">
43006
- <div class="sw-int-row">
43007
- <span class="sw-int-tile" [style.background]="it.color || '#64748b'" aria-hidden="true">@if (it.letter) { {{ it.letter }} } @else { <svg width="18" height="18" viewBox="0 0 24 24" fill="none" stroke="currentColor" stroke-width="2" stroke-linecap="round" stroke-linejoin="round" focusable="false"><path [attr.d]="iconD(it.icon ?? 'link')" /></svg> }</span>
43008
- <span class="sw-int-text">
43009
- <span class="sw-int-title">{{ it.title }}</span>
43010
- <span class="sw-int-detail">{{ detailFor(it) }}</span>
43011
- </span>
43012
- <ui-button variant="secondary" size="xs" [attr.data-testid]="'integration-pick-' + it.key" [ariaLabel]="(isConnected(it) ? t().reconnect : t().connect) + ' ' + it.title" (click)="connect(it)">{{ isConnected(it) ? t().reconnect : t().connect }}</ui-button>
43013
- </div>
43318
+ <ui-option-card class="sw-integration" [attr.data-testid]="'integration-' + it.key" [title]="it.title" [description]="detailFor(it)" [letter]="it.letter || ''"
43319
+ [icon]="it.letter ? '' : (it.icon ?? 'link')" [color]="it.color || '#64748b'" [actionLabel]="isConnected(it) ? t().reconnect : t().connect"
43320
+ [actionTestId]="'integration-pick-' + it.key" (action)="connect(it)">
43014
43321
  @if (areaCodeOpen() === it.key) {
43015
43322
  <div class="sw-area-code" [attr.data-testid]="'area-code-' + it.key">
43016
43323
  <ui-text-input [label]="areaCodeLabelFor(it)" [maxlength]="3" inputmode="numeric" [ngModel]="areaCode()" (ngModelChange)="areaCode.set($event ?? '')" [inputTestId]="'area-code-input-' + it.key" />
43017
43324
  <ui-button variant="primary" size="sm" [loading]="busy()" [disabled]="!validAreaCode()" (click)="submitAreaCode(it)"><svg class="sw-ico" width="14" height="14" viewBox="0 0 24 24" fill="none" stroke="currentColor" stroke-width="2" stroke-linecap="round" stroke-linejoin="round" aria-hidden="true" focusable="false"><path [attr.d]="iconD('link')" /></svg> {{ t().connect }}</ui-button>
43018
43325
  </div>
43019
43326
  }
43020
- </ui-detail-card>
43327
+ </ui-option-card>
43021
43328
  }
43022
43329
  </div>
43023
43330
  }
@@ -43026,32 +43333,33 @@ var SetupWizardComponent = class SetupWizardComponent {
43026
43333
  @if (error()) { <ui-alert variant="danger" data-testid="wizard-save-error">{{ error() }}</ui-alert> }
43027
43334
 
43028
43335
  <div card-footer class="sw-step-actions">
43029
- @if (index() > 0) { <ui-button variant="secondary" size="sm" data-testid="wizard-back" [disabled]="busy()" (click)="back()"><svg class="sw-ico" width="14" height="14" viewBox="0 0 24 24" fill="none" stroke="currentColor" stroke-width="2" stroke-linecap="round" stroke-linejoin="round" aria-hidden="true" focusable="false"><path [attr.d]="iconD('arrow-left')" /></svg> {{ t().back }}</ui-button> } @else { <span></span> }
43336
+ @if (index() > 0) { <ui-button variant="secondary" size="sm" [fullWidth]="narrow()" data-testid="wizard-back" [disabled]="busy()" (click)="back()"><svg class="sw-ico" width="14" height="14" viewBox="0 0 24 24" fill="none" stroke="currentColor" stroke-width="2" stroke-linecap="round" stroke-linejoin="round" aria-hidden="true" focusable="false"><path [attr.d]="iconD('arrow-left')" /></svg> {{ t().back }}</ui-button> } @else { <span></span> }
43030
43337
  <div class="sw-actions-right">
43031
43338
  @if (current().skippable !== false) {
43032
- <ui-button variant="secondary" size="sm" data-testid="wizard-skip" [disabled]="busy()" (click)="skip()">{{ t().skip }} <svg class="sw-ico" width="14" height="14" viewBox="0 0 24 24" fill="none" stroke="currentColor" stroke-width="2" stroke-linecap="round" stroke-linejoin="round" aria-hidden="true" focusable="false"><path [attr.d]="iconD('chevron-right')" /></svg></ui-button>
43339
+ <ui-button variant="secondary" size="sm" [fullWidth]="narrow()" data-testid="wizard-skip" [disabled]="busy()" (click)="skip()">{{ t().skip }} <svg class="sw-ico" width="14" height="14" viewBox="0 0 24 24" fill="none" stroke="currentColor" stroke-width="2" stroke-linecap="round" stroke-linejoin="round" aria-hidden="true" focusable="false"><path [attr.d]="iconD('chevron-right')" /></svg></ui-button>
43033
43340
  }
43034
43341
  @if (current().kind === 'custom') {
43035
43342
  @if (!current().ownActions) {
43036
- <ui-button variant="primary" size="sm" data-testid="wizard-save" [loading]="busy()" [disabled]="current().canContinue ? !current().canContinue!() : false" (click)="saveAndContinue()">
43343
+ <ui-button variant="primary" size="sm" [fullWidth]="narrow()" data-testid="wizard-save" [loading]="busy()" [disabled]="current().canContinue ? !current().canContinue!() : false" (click)="saveAndContinue()">
43037
43344
  {{ current().saveLabel ?? t().saveAndContinue }} <svg class="sw-ico" width="14" height="14" viewBox="0 0 24 24" fill="none" stroke="currentColor" stroke-width="2" stroke-linecap="round" stroke-linejoin="round" aria-hidden="true" focusable="false"><path [attr.d]="iconD('arrow-right')" /></svg>
43038
43345
  </ui-button>
43039
43346
  }
43040
43347
  } @else if (current().kind === 'integrations') {
43041
- <ui-button variant="primary" size="sm" data-testid="wizard-save" [loading]="busy()" (click)="saveAndContinue()">{{ t().saveAndContinue }} <svg class="sw-ico" width="14" height="14" viewBox="0 0 24 24" fill="none" stroke="currentColor" stroke-width="2" stroke-linecap="round" stroke-linejoin="round" aria-hidden="true" focusable="false"><path [attr.d]="iconD('arrow-right')" /></svg></ui-button>
43348
+ <ui-button variant="primary" size="sm" [fullWidth]="narrow()" data-testid="wizard-save" [loading]="busy()" (click)="saveAndContinue()">{{ t().saveAndContinue }} <svg class="sw-ico" width="14" height="14" viewBox="0 0 24 24" fill="none" stroke="currentColor" stroke-width="2" stroke-linecap="round" stroke-linejoin="round" aria-hidden="true" focusable="false"><path [attr.d]="iconD('arrow-right')" /></svg></ui-button>
43042
43349
  } @else if (current().kind === 'import') {
43043
- <ui-button variant="primary" size="sm" data-testid="wizard-continue" (click)="continueFromImport()">{{ t().continue }} <svg class="sw-ico" width="14" height="14" viewBox="0 0 24 24" fill="none" stroke="currentColor" stroke-width="2" stroke-linecap="round" stroke-linejoin="round" aria-hidden="true" focusable="false"><path [attr.d]="iconD('arrow-right')" /></svg></ui-button>
43350
+ <ui-button variant="primary" size="sm" [fullWidth]="narrow()" data-testid="wizard-continue" (click)="continueFromImport()">{{ t().continue }} <svg class="sw-ico" width="14" height="14" viewBox="0 0 24 24" fill="none" stroke="currentColor" stroke-width="2" stroke-linecap="round" stroke-linejoin="round" aria-hidden="true" focusable="false"><path [attr.d]="iconD('arrow-right')" /></svg></ui-button>
43044
43351
  }
43045
43352
  </div>
43046
43353
  </div>
43047
43354
  </ui-detail-card>
43355
+ </div>
43048
43356
  </div>
43049
43357
  }
43050
43358
  </main>
43051
43359
  </div>
43052
43360
  `,
43053
43361
  isInline: true,
43054
- styles: [".sw-page{display:flex;min-height:100vh;font-family:Inter,-apple-system,BlinkMacSystemFont,Segoe UI,sans-serif}.sw-sidebar{width:260px;min-width:260px;background:#faf9f7;border-right:1px solid #e5e2dc;display:flex;flex-direction:column;justify-content:space-between;padding:28px 20px}.sw-brand{display:flex;align-items:center;gap:10px;margin-bottom:28px}.sw-brand-text{font-size:1.125rem;font-weight:700;color:#1e293b}.sw-step-nav{display:block}.sw-sidebar-bottom{margin-top:24px}.sw-progress-text{display:block;margin-top:8px;font-size:.75rem;color:#94a3b8}.sw-content{flex:1;min-width:0;background:#fff;display:flex;flex-direction:column;overflow-y:auto}.sw-content-header{display:flex;justify-content:space-between;align-items:center;gap:16px;padding:20px 32px;border-bottom:1px solid #f1f5f9}.sw-step-title{font-size:1.25rem;font-weight:700;color:#111827;margin:0}.sw-step-content{max-width:780px;padding:16px 48px 60px}.sw-intro{margin-bottom:24px}.sw-step-number{font-size:1.25rem;font-weight:800;line-height:1}.sw-step-desc{font-size:.9375rem;color:#6b7280;line-height:1.5;margin:0 0 32px}.sw-hint{font-size:.8125rem;color:#94a3b8;margin:0 0 16px}.sw-import-tags{display:flex;flex-wrap:wrap;align-items:center;gap:8px;margin-bottom:28px}.sw-tag{font-size:.6875rem;font-weight:700;letter-spacing:1px;color:#6b7280}.sw-provider-grid{display:grid;grid-template-columns:repeat(2,1fr);gap:10px;margin-bottom:8px}@media(max-width:768px){.sw-provider-grid{grid-template-columns:1fr}}.sw-provider-grid .sw-integration{margin-bottom:0}.sw-int-row{display:flex;align-items:center;gap:12px}.sw-int-tile{width:36px;height:36px;border-radius:8px;color:#fff;font-size:1rem;font-weight:700;display:flex;align-items:center;justify-content:center;flex-shrink:0}.sw-int-text{display:flex;flex-direction:column;gap:2px;flex:1;min-width:0}.sw-int-title{font-size:.8125rem;font-weight:600;color:#1e293b;line-height:1.2}.sw-int-detail{font-size:.75rem;color:#64748b;overflow-wrap:anywhere}.sw-area-code{display:flex;align-items:flex-end;gap:12px;margin-top:12px;max-width:320px}.sw-area-code ui-text-input{flex:1}.sw-content ui-alert{display:block;margin-bottom:16px}.sw-card{display:block}.sw-header-action{margin-left:auto;min-width:0;max-width:100%}.sw-step-actions{display:flex;justify-content:space-between;align-items:center}.sw-ico{flex-shrink:0;vertical-align:-2px}.sw-actions-right{display:flex;align-items:center;gap:16px}.sw-done{text-align:center;display:flex;flex-direction:column;align-items:center;max-width:none}.sw-done .sw-step-desc{max-width:480px}.sw-summary{display:block;width:100%;max-width:480px;margin-bottom:24px;text-align:left}.sw-done-hint{font-size:.8125rem;color:#9ca3af;margin-bottom:24px}@media(max-width:768px){.sw-page{flex-direction:column}.sw-sidebar{width:100%;min-width:unset;padding:16px}.sw-brand{margin-bottom:12px}.sw-sidebar-bottom{display:none}.sw-step-content{padding:12px 20px 40px}}\n"],
43362
+ styles: [".sw-page{display:flex;min-height:100vh;min-height:100dvh;font-family:Inter,-apple-system,BlinkMacSystemFont,Segoe UI,sans-serif}.sw-sidebar{width:260px;min-width:260px;background:#faf9f7;border-right:1px solid #e5e2dc;display:flex;flex-direction:column;justify-content:space-between;padding:28px 20px}.sw-brand{display:flex;align-items:center;gap:10px;margin-bottom:28px}.sw-brand-text{font-size:1.125rem;font-weight:700;color:#1e293b}.sw-step-nav{display:block}.sw-sidebar-bottom{margin-top:24px}.sw-progress-text{display:block;margin-top:8px;font-size:.75rem;color:#94a3b8}.sw-content{flex:1;min-width:0;background:#fff;display:flex;flex-direction:column;overflow-y:auto}.sw-content-header{display:flex;justify-content:space-between;align-items:center;gap:16px;padding:20px 32px;border-bottom:1px solid #f1f5f9}.sw-step-title{font-size:1.25rem;font-weight:700;color:#111827;margin:0}.sw-step-content{max-width:780px;padding:16px 48px 60px}@media(min-width:1100px){.sw-step-content.sw-wide{max-width:1400px}}.sw-intro{margin-bottom:24px}.sw-step-number{font-size:1.25rem;font-weight:800;line-height:1}.sw-step-desc{font-size:.9375rem;color:#6b7280;line-height:1.5;margin:0 0 32px}.sw-body{display:block}.sw-body.sw-split{display:grid;grid-template-columns:1fr;gap:24px}@media(min-width:1100px){.sw-body.sw-split{grid-template-columns:1fr 1fr;align-items:start}}.sw-body>.sw-card{min-width:0}.sw-hint{font-size:.8125rem;color:#94a3b8;margin:0 0 16px}.sw-import-tags{display:flex;flex-wrap:wrap;align-items:center;gap:8px;margin-bottom:28px}.sw-tag{font-size:.6875rem;font-weight:700;letter-spacing:1px;color:#6b7280}.sw-provider-grid{display:grid;grid-template-columns:repeat(2,1fr);gap:10px;margin-bottom:8px}@media(max-width:768px){.sw-provider-grid{grid-template-columns:1fr}}.sw-provider-grid .sw-integration{margin-bottom:0}.sw-area-code{display:flex;align-items:flex-end;gap:12px;margin-top:12px;max-width:320px}.sw-area-code ui-text-input{flex:1}.sw-content ui-alert{display:block;margin-bottom:16px}.sw-card{display:block}.sw-header-action{margin-left:auto;min-width:0;max-width:100%}.sw-step-actions{display:flex;justify-content:space-between;align-items:center}.sw-ico{flex-shrink:0;vertical-align:-2px}.sw-actions-right{display:flex;align-items:center;gap:16px}.sw-done{text-align:center;display:flex;flex-direction:column;align-items:center;max-width:none}.sw-done .sw-step-desc{max-width:480px}.sw-summary{display:block;width:100%;max-width:480px;margin-bottom:24px;text-align:left}.sw-done-hint{font-size:.8125rem;color:#9ca3af;margin-bottom:24px}@media(max-width:768px){.sw-step-actions,.sw-actions-right{flex-direction:column-reverse;align-items:stretch;gap:10px}.sw-page{flex-direction:column}.sw-sidebar{width:100%;min-width:unset;padding:16px}.sw-brand{margin-bottom:12px}.sw-sidebar-bottom{display:none}.sw-step-content{padding:12px 20px 40px}}\n"],
43055
43363
  dependencies: [
43056
43364
  {
43057
43365
  kind: "directive",
@@ -43203,6 +43511,25 @@ var SetupWizardComponent = class SetupWizardComponent {
43203
43511
  ],
43204
43512
  outputs: ["sourceSelect"]
43205
43513
  },
43514
+ {
43515
+ kind: "component",
43516
+ type: OptionCardComponent,
43517
+ selector: "ui-option-card",
43518
+ inputs: [
43519
+ "title",
43520
+ "description",
43521
+ "letter",
43522
+ "icon",
43523
+ "color",
43524
+ "actionLabel",
43525
+ "actionVariant",
43526
+ "actionAriaLabel",
43527
+ "actionTestId",
43528
+ "actionLoading",
43529
+ "disabled"
43530
+ ],
43531
+ outputs: ["action"]
43532
+ },
43206
43533
  {
43207
43534
  kind: "component",
43208
43535
  type: PanelInfoListComponent,
@@ -43341,6 +43668,7 @@ i0.ɵɵngDeclareClassMetadata({
43341
43668
  ImportExportComponent,
43342
43669
  DetailCardComponent,
43343
43670
  ImportSourceGridComponent,
43671
+ OptionCardComponent,
43344
43672
  PanelInfoListComponent,
43345
43673
  ProgressBarComponent,
43346
43674
  SectionHeaderComponent,
@@ -43349,7 +43677,7 @@ i0.ɵɵngDeclareClassMetadata({
43349
43677
  ],
43350
43678
  template: `
43351
43679
  <div class="sw-page" data-testid="setup-wizard-page">
43352
- <aside class="sw-sidebar">
43680
+ <aside class="sw-sidebar" [attr.aria-label]="t().brand">
43353
43681
  <div class="sw-sidebar-top">
43354
43682
  <div class="sw-brand">
43355
43683
  <ng-content select="[setup-wizard-logo]" />
@@ -43366,7 +43694,7 @@ i0.ɵɵngDeclareClassMetadata({
43366
43694
 
43367
43695
  <main class="sw-content">
43368
43696
  <div class="sw-content-header">
43369
- <h1 class="sw-step-title" data-testid="wizard-step-title">{{ current().label }}</h1>
43697
+ <h1 #stepTitle class="sw-step-title" tabindex="-1" data-testid="wizard-step-title">{{ current().label }}</h1>
43370
43698
  <ui-button variant="ghost" size="sm" data-testid="wizard-exit" (click)="exited.emit()"><svg class="sw-ico" width="14" height="14" viewBox="0 0 24 24" fill="none" stroke="currentColor" stroke-width="2" stroke-linecap="round" stroke-linejoin="round" aria-hidden="true" focusable="false"><path [attr.d]="iconD('close')" /></svg> {{ t().exit }}</ui-button>
43371
43699
  </div>
43372
43700
 
@@ -43378,15 +43706,22 @@ i0.ɵɵngDeclareClassMetadata({
43378
43706
  <ui-button variant="primary" size="sm" data-testid="wizard-finish" (click)="finished.emit()"><svg class="sw-ico" width="14" height="14" viewBox="0 0 24 24" fill="none" stroke="currentColor" stroke-width="2" stroke-linecap="round" stroke-linejoin="round" aria-hidden="true" focusable="false"><path [attr.d]="iconD('check')" /></svg> {{ t().finish }}</ui-button>
43379
43707
  </div>
43380
43708
  } @else {
43381
- <div class="sw-step-content" [attr.data-step]="current().key">
43709
+ <div class="sw-step-content" [class.sw-wide]="split()" [attr.aria-busy]="busy()" [attr.data-step]="current().key">
43382
43710
  @if (intro(); as i) { <ui-section-header class="sw-intro" data-testid="wizard-step-intro" size="lg" background="#eaf3ff" [title]="i.title" [description]="i.text"><span section-header-icon class="sw-step-number" data-testid="wizard-step-number">{{ index() + 1 }}</span></ui-section-header> }
43383
43711
 
43712
+ <div class="sw-body" [class.sw-split]="split()" data-testid="wizard-body">
43713
+ @if (split() && templateFor(current().key); as left) {
43714
+ <ui-detail-card class="sw-card sw-extra-card" [title]="current().extraTitle ?? ''" [showHeader]="!!current().extraTitle" [headingLevel]="3" [collapsible]="false"
43715
+ [ariaLabel]="current().extraTitle || current().label" headerBackground="rgb(248, 250, 252)" data-testid="wizard-extra-card">
43716
+ <ng-container [ngTemplateOutlet]="left" [ngTemplateOutletContext]="{ $implicit: api }" />
43717
+ </ui-detail-card>
43718
+ }
43384
43719
  <ui-detail-card class="sw-card" [showHeader]="!!current().cardTitle || !!headerTemplateFor(current().key)" [title]="current().cardTitle ?? ''" [headingLevel]="3" [collapsible]="false"
43385
43720
  [ariaLabel]="current().label" headerBackground="rgb(248, 250, 252)" footerBackground="rgb(248, 250, 252)" data-testid="wizard-step-card">
43386
43721
  @if (headerTemplateFor(current().key); as ht) {
43387
43722
  <div card-header-action class="sw-header-action" data-testid="wizard-card-header-action"><ng-container [ngTemplateOutlet]="ht" [ngTemplateOutletContext]="{ $implicit: api }" /></div>
43388
43723
  }
43389
- @if (current().kind !== 'custom' && templateFor(current().key); as extra) {
43724
+ @if (!split() && current().kind !== 'custom' && templateFor(current().key); as extra) {
43390
43725
  <ng-container [ngTemplateOutlet]="extra" [ngTemplateOutletContext]="{ $implicit: api }" />
43391
43726
  }
43392
43727
  @switch (current().kind) {
@@ -43420,22 +43755,16 @@ i0.ɵɵngDeclareClassMetadata({
43420
43755
  @case ('integrations') {
43421
43756
  <div class="sw-provider-grid">
43422
43757
  @for (it of current().integrations ?? []; track it.key) {
43423
- <ui-detail-card class="sw-integration" [attr.data-testid]="'integration-' + it.key" [showHeader]="false" [fill]="true" [ariaLabel]="it.title">
43424
- <div class="sw-int-row">
43425
- <span class="sw-int-tile" [style.background]="it.color || '#64748b'" aria-hidden="true">@if (it.letter) { {{ it.letter }} } @else { <svg width="18" height="18" viewBox="0 0 24 24" fill="none" stroke="currentColor" stroke-width="2" stroke-linecap="round" stroke-linejoin="round" focusable="false"><path [attr.d]="iconD(it.icon ?? 'link')" /></svg> }</span>
43426
- <span class="sw-int-text">
43427
- <span class="sw-int-title">{{ it.title }}</span>
43428
- <span class="sw-int-detail">{{ detailFor(it) }}</span>
43429
- </span>
43430
- <ui-button variant="secondary" size="xs" [attr.data-testid]="'integration-pick-' + it.key" [ariaLabel]="(isConnected(it) ? t().reconnect : t().connect) + ' ' + it.title" (click)="connect(it)">{{ isConnected(it) ? t().reconnect : t().connect }}</ui-button>
43431
- </div>
43758
+ <ui-option-card class="sw-integration" [attr.data-testid]="'integration-' + it.key" [title]="it.title" [description]="detailFor(it)" [letter]="it.letter || ''"
43759
+ [icon]="it.letter ? '' : (it.icon ?? 'link')" [color]="it.color || '#64748b'" [actionLabel]="isConnected(it) ? t().reconnect : t().connect"
43760
+ [actionTestId]="'integration-pick-' + it.key" (action)="connect(it)">
43432
43761
  @if (areaCodeOpen() === it.key) {
43433
43762
  <div class="sw-area-code" [attr.data-testid]="'area-code-' + it.key">
43434
43763
  <ui-text-input [label]="areaCodeLabelFor(it)" [maxlength]="3" inputmode="numeric" [ngModel]="areaCode()" (ngModelChange)="areaCode.set($event ?? '')" [inputTestId]="'area-code-input-' + it.key" />
43435
43764
  <ui-button variant="primary" size="sm" [loading]="busy()" [disabled]="!validAreaCode()" (click)="submitAreaCode(it)"><svg class="sw-ico" width="14" height="14" viewBox="0 0 24 24" fill="none" stroke="currentColor" stroke-width="2" stroke-linecap="round" stroke-linejoin="round" aria-hidden="true" focusable="false"><path [attr.d]="iconD('link')" /></svg> {{ t().connect }}</ui-button>
43436
43765
  </div>
43437
43766
  }
43438
- </ui-detail-card>
43767
+ </ui-option-card>
43439
43768
  }
43440
43769
  </div>
43441
43770
  }
@@ -43444,31 +43773,32 @@ i0.ɵɵngDeclareClassMetadata({
43444
43773
  @if (error()) { <ui-alert variant="danger" data-testid="wizard-save-error">{{ error() }}</ui-alert> }
43445
43774
 
43446
43775
  <div card-footer class="sw-step-actions">
43447
- @if (index() > 0) { <ui-button variant="secondary" size="sm" data-testid="wizard-back" [disabled]="busy()" (click)="back()"><svg class="sw-ico" width="14" height="14" viewBox="0 0 24 24" fill="none" stroke="currentColor" stroke-width="2" stroke-linecap="round" stroke-linejoin="round" aria-hidden="true" focusable="false"><path [attr.d]="iconD('arrow-left')" /></svg> {{ t().back }}</ui-button> } @else { <span></span> }
43776
+ @if (index() > 0) { <ui-button variant="secondary" size="sm" [fullWidth]="narrow()" data-testid="wizard-back" [disabled]="busy()" (click)="back()"><svg class="sw-ico" width="14" height="14" viewBox="0 0 24 24" fill="none" stroke="currentColor" stroke-width="2" stroke-linecap="round" stroke-linejoin="round" aria-hidden="true" focusable="false"><path [attr.d]="iconD('arrow-left')" /></svg> {{ t().back }}</ui-button> } @else { <span></span> }
43448
43777
  <div class="sw-actions-right">
43449
43778
  @if (current().skippable !== false) {
43450
- <ui-button variant="secondary" size="sm" data-testid="wizard-skip" [disabled]="busy()" (click)="skip()">{{ t().skip }} <svg class="sw-ico" width="14" height="14" viewBox="0 0 24 24" fill="none" stroke="currentColor" stroke-width="2" stroke-linecap="round" stroke-linejoin="round" aria-hidden="true" focusable="false"><path [attr.d]="iconD('chevron-right')" /></svg></ui-button>
43779
+ <ui-button variant="secondary" size="sm" [fullWidth]="narrow()" data-testid="wizard-skip" [disabled]="busy()" (click)="skip()">{{ t().skip }} <svg class="sw-ico" width="14" height="14" viewBox="0 0 24 24" fill="none" stroke="currentColor" stroke-width="2" stroke-linecap="round" stroke-linejoin="round" aria-hidden="true" focusable="false"><path [attr.d]="iconD('chevron-right')" /></svg></ui-button>
43451
43780
  }
43452
43781
  @if (current().kind === 'custom') {
43453
43782
  @if (!current().ownActions) {
43454
- <ui-button variant="primary" size="sm" data-testid="wizard-save" [loading]="busy()" [disabled]="current().canContinue ? !current().canContinue!() : false" (click)="saveAndContinue()">
43783
+ <ui-button variant="primary" size="sm" [fullWidth]="narrow()" data-testid="wizard-save" [loading]="busy()" [disabled]="current().canContinue ? !current().canContinue!() : false" (click)="saveAndContinue()">
43455
43784
  {{ current().saveLabel ?? t().saveAndContinue }} <svg class="sw-ico" width="14" height="14" viewBox="0 0 24 24" fill="none" stroke="currentColor" stroke-width="2" stroke-linecap="round" stroke-linejoin="round" aria-hidden="true" focusable="false"><path [attr.d]="iconD('arrow-right')" /></svg>
43456
43785
  </ui-button>
43457
43786
  }
43458
43787
  } @else if (current().kind === 'integrations') {
43459
- <ui-button variant="primary" size="sm" data-testid="wizard-save" [loading]="busy()" (click)="saveAndContinue()">{{ t().saveAndContinue }} <svg class="sw-ico" width="14" height="14" viewBox="0 0 24 24" fill="none" stroke="currentColor" stroke-width="2" stroke-linecap="round" stroke-linejoin="round" aria-hidden="true" focusable="false"><path [attr.d]="iconD('arrow-right')" /></svg></ui-button>
43788
+ <ui-button variant="primary" size="sm" [fullWidth]="narrow()" data-testid="wizard-save" [loading]="busy()" (click)="saveAndContinue()">{{ t().saveAndContinue }} <svg class="sw-ico" width="14" height="14" viewBox="0 0 24 24" fill="none" stroke="currentColor" stroke-width="2" stroke-linecap="round" stroke-linejoin="round" aria-hidden="true" focusable="false"><path [attr.d]="iconD('arrow-right')" /></svg></ui-button>
43460
43789
  } @else if (current().kind === 'import') {
43461
- <ui-button variant="primary" size="sm" data-testid="wizard-continue" (click)="continueFromImport()">{{ t().continue }} <svg class="sw-ico" width="14" height="14" viewBox="0 0 24 24" fill="none" stroke="currentColor" stroke-width="2" stroke-linecap="round" stroke-linejoin="round" aria-hidden="true" focusable="false"><path [attr.d]="iconD('arrow-right')" /></svg></ui-button>
43790
+ <ui-button variant="primary" size="sm" [fullWidth]="narrow()" data-testid="wizard-continue" (click)="continueFromImport()">{{ t().continue }} <svg class="sw-ico" width="14" height="14" viewBox="0 0 24 24" fill="none" stroke="currentColor" stroke-width="2" stroke-linecap="round" stroke-linejoin="round" aria-hidden="true" focusable="false"><path [attr.d]="iconD('arrow-right')" /></svg></ui-button>
43462
43791
  }
43463
43792
  </div>
43464
43793
  </div>
43465
43794
  </ui-detail-card>
43795
+ </div>
43466
43796
  </div>
43467
43797
  }
43468
43798
  </main>
43469
43799
  </div>
43470
43800
  `,
43471
- styles: [".sw-page{display:flex;min-height:100vh;font-family:Inter,-apple-system,BlinkMacSystemFont,Segoe UI,sans-serif}.sw-sidebar{width:260px;min-width:260px;background:#faf9f7;border-right:1px solid #e5e2dc;display:flex;flex-direction:column;justify-content:space-between;padding:28px 20px}.sw-brand{display:flex;align-items:center;gap:10px;margin-bottom:28px}.sw-brand-text{font-size:1.125rem;font-weight:700;color:#1e293b}.sw-step-nav{display:block}.sw-sidebar-bottom{margin-top:24px}.sw-progress-text{display:block;margin-top:8px;font-size:.75rem;color:#94a3b8}.sw-content{flex:1;min-width:0;background:#fff;display:flex;flex-direction:column;overflow-y:auto}.sw-content-header{display:flex;justify-content:space-between;align-items:center;gap:16px;padding:20px 32px;border-bottom:1px solid #f1f5f9}.sw-step-title{font-size:1.25rem;font-weight:700;color:#111827;margin:0}.sw-step-content{max-width:780px;padding:16px 48px 60px}.sw-intro{margin-bottom:24px}.sw-step-number{font-size:1.25rem;font-weight:800;line-height:1}.sw-step-desc{font-size:.9375rem;color:#6b7280;line-height:1.5;margin:0 0 32px}.sw-hint{font-size:.8125rem;color:#94a3b8;margin:0 0 16px}.sw-import-tags{display:flex;flex-wrap:wrap;align-items:center;gap:8px;margin-bottom:28px}.sw-tag{font-size:.6875rem;font-weight:700;letter-spacing:1px;color:#6b7280}.sw-provider-grid{display:grid;grid-template-columns:repeat(2,1fr);gap:10px;margin-bottom:8px}@media(max-width:768px){.sw-provider-grid{grid-template-columns:1fr}}.sw-provider-grid .sw-integration{margin-bottom:0}.sw-int-row{display:flex;align-items:center;gap:12px}.sw-int-tile{width:36px;height:36px;border-radius:8px;color:#fff;font-size:1rem;font-weight:700;display:flex;align-items:center;justify-content:center;flex-shrink:0}.sw-int-text{display:flex;flex-direction:column;gap:2px;flex:1;min-width:0}.sw-int-title{font-size:.8125rem;font-weight:600;color:#1e293b;line-height:1.2}.sw-int-detail{font-size:.75rem;color:#64748b;overflow-wrap:anywhere}.sw-area-code{display:flex;align-items:flex-end;gap:12px;margin-top:12px;max-width:320px}.sw-area-code ui-text-input{flex:1}.sw-content ui-alert{display:block;margin-bottom:16px}.sw-card{display:block}.sw-header-action{margin-left:auto;min-width:0;max-width:100%}.sw-step-actions{display:flex;justify-content:space-between;align-items:center}.sw-ico{flex-shrink:0;vertical-align:-2px}.sw-actions-right{display:flex;align-items:center;gap:16px}.sw-done{text-align:center;display:flex;flex-direction:column;align-items:center;max-width:none}.sw-done .sw-step-desc{max-width:480px}.sw-summary{display:block;width:100%;max-width:480px;margin-bottom:24px;text-align:left}.sw-done-hint{font-size:.8125rem;color:#9ca3af;margin-bottom:24px}@media(max-width:768px){.sw-page{flex-direction:column}.sw-sidebar{width:100%;min-width:unset;padding:16px}.sw-brand{margin-bottom:12px}.sw-sidebar-bottom{display:none}.sw-step-content{padding:12px 20px 40px}}\n"]
43801
+ styles: [".sw-page{display:flex;min-height:100vh;min-height:100dvh;font-family:Inter,-apple-system,BlinkMacSystemFont,Segoe UI,sans-serif}.sw-sidebar{width:260px;min-width:260px;background:#faf9f7;border-right:1px solid #e5e2dc;display:flex;flex-direction:column;justify-content:space-between;padding:28px 20px}.sw-brand{display:flex;align-items:center;gap:10px;margin-bottom:28px}.sw-brand-text{font-size:1.125rem;font-weight:700;color:#1e293b}.sw-step-nav{display:block}.sw-sidebar-bottom{margin-top:24px}.sw-progress-text{display:block;margin-top:8px;font-size:.75rem;color:#94a3b8}.sw-content{flex:1;min-width:0;background:#fff;display:flex;flex-direction:column;overflow-y:auto}.sw-content-header{display:flex;justify-content:space-between;align-items:center;gap:16px;padding:20px 32px;border-bottom:1px solid #f1f5f9}.sw-step-title{font-size:1.25rem;font-weight:700;color:#111827;margin:0}.sw-step-content{max-width:780px;padding:16px 48px 60px}@media(min-width:1100px){.sw-step-content.sw-wide{max-width:1400px}}.sw-intro{margin-bottom:24px}.sw-step-number{font-size:1.25rem;font-weight:800;line-height:1}.sw-step-desc{font-size:.9375rem;color:#6b7280;line-height:1.5;margin:0 0 32px}.sw-body{display:block}.sw-body.sw-split{display:grid;grid-template-columns:1fr;gap:24px}@media(min-width:1100px){.sw-body.sw-split{grid-template-columns:1fr 1fr;align-items:start}}.sw-body>.sw-card{min-width:0}.sw-hint{font-size:.8125rem;color:#94a3b8;margin:0 0 16px}.sw-import-tags{display:flex;flex-wrap:wrap;align-items:center;gap:8px;margin-bottom:28px}.sw-tag{font-size:.6875rem;font-weight:700;letter-spacing:1px;color:#6b7280}.sw-provider-grid{display:grid;grid-template-columns:repeat(2,1fr);gap:10px;margin-bottom:8px}@media(max-width:768px){.sw-provider-grid{grid-template-columns:1fr}}.sw-provider-grid .sw-integration{margin-bottom:0}.sw-area-code{display:flex;align-items:flex-end;gap:12px;margin-top:12px;max-width:320px}.sw-area-code ui-text-input{flex:1}.sw-content ui-alert{display:block;margin-bottom:16px}.sw-card{display:block}.sw-header-action{margin-left:auto;min-width:0;max-width:100%}.sw-step-actions{display:flex;justify-content:space-between;align-items:center}.sw-ico{flex-shrink:0;vertical-align:-2px}.sw-actions-right{display:flex;align-items:center;gap:16px}.sw-done{text-align:center;display:flex;flex-direction:column;align-items:center;max-width:none}.sw-done .sw-step-desc{max-width:480px}.sw-summary{display:block;width:100%;max-width:480px;margin-bottom:24px;text-align:left}.sw-done-hint{font-size:.8125rem;color:#9ca3af;margin-bottom:24px}@media(max-width:768px){.sw-step-actions,.sw-actions-right{flex-direction:column-reverse;align-items:stretch;gap:10px}.sw-page{flex-direction:column}.sw-sidebar{width:100%;min-width:unset;padding:16px}.sw-brand{margin-bottom:12px}.sw-sidebar-bottom{display:none}.sw-step-content{padding:12px 20px 40px}}\n"]
43472
43802
  }]
43473
43803
  }],
43474
43804
  ctorParameters: () => [],
@@ -43509,6 +43839,10 @@ i0.ɵɵngDeclareClassMetadata({
43509
43839
  type: i0.ContentChildren,
43510
43840
  args: [i0.forwardRef(() => SetupWizardStepHeaderDirective), { isSignal: true }]
43511
43841
  }],
43842
+ stepTitle: [{
43843
+ type: i0.ViewChild,
43844
+ args: ["stepTitle", { isSignal: true }]
43845
+ }],
43512
43846
  importers: [{
43513
43847
  type: i0.ViewChildren,
43514
43848
  args: ["importer", { isSignal: true }]
@@ -43727,6 +44061,11 @@ const HEADING_OPTIONS = [
43727
44061
  label: "Heading 3"
43728
44062
  }
43729
44063
  ];
44064
+ const BLOCK_BASE_PADDING_PX = 12;
44065
+ function setEditorSpacing(el, spacing) {
44066
+ el.style.paddingTop = spacing ? `calc(${BLOCK_BASE_PADDING_PX}px + ${spacing})` : "";
44067
+ el.style.paddingBottom = spacing ? `calc(${BLOCK_BASE_PADDING_PX}px + ${spacing})` : "";
44068
+ }
43730
44069
  const SPACING_TABS = [
43731
44070
  {
43732
44071
  key: "none",
@@ -43788,7 +44127,7 @@ var EmailTemplateEditorComponent = class EmailTemplateEditorComponent {
43788
44127
  this.categoryPlaceholder = input("Select category...", ...ngDevMode ? [{ debugName: "categoryPlaceholder" }] : /* istanbul ignore next */ []);
43789
44128
  this.assignmentOptions = input([], ...ngDevMode ? [{ debugName: "assignmentOptions" }] : /* istanbul ignore next */ []);
43790
44129
  this.featuredAssignmentKey = input(null, ...ngDevMode ? [{ debugName: "featuredAssignmentKey" }] : /* istanbul ignore next */ []);
43791
- this.assignmentsDescription = input("Assign this template to automated email triggers. When triggered, the system will send this template.", ...ngDevMode ? [{ debugName: "assignmentsDescription" }] : /* istanbul ignore next */ []);
44130
+ this.assignmentsDescription = input("Assign this template to at least one automated email trigger. When triggered, the system will send this template.", ...ngDevMode ? [{ debugName: "assignmentsDescription" }] : /* istanbul ignore next */ []);
43792
44131
  this.variableGroups = input(DEFAULT_EMAIL_TEMPLATE_VARIABLE_GROUPS, ...ngDevMode ? [{ debugName: "variableGroups" }] : /* istanbul ignore next */ []);
43793
44132
  this.blockGroups = input(DEFAULT_EMAIL_TEMPLATE_BLOCK_GROUPS, ...ngDevMode ? [{ debugName: "blockGroups" }] : /* istanbul ignore next */ []);
43794
44133
  this.heading = input("", ...ngDevMode ? [{ debugName: "heading" }] : /* istanbul ignore next */ []);
@@ -43921,8 +44260,20 @@ var EmailTemplateEditorComponent = class EmailTemplateEditorComponent {
43921
44260
  this.nameErrorShown = computed(() => this.nameTouched() || this.submitAttempted() ? this.nameError() : "", ...ngDevMode ? [{ debugName: "nameErrorShown" }] : /* istanbul ignore next */ []);
43922
44261
  this.subjectErrorShown = computed(() => this.subjectTouched() || this.submitAttempted() ? this.subjectError() : "", ...ngDevMode ? [{ debugName: "subjectErrorShown" }] : /* istanbul ignore next */ []);
43923
44262
  this.bodyErrorShown = computed(() => this.bodyEdited() || this.submitAttempted() ? this.bodyError() : "", ...ngDevMode ? [{ debugName: "bodyErrorShown" }] : /* istanbul ignore next */ []);
43924
- this.canSave = computed(() => !this.nameError() && !this.subjectError() && !this.bodyError() && !this.datesError(), ...ngDevMode ? [{ debugName: "canSave" }] : /* istanbul ignore next */ []);
43925
- this.saveDisabled = computed(() => !this.canWrite(), ...ngDevMode ? [{ debugName: "saveDisabled" }] : /* istanbul ignore next */ []);
44263
+ this.assignmentError = computed(() => this.assignmentOptions().length > 0 && !this.assignmentState().some((a) => a.assigned) ? "Assign this template to at least one automation." : "", ...ngDevMode ? [{ debugName: "assignmentError" }] : /* istanbul ignore next */ []);
44264
+ this.assignmentsTouched = signal(false, ...ngDevMode ? [{ debugName: "assignmentsTouched" }] : /* istanbul ignore next */ []);
44265
+ this.assignmentErrorShown = computed(() => this.assignmentsTouched() || this.submitAttempted() ? this.assignmentError() : "", ...ngDevMode ? [{ debugName: "assignmentErrorShown" }] : /* istanbul ignore next */ []);
44266
+ this.canSave = computed(() => !this.nameError() && !this.subjectError() && !this.bodyError() && !this.datesError() && !this.assignmentError(), ...ngDevMode ? [{ debugName: "canSave" }] : /* istanbul ignore next */ []);
44267
+ this.saveDisabled = computed(() => !this.canWrite() || !this.canSave(), ...ngDevMode ? [{ debugName: "saveDisabled" }] : /* istanbul ignore next */ []);
44268
+ this.saveHint = computed(() => {
44269
+ if (!this.canWrite() || this.canSave()) return "";
44270
+ const missing = [];
44271
+ if (this.nameError()) missing.push(this.name().trim() ? "a shorter name" : "a name");
44272
+ if (this.subjectError()) missing.push(this.subject().trim() ? "a shorter subject" : "a subject");
44273
+ if (this.bodyError()) missing.push(this.bodyHasContent() ? "a shorter message" : "a message");
44274
+ if (this.assignmentError()) missing.push("at least one assignment");
44275
+ return missing.length ? `Add ${missing.join(", ")} to save this template.` : this.datesError() || "Fix the highlighted fields to save this template.";
44276
+ }, ...ngDevMode ? [{ debugName: "saveHint" }] : /* istanbul ignore next */ []);
43926
44277
  this.normalizedLink = computed(() => {
43927
44278
  const url = this.linkUrl().trim();
43928
44279
  if (!url) return "";
@@ -43976,7 +44327,7 @@ var EmailTemplateEditorComponent = class EmailTemplateEditorComponent {
43976
44327
  const block = current.find((b) => b.id === blockId);
43977
44328
  if (block !== void 0) {
43978
44329
  el.innerHTML = block.html;
43979
- if (block.spacing) el.style.padding = `${block.spacing} 0`;
44330
+ setEditorSpacing(el, block.spacing);
43980
44331
  this.initializedBlockIds.add(blockId);
43981
44332
  }
43982
44333
  }
@@ -44006,14 +44357,15 @@ var EmailTemplateEditorComponent = class EmailTemplateEditorComponent {
44006
44357
  id: this.genId(),
44007
44358
  html: `<p>${EMAIL_TEMPLATE_START_TEXT}</p>`
44008
44359
  }] : this.htmlToBlocks(t.body ?? ""));
44009
- this.selectedBlockId.set(null);
44010
- this.blockSpacing.set("");
44360
+ this.selectedBlockId.set(this.blocks()[0]?.id ?? null);
44361
+ this.blockSpacing.set(this.blocks()[0]?.spacing ?? "");
44011
44362
  this.loadedBody.set(t?.id ? t.body ?? "" : null);
44012
44363
  this.bodyEdited.set(false);
44013
44364
  this.submitAttempted.set(false);
44014
44365
  this.nameTouched.set(false);
44015
44366
  this.subjectTouched.set(false);
44016
44367
  this.assignedKeys.set([...t?.assignments ?? []]);
44368
+ this.assignmentsTouched.set(false);
44017
44369
  this.savedSnapshot.set(t?.id ? this.snapshot() : null);
44018
44370
  }
44019
44371
  onSave() {
@@ -44135,17 +44487,7 @@ var EmailTemplateEditorComponent = class EmailTemplateEditorComponent {
44135
44487
  if (!this.canWrite()) return;
44136
44488
  const list = this.blocks();
44137
44489
  if (index < 0 || index >= list.length) return;
44138
- if (list.length === 1) {
44139
- const ref = this.editorFor(list[0].id);
44140
- const alreadyEmpty = list[0].html === "<p></p>" && (!ref || ref.nativeElement.innerHTML === "<p></p>");
44141
- this.blocks.set([{
44142
- ...list[0],
44143
- html: "<p></p>"
44144
- }]);
44145
- if (ref) ref.nativeElement.innerHTML = "<p></p>";
44146
- if (!alreadyEmpty) this.bodyEdited.set(true);
44147
- return;
44148
- }
44490
+ if (list.length === 1) return;
44149
44491
  this.bodyEdited.set(true);
44150
44492
  this.initializedBlockIds.delete(list[index].id);
44151
44493
  const next = list.filter((_, i) => i !== index);
@@ -44357,7 +44699,7 @@ var EmailTemplateEditorComponent = class EmailTemplateEditorComponent {
44357
44699
  const id = this.selectedBlockId();
44358
44700
  if (!id) return;
44359
44701
  const ref = this.editorFor(id);
44360
- if (ref) ref.nativeElement.style.padding = value ? `${value} 0` : "";
44702
+ if (ref) setEditorSpacing(ref.nativeElement, value);
44361
44703
  const block = this.blocks().find((b) => b.id === id);
44362
44704
  if (!block) return;
44363
44705
  const changed = (block.spacing ?? "") !== (value ?? "");
@@ -44459,6 +44801,7 @@ var EmailTemplateEditorComponent = class EmailTemplateEditorComponent {
44459
44801
  toggleAssignment(item) {
44460
44802
  if (!this.canWrite()) return;
44461
44803
  this.assignedKeys.update((keys) => keys.includes(item.key) ? keys.filter((k) => k !== item.key) : [...keys, item.key]);
44804
+ this.assignmentsTouched.set(true);
44462
44805
  }
44463
44806
  isOpen(id) {
44464
44807
  return id === "v:" + (this.variableGroups()[0]?.name ?? "") !== this.toggledGroups().has(id);
@@ -44730,10 +45073,12 @@ var EmailTemplateEditorComponent = class EmailTemplateEditorComponent {
44730
45073
  Test Send
44731
45074
  </ui-button>
44732
45075
  }
45076
+ <span class="save-wrap" [uiTooltip]="saveHint()">
44733
45077
  <ui-button variant="primary" size="sm" [loading]="saving()" [disabled]="saveDisabled()" (click)="onSave()">
44734
45078
  <svg width="14" height="14" viewBox="0 0 24 24" fill="none" stroke="currentColor" stroke-width="2" aria-hidden="true"><path d="M19 21H5a2 2 0 0 1-2-2V5a2 2 0 0 1 2-2h11l5 5v11a2 2 0 0 1-2 2z"/><polyline points="17 21 17 13 7 13 7 21"/><polyline points="7 3 7 8 15 8"/></svg>
44735
45079
  Save Template
44736
45080
  </ui-button>
45081
+ </span>
44737
45082
  </div>
44738
45083
  </div>
44739
45084
  <ui-divider />
@@ -44782,8 +45127,9 @@ var EmailTemplateEditorComponent = class EmailTemplateEditorComponent {
44782
45127
  <!-- Assignments -->
44783
45128
  @if (assignmentOptions().length > 0) {
44784
45129
  <div class="assignments-section">
44785
- <h4 class="section-title">Assignments</h4>
45130
+ <h4 class="section-title">Assignments <span class="required" aria-hidden="true">*</span></h4>
44786
45131
  <p class="section-desc">{{ assignmentsDescription() }}</p>
45132
+ <ui-error [errorId]="idPrefix() + '-assignments-error'" [message]="assignmentErrorShown()" />
44787
45133
  <ui-search-input placeholder="Search..." ariaLabel="Search assignments" [(value)]="assignmentSearch" />
44788
45134
  @if (filteredAssignments().length === 0) {
44789
45135
  <ui-empty-state iconType="search" title="No assignments found" message="No assignments match your search." />
@@ -44969,9 +45315,11 @@ var EmailTemplateEditorComponent = class EmailTemplateEditorComponent {
44969
45315
  <ui-button variant="ghost" size="xs" ariaLabel="Duplicate block" uiTooltip="Duplicate" (mousedown)="preventFocusLoss($event)" (click)="duplicateBlock(i)">
44970
45316
  <svg width="12" height="12" viewBox="0 0 24 24" fill="none" stroke="currentColor" stroke-width="2" aria-hidden="true"><rect x="9" y="9" width="13" height="13" rx="2"/><path d="M5 15H4a2 2 0 0 1-2-2V4a2 2 0 0 1 2-2h9a2 2 0 0 1 2 2v1"/></svg>
44971
45317
  </ui-button>
44972
- <ui-button variant="ghost" size="xs" ariaLabel="Delete block" uiTooltip="Delete block" (mousedown)="preventFocusLoss($event)" (click)="deleteBlock(i)">
44973
- <svg width="12" height="12" viewBox="0 0 24 24" fill="none" stroke="currentColor" stroke-width="2" aria-hidden="true"><polyline points="3 6 5 6 21 6"/><path d="M19 6l-1 14a2 2 0 0 1-2 2H8a2 2 0 0 1-2-2L5 6"/><path d="M10 11v6M14 11v6"/></svg>
44974
- </ui-button>
45318
+ @if (blocks().length > 1) {
45319
+ <ui-button variant="ghost" size="xs" ariaLabel="Delete block" uiTooltip="Delete block" (mousedown)="preventFocusLoss($event)" (click)="deleteBlock(i)">
45320
+ <svg width="12" height="12" viewBox="0 0 24 24" fill="none" stroke="currentColor" stroke-width="2" aria-hidden="true"><polyline points="3 6 5 6 21 6"/><path d="M19 6l-1 14a2 2 0 0 1-2 2H8a2 2 0 0 1-2-2L5 6"/><path d="M10 11v6M14 11v6"/></svg>
45321
+ </ui-button>
45322
+ }
44975
45323
  </div>
44976
45324
  }
44977
45325
  </div>
@@ -45082,8 +45430,9 @@ var EmailTemplateEditorComponent = class EmailTemplateEditorComponent {
45082
45430
  @for (v of group.variables; track v.key) {
45083
45431
  <button type="button" class="variable-item" (mousedown)="saveSelection()" (click)="insertVariable(v)">
45084
45432
  <span class="var-tag">{{ '{{' + v.key + '}}' }}</span>
45085
- <span class="var-label">{{ v.label }}</span>
45086
45433
  <span class="var-example">{{ v.example }}</span>
45434
+ <!-- A very short explanation of what the variable is: the host's description, else its label. -->
45435
+ <span class="var-description">{{ v.description || v.label }}</span>
45087
45436
  </button>
45088
45437
  }
45089
45438
  </div>
@@ -45177,7 +45526,7 @@ var EmailTemplateEditorComponent = class EmailTemplateEditorComponent {
45177
45526
 
45178
45527
  `,
45179
45528
  isInline: true,
45180
- styles: [":host{display:flex;flex-direction:column;flex:1;min-height:0}.required{color:#ef4444;font-weight:400}.editor-page{display:flex;flex-direction:column;flex:1;min-height:0;background:#f8fafc;overflow:hidden}.editor-actions{display:flex;justify-content:space-between;align-items:center;gap:8px 16px;flex-wrap:wrap;padding:0 0 12px;flex-shrink:0}.editor-heading{margin:0;font-size:1.25rem;font-weight:700;color:#1e293b;line-height:1.3;min-width:0}.editor-actions-buttons{display:flex;align-items:center;justify-content:flex-end;gap:8px;flex-wrap:wrap;margin-left:auto}.readonly-note{margin:0;padding:8px 16px;font-size:.8125rem;color:#92400e;background:#fffbeb;border-bottom:1px solid #fde68a}.readonly-note.system-note{display:flex;align-items:center;justify-content:space-between;gap:12px;flex-wrap:wrap}.editor-body{display:grid;grid-template-columns:340px minmax(0,1fr) 300px;grid-template-rows:minmax(0,1fr);flex:1;min-height:0;overflow:hidden}.panel-left{background:#fff;border-right:1px solid #e2e8f0;padding:24px;overflow-y:auto}.panel-title{font-size:1.0625rem;font-weight:700;color:#1e293b;margin:0 0 20px}.form-field{display:flex;flex-direction:column;gap:6px;margin-bottom:16px}.form-row-dates{display:grid;grid-template-columns:1fr 1fr;gap:12px;margin-top:16px}.assignments-section{border-top:1px solid #e2e8f0;padding-top:20px;margin-top:16px}.section-title{font-size:.9375rem;font-weight:700;color:#1e293b;margin:0 0 6px}.section-desc{font-size:.8125rem;color:#64748b;line-height:1.5;margin:0 0 12px}.assignment-list{max-height:340px;overflow-y:auto;margin-top:12px;border:1px solid #e2e8f0;border-radius:8px}.assignment-item{display:flex;align-items:center;justify-content:space-between;gap:10px;padding:12px 14px;cursor:pointer;border-bottom:1px solid #f1f5f9;transition:background .1s}.assignment-item:last-child{border-bottom:none}.assignment-item:hover{background:#f8fafc}.assignment-item:focus-visible{outline:2px solid #3b82f6;outline-offset:-2px}.assignment-item.assignment-readonly{cursor:default}.assignment-item.assignment-readonly:hover{background:transparent}.assignment-text{display:flex;flex-direction:column;gap:2px;flex:1;min-width:0}.assignment-text strong{font-size:.8125rem;color:#1e293b}.assignment-text span{font-size:.75rem;color:#64748b}.assignment-channels{display:flex;gap:4px;flex-shrink:0}.channel-badge{display:flex;align-items:center;justify-content:center;width:24px;height:24px;border-radius:4px;background:#f1f5f9;color:#94a3b8;transition:all .15s}.channel-badge.active{background:#3b82f6;color:#fff}.channel-badge.disabled{opacity:.4;cursor:not-allowed}.config-desc{font-size:.875rem;color:#64748b;line-height:1.5;margin:0}.config-divider{border:none;border-top:1px solid #e2e8f0;margin:20px 0}.config-section{display:flex;flex-direction:column;gap:12px}.config-section-label{font-size:.6875rem;font-weight:700;color:#3b82f6;text-transform:uppercase;letter-spacing:.04em}.config-field{display:flex;flex-direction:column;gap:6px}.config-field-mt{margin-top:16px}.config-label{font-size:.8125rem;font-weight:600;color:#1e293b}.config-readonly{padding:9px 12px;border:1px solid #e2e8f0;border-radius:8px;background:#f8fafc;font-size:.875rem;color:#1e293b}.config-hint{font-size:.75rem;color:#64748b}.test-save-note{display:flex;align-items:center;gap:8px;padding:10px 14px;background:#fef3c7;border:1px solid #fcd34d;border-radius:8px;font-size:.8125rem;color:#92400e;margin-top:12px}.test-save-note svg{flex-shrink:0}.panel-center{display:flex;flex-direction:column;min-height:0;min-width:0;overflow:hidden}.editor-tabs{display:flex;gap:2px;padding:12px 20px 0;background:#fff;border-bottom:1px solid #e2e8f0;overflow-x:auto;-webkit-overflow-scrolling:touch}.editor-tab{display:flex;align-items:center;gap:6px;padding:10px 16px;border:1px solid #e2e8f0;border-bottom:none;border-radius:8px 8px 0 0;background:#f8fafc;font-size:.8125rem;font-weight:600;color:#64748b;cursor:pointer;font-family:inherit;white-space:nowrap}.editor-tab:hover{background:#fff;color:#1e293b}.editor-tab.active{background:#eff6ff;color:#3b82f6;border-color:#93c5fd}.editor-tab:focus-visible,.right-tab:focus-visible,.block-group-header:focus-visible,.variable-item:focus-visible,.add-block-btn:focus-visible,.block-item:focus-visible,.video-lib-item:focus-visible{outline:2px solid #3b82f6;outline-offset:-2px}.editor-toolbar{display:flex;align-items:center;gap:8px;padding:10px 20px;background:#fff;border-bottom:1px solid #e2e8f0;flex-wrap:wrap}.toolbar-row-2{display:flex;align-items:center;gap:8px;flex-wrap:wrap;padding:8px 20px;background:#fff;border-bottom:1px solid #e2e8f0}.toolbar-group{display:flex;align-items:center;gap:2px;padding-right:8px;border-right:1px solid #e2e8f0}.toolbar-group:last-child{border-right:none;padding-right:0}.toolbar-select{display:block;min-width:96px}.toolbar-label{font-size:.75rem;font-weight:600;color:#64748b;white-space:nowrap;margin-right:6px}.hidden-color-input{position:absolute;width:0;height:0;opacity:0;pointer-events:none;border:none;padding:0}.color-indicator{display:flex;flex-direction:column;align-items:center;gap:2px;color:#475569}.color-bar{display:block;width:16px;height:3px;border-radius:2px;border:1px solid rgba(0,0,0,.1)}.link-dialog{background:#fff;border-bottom:1px solid #e2e8f0;padding:12px 20px}.link-dialog-inner{display:flex;align-items:flex-start;gap:8px;flex-wrap:wrap}.link-dialog-title{font-size:.8125rem;font-weight:700;color:#1e293b;white-space:nowrap;padding-top:10px}.link-dialog-input{display:block;width:240px;max-width:100%}.link-dialog-actions{display:flex;gap:6px}.preview-frame{flex:1;display:flex;justify-content:center;padding:24px;overflow-y:auto;background:#f1f5f9}.preview-frame.mobile{align-items:flex-start}.preview-content{max-width:600px;width:100%;box-sizing:border-box;background:#fff;border:1px solid #e2e8f0;border-radius:8px;padding:32px;min-height:400px;font-size:.9375rem;line-height:1.6;color:#1e293b;overflow-wrap:anywhere}.preview-content p{margin:0 0 8px}.mobile-shell{width:375px;max-width:100%;box-sizing:border-box;min-height:600px;border:2px solid #1e293b;border-radius:24px;padding:40px 12px 24px;background:#fff;box-shadow:0 8px 32px #0000001f}.mobile-shell .preview-content{border:none;border-radius:0;padding:16px;max-width:100%}.blocks-canvas{flex:1;padding:16px 20px 24px;overflow-y:auto;background:#f1f5f9;display:flex;flex-direction:column}.block-wrapper{position:relative;display:flex;align-items:flex-start;background:#fff;border:2px solid transparent;border-radius:8px;transition:border-color .15s,box-shadow .15s}.block-wrapper:hover,.block-wrapper.selected,.block-wrapper:focus-within{border-color:#3b82f6;box-shadow:0 0 0 3px #3b82f61a}.block-wrapper:hover .block-drag-handle,.block-wrapper.selected .block-drag-handle,.block-wrapper:focus-within .block-drag-handle{opacity:1}.block-wrapper:hover .block-controls,.block-wrapper.selected .block-controls,.block-wrapper:focus-within .block-controls{opacity:1;pointer-events:all}.block-wrapper.dragging{opacity:.4}.block-drag-handle{flex-shrink:0;width:28px;display:flex;align-items:flex-start;justify-content:center;padding-top:14px;opacity:0;transition:opacity .15s;cursor:grab;color:#94a3b8}.block-drag-handle:active{cursor:grabbing}.block-content{flex:1;min-width:0;padding:12px 16px;outline:none;font-size:.9375rem;color:#1e293b;line-height:1.6;min-height:48px;overflow-wrap:anywhere}.block-content:empty:before{content:\"Click to edit...\";color:#94a3b8;font-style:italic;pointer-events:none}.block-content p{margin:0 0 8px}.block-content p:last-child{margin:0}.block-content h1,.block-content h2,.block-content h3{margin:8px 0 6px;color:#1e293b}.block-content a{color:#3b82f6}.block-content img{max-width:100%;border-radius:6px}.block-content ul,.block-content ol{padding-left:20px;margin:0 0 8px}.block-controls{position:absolute;top:6px;right:6px;display:flex;gap:2px;opacity:0;pointer-events:none;transition:opacity .15s;background:#fff;border:1px solid #e2e8f0;border-radius:6px;padding:3px;box-shadow:0 2px 6px #00000014}@media(hover:none){.block-wrapper.selected .block-controls{opacity:1;pointer-events:all}}.drop-zone{height:8px;display:flex;align-items:center;justify-content:center;border-radius:4px;transition:height .15s,background .15s;position:relative}.drop-zone-label{font-size:.75rem;font-weight:600;color:#3b82f6;opacity:0;transition:opacity .1s}.drop-zone.active{height:40px;background:#3b82f614;border:2px dashed #3b82f6}.drop-zone.active .drop-zone-label{opacity:1}.add-block-btn{display:flex;align-items:center;justify-content:center;gap:8px;width:100%;min-height:44px;padding:12px;margin-top:8px;border:2px dashed #e2e8f0;border-radius:8px;background:none;font-size:.875rem;font-weight:600;color:#64748b;cursor:pointer;font-family:inherit;transition:border-color .15s,color .15s,background .15s}.add-block-btn:hover{border-color:#3b82f6;color:#3b82f6;background:#3b82f60a}.panel-right{background:#fff;border-left:1px solid #e2e8f0;display:flex;flex-direction:column;min-height:0;min-width:0}.right-tabs{display:flex;border-bottom:1px solid #e2e8f0}.right-tab{flex:1;display:flex;align-items:center;justify-content:center;gap:6px;padding:12px;min-height:44px;border:none;background:none;font-size:.8125rem;font-weight:600;color:#64748b;cursor:pointer;font-family:inherit;border-bottom:2px solid transparent}.right-tab:hover{color:#1e293b}.right-tab.active{color:#3b82f6;background:#eff6ff;border-bottom-color:#3b82f6}.right-panel-body{flex:1;padding:20px;overflow-y:auto}.right-section-title{font-size:.9375rem;font-weight:700;color:#1e293b;margin:0 0 12px}.right-section-desc{font-size:.8125rem;color:#64748b;margin:0 0 16px;line-height:1.5}.right-section-hint{font-size:.8125rem;color:#64748b;margin:0 0 12px;line-height:1.5}.block-group{border-bottom:1px solid #f1f5f9}.block-group-header{display:flex;align-items:center;gap:8px;width:100%;min-height:44px;padding:12px 0;border:none;background:none;font-size:.875rem;font-weight:600;color:#1e293b;cursor:pointer;font-family:inherit;text-align:left}.block-group-header .chevron{transition:transform .2s;color:#94a3b8}.block-group-header .chevron.expanded{transform:rotate(90deg)}.block-group-header span:nth-of-type(1){flex:1}.block-count{font-size:.75rem;font-weight:600;color:#64748b;background:#f1f5f9;padding:2px 8px;border-radius:10px;margin-left:auto}.block-list,.variable-list{display:flex;flex-direction:column;gap:2px;padding-bottom:8px}.block-item{display:flex;align-items:center;gap:6px;box-sizing:border-box;width:100%;min-height:44px;padding:8px 12px 8px 28px;font-size:.8125rem;color:#64748b;cursor:pointer;text-align:left;border-radius:4px;font-family:inherit;-webkit-user-select:none;user-select:none}.block-item:hover{background:#f8fafc;color:#1e293b}.block-item-drag{color:#cbd5e1;flex-shrink:0;cursor:grab}.variable-item{display:grid;grid-template-columns:auto 1fr auto;gap:8px;align-items:center;min-height:44px;padding:8px 12px 8px 28px;border:none;background:none;cursor:pointer;text-align:left;border-radius:4px;font-family:inherit}.variable-item:hover{background:#f8fafc}.var-tag{font-size:.75rem;font-weight:600;color:#3b82f6;background:#3b82f614;padding:2px 6px;border-radius:4px;font-family:ui-monospace,SFMono-Regular,Menlo,monospace}.var-label{font-size:.8125rem;color:#1e293b}.var-example{font-size:.75rem;color:#64748b;overflow-wrap:anywhere}.video-library-panel{padding:0}.video-library-panel .right-section-title,.video-library-panel .right-section-hint{padding:0 16px}.video-library-panel .right-section-title{padding-top:16px}.video-config-section{display:flex;flex-direction:column;gap:8px;padding:12px 16px;border-bottom:1px solid #f1f5f9}.video-config-section:last-of-type{border-bottom:none}.video-lib-list{display:flex;flex-direction:column;gap:2px;padding:8px 8px 16px}.video-lib-item{display:flex;align-items:center;gap:10px;width:100%;min-height:44px;padding:8px;border:1px solid transparent;border-radius:8px;background:none;cursor:pointer;text-align:left;font-family:inherit;transition:background .15s,border-color .15s}.video-lib-item:hover{background:#f8fafc;border-color:#e2e8f0}.video-lib-item.selected{background:#eff6ff;border-color:#93c5fd}.vli-thumb{position:relative;flex-shrink:0;width:56px;height:40px;border-radius:6px;background:linear-gradient(135deg,#f1f5f9,#e2e8f0);display:flex;align-items:center;justify-content:center}.vli-dur{position:absolute;bottom:2px;right:3px;font-size:.625rem;font-weight:600;color:#fff;background:#000000a6;padding:1px 4px;border-radius:3px}.vli-info{flex:1;min-width:0;display:flex;flex-direction:column;gap:2px}.vli-title{font-size:.8125rem;font-weight:600;color:#1e293b;overflow:hidden;text-overflow:ellipsis;white-space:nowrap}.vli-cat{font-size:.75rem;color:#64748b}.vli-check{flex-shrink:0}.video-lib-loading{padding:8px}.video-lib-skeleton{display:flex;align-items:center;gap:10px;padding:8px;margin-bottom:4px}.vls-info{flex:1;display:flex;flex-direction:column;gap:6px}@media(max-width:1200px){.editor-body{grid-template-columns:280px minmax(0,1fr) 260px}}@media(max-width:900px){:host{flex:none}.editor-page{flex:none;min-height:100vh;min-height:100dvh;overflow:visible}.editor-body{display:flex;flex-direction:column;flex:none;overflow:visible}.panel-left{border-right:none;border-bottom:1px solid #e2e8f0;overflow:visible;padding:16px}.panel-center{overflow:visible;min-height:480px}.blocks-canvas{overflow:visible;min-height:320px}.panel-right{border-left:none;border-top:1px solid #e2e8f0}.right-panel-body{overflow:visible}.editor-toolbar,.toolbar-row-2,.link-dialog,.editor-tabs{padding-left:12px;padding-right:12px}.preview-frame{padding:12px}.preview-content{padding:16px}.form-row-dates{grid-template-columns:1fr}}@media(prefers-reduced-motion:reduce){*{transition:none!important}}\n"],
45529
+ styles: [":host{display:flex;flex-direction:column;flex:1;min-height:0}.required{color:#ef4444;font-weight:400}.editor-page{display:flex;flex-direction:column;flex:1;min-height:0;background:#f8fafc;overflow:hidden}.editor-actions{display:flex;justify-content:space-between;align-items:center;gap:8px 16px;flex-wrap:wrap;padding:0 0 12px;flex-shrink:0}.editor-heading{margin:0;font-size:1.25rem;font-weight:700;color:#1e293b;line-height:1.3;min-width:0}.save-wrap{display:inline-flex}.editor-actions-buttons{display:flex;align-items:center;justify-content:flex-end;gap:8px;flex-wrap:wrap;margin-left:auto}.readonly-note{margin:0;padding:8px 16px;font-size:.8125rem;color:#92400e;background:#fffbeb;border-bottom:1px solid #fde68a}.readonly-note.system-note{display:flex;align-items:center;justify-content:space-between;gap:12px;flex-wrap:wrap}.editor-body{display:grid;grid-template-columns:340px minmax(0,1fr) 300px;grid-template-rows:minmax(0,1fr);flex:1;min-height:0;overflow:hidden}.panel-left{background:#fff;border-right:1px solid #e2e8f0;padding:24px;overflow-y:auto}.panel-title{font-size:1.0625rem;font-weight:700;color:#1e293b;margin:0 0 20px}.form-field{display:flex;flex-direction:column;gap:6px;margin-bottom:16px}.form-row-dates{display:grid;grid-template-columns:1fr 1fr;gap:12px;margin-top:16px}.assignments-section{border-top:1px solid #e2e8f0;padding-top:20px;margin-top:16px}.section-title{font-size:.9375rem;font-weight:700;color:#1e293b;margin:0 0 6px}.section-desc{font-size:.8125rem;color:#64748b;line-height:1.5;margin:0 0 12px}.assignment-list{max-height:340px;overflow-y:auto;margin-top:12px;border:1px solid #e2e8f0;border-radius:8px}.assignment-item{display:flex;align-items:center;justify-content:space-between;gap:10px;padding:12px 14px;cursor:pointer;border-bottom:1px solid #f1f5f9;transition:background .1s}.assignment-item:last-child{border-bottom:none}.assignment-item:hover{background:#f8fafc}.assignment-item:focus-visible{outline:2px solid #3b82f6;outline-offset:-2px}.assignment-item.assignment-readonly{cursor:default}.assignment-item.assignment-readonly:hover{background:transparent}.assignment-text{display:flex;flex-direction:column;gap:2px;flex:1;min-width:0}.assignment-text strong{font-size:.8125rem;color:#1e293b}.assignment-text span{font-size:.75rem;color:#64748b}.assignment-channels{display:flex;gap:4px;flex-shrink:0}.channel-badge{display:flex;align-items:center;justify-content:center;width:24px;height:24px;border-radius:4px;background:#f1f5f9;color:#94a3b8;transition:all .15s}.channel-badge.active{background:#3b82f6;color:#fff}.channel-badge.disabled{opacity:.4;cursor:not-allowed}.config-desc{font-size:.875rem;color:#64748b;line-height:1.5;margin:0}.config-divider{border:none;border-top:1px solid #e2e8f0;margin:20px 0}.config-section{display:flex;flex-direction:column;gap:12px}.config-section-label{font-size:.6875rem;font-weight:700;color:#3b82f6;text-transform:uppercase;letter-spacing:.04em}.config-field{display:flex;flex-direction:column;gap:6px}.config-field-mt{margin-top:16px}.config-label{font-size:.8125rem;font-weight:600;color:#1e293b}.config-readonly{padding:9px 12px;border:1px solid #e2e8f0;border-radius:8px;background:#f8fafc;font-size:.875rem;color:#1e293b}.config-hint{font-size:.75rem;color:#64748b}.test-save-note{display:flex;align-items:center;gap:8px;padding:10px 14px;background:#fef3c7;border:1px solid #fcd34d;border-radius:8px;font-size:.8125rem;color:#92400e;margin-top:12px}.test-save-note svg{flex-shrink:0}.panel-center{display:flex;flex-direction:column;min-height:0;min-width:0;overflow:hidden}.editor-tabs{display:flex;gap:2px;padding:12px 20px 0;background:#fff;border-bottom:1px solid #e2e8f0;overflow-x:auto;-webkit-overflow-scrolling:touch}.editor-tab{display:flex;align-items:center;gap:6px;padding:10px 16px;border:1px solid #e2e8f0;border-bottom:none;border-radius:8px 8px 0 0;background:#f8fafc;font-size:.8125rem;font-weight:600;color:#64748b;cursor:pointer;font-family:inherit;white-space:nowrap}.editor-tab:hover{background:#fff;color:#1e293b}.editor-tab.active{background:#eff6ff;color:#3b82f6;border-color:#93c5fd}.editor-tab:focus-visible,.right-tab:focus-visible,.block-group-header:focus-visible,.variable-item:focus-visible,.add-block-btn:focus-visible,.block-item:focus-visible,.video-lib-item:focus-visible{outline:2px solid #3b82f6;outline-offset:-2px}.editor-toolbar{display:flex;align-items:center;gap:8px;padding:10px 20px;background:#fff;border-bottom:1px solid #e2e8f0;flex-wrap:wrap}.toolbar-row-2{display:flex;align-items:center;gap:8px;flex-wrap:wrap;padding:8px 20px;background:#fff;border-bottom:1px solid #e2e8f0}.toolbar-group{display:flex;align-items:center;gap:2px;padding-right:8px;border-right:1px solid #e2e8f0}.toolbar-group:last-child{border-right:none;padding-right:0}.toolbar-select{display:block;min-width:96px}.toolbar-label{font-size:.75rem;font-weight:600;color:#64748b;white-space:nowrap;margin-right:6px}.hidden-color-input{position:absolute;width:0;height:0;opacity:0;pointer-events:none;border:none;padding:0}.color-indicator{display:flex;flex-direction:column;align-items:center;gap:2px;color:#475569}.color-bar{display:block;width:16px;height:3px;border-radius:2px;border:1px solid rgba(0,0,0,.1)}.link-dialog{background:#fff;border-bottom:1px solid #e2e8f0;padding:12px 20px}.link-dialog-inner{display:flex;align-items:flex-start;gap:8px;flex-wrap:wrap}.link-dialog-title{font-size:.8125rem;font-weight:700;color:#1e293b;white-space:nowrap;padding-top:10px}.link-dialog-input{display:block;width:240px;max-width:100%}.link-dialog-actions{display:flex;gap:6px}.preview-frame{flex:1;display:flex;justify-content:center;padding:24px;overflow-y:auto;background:#f1f5f9}.preview-frame.mobile{align-items:flex-start}.preview-content{max-width:600px;width:100%;box-sizing:border-box;background:#fff;border:1px solid #e2e8f0;border-radius:8px;padding:32px;min-height:400px;font-size:.9375rem;line-height:1.6;color:#1e293b;overflow-wrap:anywhere}.preview-content p{margin:0 0 8px}.mobile-shell{width:375px;max-width:100%;box-sizing:border-box;min-height:600px;border:2px solid #1e293b;border-radius:24px;padding:40px 12px 24px;background:#fff;box-shadow:0 8px 32px #0000001f}.mobile-shell .preview-content{border:none;border-radius:0;padding:16px;max-width:100%}.blocks-canvas{flex:1 1 0;min-height:0;padding:16px 20px 24px;overflow-y:auto;overscroll-behavior:contain;-webkit-overflow-scrolling:touch;background:#f1f5f9;display:flex;flex-direction:column}.block-wrapper{flex-shrink:0;position:relative;display:flex;align-items:flex-start;background:#fff;border:2px solid transparent;border-radius:8px;transition:border-color .15s,box-shadow .15s}.block-wrapper:hover,.block-wrapper.selected,.block-wrapper:focus-within{border-color:#3b82f6;box-shadow:0 0 0 3px #3b82f61a}.block-wrapper:hover .block-drag-handle,.block-wrapper.selected .block-drag-handle,.block-wrapper:focus-within .block-drag-handle{opacity:1}.block-wrapper:hover .block-controls,.block-wrapper.selected .block-controls,.block-wrapper:focus-within .block-controls{opacity:1;pointer-events:all}.block-wrapper.dragging{opacity:.4}.block-drag-handle{flex-shrink:0;width:28px;display:flex;align-items:flex-start;justify-content:center;padding-top:14px;opacity:0;transition:opacity .15s;cursor:grab;color:#94a3b8}.block-drag-handle:active{cursor:grabbing}.block-content{flex:1;min-width:0;padding:12px 16px;outline:none;font-size:.9375rem;color:#1e293b;line-height:1.6;min-height:48px;overflow-wrap:anywhere}.block-content:empty:before{content:\"Click to edit...\";color:#94a3b8;font-style:italic;pointer-events:none}.block-content p{margin:0 0 8px}.block-content p:last-child{margin:0}.block-content h1,.block-content h2,.block-content h3{margin:8px 0 6px;color:#1e293b}.block-content a{color:#3b82f6}.block-content img{max-width:100%;border-radius:6px}.block-content ul,.block-content ol{padding-left:20px;margin:0 0 8px}.block-controls{position:absolute;top:6px;right:6px;display:flex;gap:2px;opacity:0;pointer-events:none;transition:opacity .15s;background:#fff;border:1px solid #e2e8f0;border-radius:6px;padding:3px;box-shadow:0 2px 6px #00000014}@media(hover:none){.block-wrapper.selected .block-controls{opacity:1;pointer-events:all}}.drop-zone{flex-shrink:0;height:8px;display:flex;align-items:center;justify-content:center;border-radius:4px;transition:height .15s,background .15s;position:relative}.drop-zone-label{font-size:.75rem;font-weight:600;color:#3b82f6;opacity:0;transition:opacity .1s}.drop-zone.active{height:40px;background:#3b82f614;border:2px dashed #3b82f6}.drop-zone.active .drop-zone-label{opacity:1}.add-block-btn{flex-shrink:0;display:flex;align-items:center;justify-content:center;gap:8px;width:100%;min-height:44px;padding:12px;margin-top:8px;border:2px dashed #e2e8f0;border-radius:8px;background:none;font-size:.875rem;font-weight:600;color:#64748b;cursor:pointer;font-family:inherit;transition:border-color .15s,color .15s,background .15s}.add-block-btn:hover{border-color:#3b82f6;color:#3b82f6;background:#3b82f60a}.panel-right{background:#fff;border-left:1px solid #e2e8f0;display:flex;flex-direction:column;min-height:0;min-width:0}.right-tabs{display:flex;border-bottom:1px solid #e2e8f0}.right-tab{flex:1;display:flex;align-items:center;justify-content:center;gap:6px;padding:12px;min-height:44px;border:none;background:none;font-size:.8125rem;font-weight:600;color:#64748b;cursor:pointer;font-family:inherit;border-bottom:2px solid transparent}.right-tab:hover{color:#1e293b}.right-tab.active{color:#3b82f6;background:#eff6ff;border-bottom-color:#3b82f6}.right-panel-body{flex:1;padding:20px;overflow-y:auto}.right-section-title{font-size:.9375rem;font-weight:700;color:#1e293b;margin:0 0 12px}.right-section-desc{font-size:.8125rem;color:#64748b;margin:0 0 16px;line-height:1.5}.right-section-hint{font-size:.8125rem;color:#64748b;margin:0 0 12px;line-height:1.5}.block-group{border-bottom:1px solid #f1f5f9}.block-group-header{display:flex;align-items:center;gap:8px;width:100%;min-height:44px;padding:12px 0;border:none;background:none;font-size:.875rem;font-weight:600;color:#1e293b;cursor:pointer;font-family:inherit;text-align:left}.block-group-header .chevron{transition:transform .2s;color:#94a3b8}.block-group-header .chevron.expanded{transform:rotate(90deg)}.block-group-header span:nth-of-type(1){flex:1}.block-count{font-size:.75rem;font-weight:600;color:#64748b;background:#f1f5f9;padding:2px 8px;border-radius:10px;margin-left:auto}.block-list{display:flex;flex-direction:column;gap:2px;padding-bottom:8px}.variable-list{display:flex;flex-direction:column;padding-bottom:8px}.variable-item+.variable-item{border-top:1px solid #f1f5f9;border-radius:0}.block-item{display:flex;align-items:center;gap:6px;box-sizing:border-box;width:100%;min-height:44px;padding:8px 12px 8px 28px;font-size:.8125rem;color:#64748b;cursor:pointer;text-align:left;border-radius:4px;font-family:inherit;-webkit-user-select:none;user-select:none}.block-item:hover{background:#f8fafc;color:#1e293b}.block-item-drag{color:#cbd5e1;flex-shrink:0;cursor:grab}.variable-item{display:flex;flex-direction:column;align-items:flex-start;gap:4px;min-height:44px;padding:8px 0;min-width:0;width:100%;box-sizing:border-box;border:none;background:none;cursor:pointer;text-align:left;border-radius:4px;font-family:inherit}.variable-item:hover{background:#f8fafc}.var-tag{max-width:100%;overflow-wrap:anywhere;font-size:.75rem;font-weight:600;color:#3b82f6;background:#3b82f614;padding:2px 6px;border-radius:4px;font-family:ui-monospace,SFMono-Regular,Menlo,monospace}.var-example{font-size:.75rem;color:#64748b;overflow-wrap:anywhere}.var-description{font-size:.75rem;color:#64748b;line-height:1.4;overflow-wrap:anywhere}.video-library-panel{padding:0}.video-library-panel .right-section-title,.video-library-panel .right-section-hint{padding:0 16px}.video-library-panel .right-section-title{padding-top:16px}.video-config-section{display:flex;flex-direction:column;gap:8px;padding:12px 16px;border-bottom:1px solid #f1f5f9}.video-config-section:last-of-type{border-bottom:none}.video-lib-list{display:flex;flex-direction:column;gap:2px;padding:8px 8px 16px}.video-lib-item{display:flex;align-items:center;gap:10px;width:100%;min-height:44px;padding:8px;border:1px solid transparent;border-radius:8px;background:none;cursor:pointer;text-align:left;font-family:inherit;transition:background .15s,border-color .15s}.video-lib-item:hover{background:#f8fafc;border-color:#e2e8f0}.video-lib-item.selected{background:#eff6ff;border-color:#93c5fd}.vli-thumb{position:relative;flex-shrink:0;width:56px;height:40px;border-radius:6px;background:linear-gradient(135deg,#f1f5f9,#e2e8f0);display:flex;align-items:center;justify-content:center}.vli-dur{position:absolute;bottom:2px;right:3px;font-size:.625rem;font-weight:600;color:#fff;background:#000000a6;padding:1px 4px;border-radius:3px}.vli-info{flex:1;min-width:0;display:flex;flex-direction:column;gap:2px}.vli-title{font-size:.8125rem;font-weight:600;color:#1e293b;overflow:hidden;text-overflow:ellipsis;white-space:nowrap}.vli-cat{font-size:.75rem;color:#64748b}.vli-check{flex-shrink:0}.video-lib-loading{padding:8px}.video-lib-skeleton{display:flex;align-items:center;gap:10px;padding:8px;margin-bottom:4px}.vls-info{flex:1;display:flex;flex-direction:column;gap:6px}@media(max-width:1200px){.editor-body{grid-template-columns:280px minmax(0,1fr) 260px}}@media(max-width:900px){:host{flex:none}.editor-page{flex:none;min-height:100vh;min-height:100dvh;overflow:visible}.editor-body{display:flex;flex-direction:column;flex:none;overflow:visible}.panel-left{border-right:none;border-bottom:1px solid #e2e8f0;overflow:visible;padding:16px}.panel-center{overflow:visible;min-height:480px}.blocks-canvas{overflow:visible;min-height:320px}.panel-right{border-left:none;border-top:1px solid #e2e8f0}.right-panel-body{overflow:visible}.editor-toolbar,.toolbar-row-2,.link-dialog,.editor-tabs{padding-left:12px;padding-right:12px}.preview-frame{padding:12px}.preview-content{padding:16px}.form-row-dates{grid-template-columns:1fr}}@media(prefers-reduced-motion:reduce){*{transition:none!important}}\n"],
45181
45530
  dependencies: [
45182
45531
  {
45183
45532
  kind: "ngmodule",
@@ -45507,10 +45856,12 @@ i0.ɵɵngDeclareClassMetadata({
45507
45856
  Test Send
45508
45857
  </ui-button>
45509
45858
  }
45859
+ <span class="save-wrap" [uiTooltip]="saveHint()">
45510
45860
  <ui-button variant="primary" size="sm" [loading]="saving()" [disabled]="saveDisabled()" (click)="onSave()">
45511
45861
  <svg width="14" height="14" viewBox="0 0 24 24" fill="none" stroke="currentColor" stroke-width="2" aria-hidden="true"><path d="M19 21H5a2 2 0 0 1-2-2V5a2 2 0 0 1 2-2h11l5 5v11a2 2 0 0 1-2 2z"/><polyline points="17 21 17 13 7 13 7 21"/><polyline points="7 3 7 8 15 8"/></svg>
45512
45862
  Save Template
45513
45863
  </ui-button>
45864
+ </span>
45514
45865
  </div>
45515
45866
  </div>
45516
45867
  <ui-divider />
@@ -45559,8 +45910,9 @@ i0.ɵɵngDeclareClassMetadata({
45559
45910
  <!-- Assignments -->
45560
45911
  @if (assignmentOptions().length > 0) {
45561
45912
  <div class="assignments-section">
45562
- <h4 class="section-title">Assignments</h4>
45913
+ <h4 class="section-title">Assignments <span class="required" aria-hidden="true">*</span></h4>
45563
45914
  <p class="section-desc">{{ assignmentsDescription() }}</p>
45915
+ <ui-error [errorId]="idPrefix() + '-assignments-error'" [message]="assignmentErrorShown()" />
45564
45916
  <ui-search-input placeholder="Search..." ariaLabel="Search assignments" [(value)]="assignmentSearch" />
45565
45917
  @if (filteredAssignments().length === 0) {
45566
45918
  <ui-empty-state iconType="search" title="No assignments found" message="No assignments match your search." />
@@ -45746,9 +46098,11 @@ i0.ɵɵngDeclareClassMetadata({
45746
46098
  <ui-button variant="ghost" size="xs" ariaLabel="Duplicate block" uiTooltip="Duplicate" (mousedown)="preventFocusLoss($event)" (click)="duplicateBlock(i)">
45747
46099
  <svg width="12" height="12" viewBox="0 0 24 24" fill="none" stroke="currentColor" stroke-width="2" aria-hidden="true"><rect x="9" y="9" width="13" height="13" rx="2"/><path d="M5 15H4a2 2 0 0 1-2-2V4a2 2 0 0 1 2-2h9a2 2 0 0 1 2 2v1"/></svg>
45748
46100
  </ui-button>
45749
- <ui-button variant="ghost" size="xs" ariaLabel="Delete block" uiTooltip="Delete block" (mousedown)="preventFocusLoss($event)" (click)="deleteBlock(i)">
45750
- <svg width="12" height="12" viewBox="0 0 24 24" fill="none" stroke="currentColor" stroke-width="2" aria-hidden="true"><polyline points="3 6 5 6 21 6"/><path d="M19 6l-1 14a2 2 0 0 1-2 2H8a2 2 0 0 1-2-2L5 6"/><path d="M10 11v6M14 11v6"/></svg>
45751
- </ui-button>
46101
+ @if (blocks().length > 1) {
46102
+ <ui-button variant="ghost" size="xs" ariaLabel="Delete block" uiTooltip="Delete block" (mousedown)="preventFocusLoss($event)" (click)="deleteBlock(i)">
46103
+ <svg width="12" height="12" viewBox="0 0 24 24" fill="none" stroke="currentColor" stroke-width="2" aria-hidden="true"><polyline points="3 6 5 6 21 6"/><path d="M19 6l-1 14a2 2 0 0 1-2 2H8a2 2 0 0 1-2-2L5 6"/><path d="M10 11v6M14 11v6"/></svg>
46104
+ </ui-button>
46105
+ }
45752
46106
  </div>
45753
46107
  }
45754
46108
  </div>
@@ -45859,8 +46213,9 @@ i0.ɵɵngDeclareClassMetadata({
45859
46213
  @for (v of group.variables; track v.key) {
45860
46214
  <button type="button" class="variable-item" (mousedown)="saveSelection()" (click)="insertVariable(v)">
45861
46215
  <span class="var-tag">{{ '{{' + v.key + '}}' }}</span>
45862
- <span class="var-label">{{ v.label }}</span>
45863
46216
  <span class="var-example">{{ v.example }}</span>
46217
+ <!-- A very short explanation of what the variable is: the host's description, else its label. -->
46218
+ <span class="var-description">{{ v.description || v.label }}</span>
45864
46219
  </button>
45865
46220
  }
45866
46221
  </div>
@@ -45953,7 +46308,7 @@ i0.ɵɵngDeclareClassMetadata({
45953
46308
 
45954
46309
 
45955
46310
  `,
45956
- styles: [":host{display:flex;flex-direction:column;flex:1;min-height:0}.required{color:#ef4444;font-weight:400}.editor-page{display:flex;flex-direction:column;flex:1;min-height:0;background:#f8fafc;overflow:hidden}.editor-actions{display:flex;justify-content:space-between;align-items:center;gap:8px 16px;flex-wrap:wrap;padding:0 0 12px;flex-shrink:0}.editor-heading{margin:0;font-size:1.25rem;font-weight:700;color:#1e293b;line-height:1.3;min-width:0}.editor-actions-buttons{display:flex;align-items:center;justify-content:flex-end;gap:8px;flex-wrap:wrap;margin-left:auto}.readonly-note{margin:0;padding:8px 16px;font-size:.8125rem;color:#92400e;background:#fffbeb;border-bottom:1px solid #fde68a}.readonly-note.system-note{display:flex;align-items:center;justify-content:space-between;gap:12px;flex-wrap:wrap}.editor-body{display:grid;grid-template-columns:340px minmax(0,1fr) 300px;grid-template-rows:minmax(0,1fr);flex:1;min-height:0;overflow:hidden}.panel-left{background:#fff;border-right:1px solid #e2e8f0;padding:24px;overflow-y:auto}.panel-title{font-size:1.0625rem;font-weight:700;color:#1e293b;margin:0 0 20px}.form-field{display:flex;flex-direction:column;gap:6px;margin-bottom:16px}.form-row-dates{display:grid;grid-template-columns:1fr 1fr;gap:12px;margin-top:16px}.assignments-section{border-top:1px solid #e2e8f0;padding-top:20px;margin-top:16px}.section-title{font-size:.9375rem;font-weight:700;color:#1e293b;margin:0 0 6px}.section-desc{font-size:.8125rem;color:#64748b;line-height:1.5;margin:0 0 12px}.assignment-list{max-height:340px;overflow-y:auto;margin-top:12px;border:1px solid #e2e8f0;border-radius:8px}.assignment-item{display:flex;align-items:center;justify-content:space-between;gap:10px;padding:12px 14px;cursor:pointer;border-bottom:1px solid #f1f5f9;transition:background .1s}.assignment-item:last-child{border-bottom:none}.assignment-item:hover{background:#f8fafc}.assignment-item:focus-visible{outline:2px solid #3b82f6;outline-offset:-2px}.assignment-item.assignment-readonly{cursor:default}.assignment-item.assignment-readonly:hover{background:transparent}.assignment-text{display:flex;flex-direction:column;gap:2px;flex:1;min-width:0}.assignment-text strong{font-size:.8125rem;color:#1e293b}.assignment-text span{font-size:.75rem;color:#64748b}.assignment-channels{display:flex;gap:4px;flex-shrink:0}.channel-badge{display:flex;align-items:center;justify-content:center;width:24px;height:24px;border-radius:4px;background:#f1f5f9;color:#94a3b8;transition:all .15s}.channel-badge.active{background:#3b82f6;color:#fff}.channel-badge.disabled{opacity:.4;cursor:not-allowed}.config-desc{font-size:.875rem;color:#64748b;line-height:1.5;margin:0}.config-divider{border:none;border-top:1px solid #e2e8f0;margin:20px 0}.config-section{display:flex;flex-direction:column;gap:12px}.config-section-label{font-size:.6875rem;font-weight:700;color:#3b82f6;text-transform:uppercase;letter-spacing:.04em}.config-field{display:flex;flex-direction:column;gap:6px}.config-field-mt{margin-top:16px}.config-label{font-size:.8125rem;font-weight:600;color:#1e293b}.config-readonly{padding:9px 12px;border:1px solid #e2e8f0;border-radius:8px;background:#f8fafc;font-size:.875rem;color:#1e293b}.config-hint{font-size:.75rem;color:#64748b}.test-save-note{display:flex;align-items:center;gap:8px;padding:10px 14px;background:#fef3c7;border:1px solid #fcd34d;border-radius:8px;font-size:.8125rem;color:#92400e;margin-top:12px}.test-save-note svg{flex-shrink:0}.panel-center{display:flex;flex-direction:column;min-height:0;min-width:0;overflow:hidden}.editor-tabs{display:flex;gap:2px;padding:12px 20px 0;background:#fff;border-bottom:1px solid #e2e8f0;overflow-x:auto;-webkit-overflow-scrolling:touch}.editor-tab{display:flex;align-items:center;gap:6px;padding:10px 16px;border:1px solid #e2e8f0;border-bottom:none;border-radius:8px 8px 0 0;background:#f8fafc;font-size:.8125rem;font-weight:600;color:#64748b;cursor:pointer;font-family:inherit;white-space:nowrap}.editor-tab:hover{background:#fff;color:#1e293b}.editor-tab.active{background:#eff6ff;color:#3b82f6;border-color:#93c5fd}.editor-tab:focus-visible,.right-tab:focus-visible,.block-group-header:focus-visible,.variable-item:focus-visible,.add-block-btn:focus-visible,.block-item:focus-visible,.video-lib-item:focus-visible{outline:2px solid #3b82f6;outline-offset:-2px}.editor-toolbar{display:flex;align-items:center;gap:8px;padding:10px 20px;background:#fff;border-bottom:1px solid #e2e8f0;flex-wrap:wrap}.toolbar-row-2{display:flex;align-items:center;gap:8px;flex-wrap:wrap;padding:8px 20px;background:#fff;border-bottom:1px solid #e2e8f0}.toolbar-group{display:flex;align-items:center;gap:2px;padding-right:8px;border-right:1px solid #e2e8f0}.toolbar-group:last-child{border-right:none;padding-right:0}.toolbar-select{display:block;min-width:96px}.toolbar-label{font-size:.75rem;font-weight:600;color:#64748b;white-space:nowrap;margin-right:6px}.hidden-color-input{position:absolute;width:0;height:0;opacity:0;pointer-events:none;border:none;padding:0}.color-indicator{display:flex;flex-direction:column;align-items:center;gap:2px;color:#475569}.color-bar{display:block;width:16px;height:3px;border-radius:2px;border:1px solid rgba(0,0,0,.1)}.link-dialog{background:#fff;border-bottom:1px solid #e2e8f0;padding:12px 20px}.link-dialog-inner{display:flex;align-items:flex-start;gap:8px;flex-wrap:wrap}.link-dialog-title{font-size:.8125rem;font-weight:700;color:#1e293b;white-space:nowrap;padding-top:10px}.link-dialog-input{display:block;width:240px;max-width:100%}.link-dialog-actions{display:flex;gap:6px}.preview-frame{flex:1;display:flex;justify-content:center;padding:24px;overflow-y:auto;background:#f1f5f9}.preview-frame.mobile{align-items:flex-start}.preview-content{max-width:600px;width:100%;box-sizing:border-box;background:#fff;border:1px solid #e2e8f0;border-radius:8px;padding:32px;min-height:400px;font-size:.9375rem;line-height:1.6;color:#1e293b;overflow-wrap:anywhere}.preview-content p{margin:0 0 8px}.mobile-shell{width:375px;max-width:100%;box-sizing:border-box;min-height:600px;border:2px solid #1e293b;border-radius:24px;padding:40px 12px 24px;background:#fff;box-shadow:0 8px 32px #0000001f}.mobile-shell .preview-content{border:none;border-radius:0;padding:16px;max-width:100%}.blocks-canvas{flex:1;padding:16px 20px 24px;overflow-y:auto;background:#f1f5f9;display:flex;flex-direction:column}.block-wrapper{position:relative;display:flex;align-items:flex-start;background:#fff;border:2px solid transparent;border-radius:8px;transition:border-color .15s,box-shadow .15s}.block-wrapper:hover,.block-wrapper.selected,.block-wrapper:focus-within{border-color:#3b82f6;box-shadow:0 0 0 3px #3b82f61a}.block-wrapper:hover .block-drag-handle,.block-wrapper.selected .block-drag-handle,.block-wrapper:focus-within .block-drag-handle{opacity:1}.block-wrapper:hover .block-controls,.block-wrapper.selected .block-controls,.block-wrapper:focus-within .block-controls{opacity:1;pointer-events:all}.block-wrapper.dragging{opacity:.4}.block-drag-handle{flex-shrink:0;width:28px;display:flex;align-items:flex-start;justify-content:center;padding-top:14px;opacity:0;transition:opacity .15s;cursor:grab;color:#94a3b8}.block-drag-handle:active{cursor:grabbing}.block-content{flex:1;min-width:0;padding:12px 16px;outline:none;font-size:.9375rem;color:#1e293b;line-height:1.6;min-height:48px;overflow-wrap:anywhere}.block-content:empty:before{content:\"Click to edit...\";color:#94a3b8;font-style:italic;pointer-events:none}.block-content p{margin:0 0 8px}.block-content p:last-child{margin:0}.block-content h1,.block-content h2,.block-content h3{margin:8px 0 6px;color:#1e293b}.block-content a{color:#3b82f6}.block-content img{max-width:100%;border-radius:6px}.block-content ul,.block-content ol{padding-left:20px;margin:0 0 8px}.block-controls{position:absolute;top:6px;right:6px;display:flex;gap:2px;opacity:0;pointer-events:none;transition:opacity .15s;background:#fff;border:1px solid #e2e8f0;border-radius:6px;padding:3px;box-shadow:0 2px 6px #00000014}@media(hover:none){.block-wrapper.selected .block-controls{opacity:1;pointer-events:all}}.drop-zone{height:8px;display:flex;align-items:center;justify-content:center;border-radius:4px;transition:height .15s,background .15s;position:relative}.drop-zone-label{font-size:.75rem;font-weight:600;color:#3b82f6;opacity:0;transition:opacity .1s}.drop-zone.active{height:40px;background:#3b82f614;border:2px dashed #3b82f6}.drop-zone.active .drop-zone-label{opacity:1}.add-block-btn{display:flex;align-items:center;justify-content:center;gap:8px;width:100%;min-height:44px;padding:12px;margin-top:8px;border:2px dashed #e2e8f0;border-radius:8px;background:none;font-size:.875rem;font-weight:600;color:#64748b;cursor:pointer;font-family:inherit;transition:border-color .15s,color .15s,background .15s}.add-block-btn:hover{border-color:#3b82f6;color:#3b82f6;background:#3b82f60a}.panel-right{background:#fff;border-left:1px solid #e2e8f0;display:flex;flex-direction:column;min-height:0;min-width:0}.right-tabs{display:flex;border-bottom:1px solid #e2e8f0}.right-tab{flex:1;display:flex;align-items:center;justify-content:center;gap:6px;padding:12px;min-height:44px;border:none;background:none;font-size:.8125rem;font-weight:600;color:#64748b;cursor:pointer;font-family:inherit;border-bottom:2px solid transparent}.right-tab:hover{color:#1e293b}.right-tab.active{color:#3b82f6;background:#eff6ff;border-bottom-color:#3b82f6}.right-panel-body{flex:1;padding:20px;overflow-y:auto}.right-section-title{font-size:.9375rem;font-weight:700;color:#1e293b;margin:0 0 12px}.right-section-desc{font-size:.8125rem;color:#64748b;margin:0 0 16px;line-height:1.5}.right-section-hint{font-size:.8125rem;color:#64748b;margin:0 0 12px;line-height:1.5}.block-group{border-bottom:1px solid #f1f5f9}.block-group-header{display:flex;align-items:center;gap:8px;width:100%;min-height:44px;padding:12px 0;border:none;background:none;font-size:.875rem;font-weight:600;color:#1e293b;cursor:pointer;font-family:inherit;text-align:left}.block-group-header .chevron{transition:transform .2s;color:#94a3b8}.block-group-header .chevron.expanded{transform:rotate(90deg)}.block-group-header span:nth-of-type(1){flex:1}.block-count{font-size:.75rem;font-weight:600;color:#64748b;background:#f1f5f9;padding:2px 8px;border-radius:10px;margin-left:auto}.block-list,.variable-list{display:flex;flex-direction:column;gap:2px;padding-bottom:8px}.block-item{display:flex;align-items:center;gap:6px;box-sizing:border-box;width:100%;min-height:44px;padding:8px 12px 8px 28px;font-size:.8125rem;color:#64748b;cursor:pointer;text-align:left;border-radius:4px;font-family:inherit;-webkit-user-select:none;user-select:none}.block-item:hover{background:#f8fafc;color:#1e293b}.block-item-drag{color:#cbd5e1;flex-shrink:0;cursor:grab}.variable-item{display:grid;grid-template-columns:auto 1fr auto;gap:8px;align-items:center;min-height:44px;padding:8px 12px 8px 28px;border:none;background:none;cursor:pointer;text-align:left;border-radius:4px;font-family:inherit}.variable-item:hover{background:#f8fafc}.var-tag{font-size:.75rem;font-weight:600;color:#3b82f6;background:#3b82f614;padding:2px 6px;border-radius:4px;font-family:ui-monospace,SFMono-Regular,Menlo,monospace}.var-label{font-size:.8125rem;color:#1e293b}.var-example{font-size:.75rem;color:#64748b;overflow-wrap:anywhere}.video-library-panel{padding:0}.video-library-panel .right-section-title,.video-library-panel .right-section-hint{padding:0 16px}.video-library-panel .right-section-title{padding-top:16px}.video-config-section{display:flex;flex-direction:column;gap:8px;padding:12px 16px;border-bottom:1px solid #f1f5f9}.video-config-section:last-of-type{border-bottom:none}.video-lib-list{display:flex;flex-direction:column;gap:2px;padding:8px 8px 16px}.video-lib-item{display:flex;align-items:center;gap:10px;width:100%;min-height:44px;padding:8px;border:1px solid transparent;border-radius:8px;background:none;cursor:pointer;text-align:left;font-family:inherit;transition:background .15s,border-color .15s}.video-lib-item:hover{background:#f8fafc;border-color:#e2e8f0}.video-lib-item.selected{background:#eff6ff;border-color:#93c5fd}.vli-thumb{position:relative;flex-shrink:0;width:56px;height:40px;border-radius:6px;background:linear-gradient(135deg,#f1f5f9,#e2e8f0);display:flex;align-items:center;justify-content:center}.vli-dur{position:absolute;bottom:2px;right:3px;font-size:.625rem;font-weight:600;color:#fff;background:#000000a6;padding:1px 4px;border-radius:3px}.vli-info{flex:1;min-width:0;display:flex;flex-direction:column;gap:2px}.vli-title{font-size:.8125rem;font-weight:600;color:#1e293b;overflow:hidden;text-overflow:ellipsis;white-space:nowrap}.vli-cat{font-size:.75rem;color:#64748b}.vli-check{flex-shrink:0}.video-lib-loading{padding:8px}.video-lib-skeleton{display:flex;align-items:center;gap:10px;padding:8px;margin-bottom:4px}.vls-info{flex:1;display:flex;flex-direction:column;gap:6px}@media(max-width:1200px){.editor-body{grid-template-columns:280px minmax(0,1fr) 260px}}@media(max-width:900px){:host{flex:none}.editor-page{flex:none;min-height:100vh;min-height:100dvh;overflow:visible}.editor-body{display:flex;flex-direction:column;flex:none;overflow:visible}.panel-left{border-right:none;border-bottom:1px solid #e2e8f0;overflow:visible;padding:16px}.panel-center{overflow:visible;min-height:480px}.blocks-canvas{overflow:visible;min-height:320px}.panel-right{border-left:none;border-top:1px solid #e2e8f0}.right-panel-body{overflow:visible}.editor-toolbar,.toolbar-row-2,.link-dialog,.editor-tabs{padding-left:12px;padding-right:12px}.preview-frame{padding:12px}.preview-content{padding:16px}.form-row-dates{grid-template-columns:1fr}}@media(prefers-reduced-motion:reduce){*{transition:none!important}}\n"]
46311
+ styles: [":host{display:flex;flex-direction:column;flex:1;min-height:0}.required{color:#ef4444;font-weight:400}.editor-page{display:flex;flex-direction:column;flex:1;min-height:0;background:#f8fafc;overflow:hidden}.editor-actions{display:flex;justify-content:space-between;align-items:center;gap:8px 16px;flex-wrap:wrap;padding:0 0 12px;flex-shrink:0}.editor-heading{margin:0;font-size:1.25rem;font-weight:700;color:#1e293b;line-height:1.3;min-width:0}.save-wrap{display:inline-flex}.editor-actions-buttons{display:flex;align-items:center;justify-content:flex-end;gap:8px;flex-wrap:wrap;margin-left:auto}.readonly-note{margin:0;padding:8px 16px;font-size:.8125rem;color:#92400e;background:#fffbeb;border-bottom:1px solid #fde68a}.readonly-note.system-note{display:flex;align-items:center;justify-content:space-between;gap:12px;flex-wrap:wrap}.editor-body{display:grid;grid-template-columns:340px minmax(0,1fr) 300px;grid-template-rows:minmax(0,1fr);flex:1;min-height:0;overflow:hidden}.panel-left{background:#fff;border-right:1px solid #e2e8f0;padding:24px;overflow-y:auto}.panel-title{font-size:1.0625rem;font-weight:700;color:#1e293b;margin:0 0 20px}.form-field{display:flex;flex-direction:column;gap:6px;margin-bottom:16px}.form-row-dates{display:grid;grid-template-columns:1fr 1fr;gap:12px;margin-top:16px}.assignments-section{border-top:1px solid #e2e8f0;padding-top:20px;margin-top:16px}.section-title{font-size:.9375rem;font-weight:700;color:#1e293b;margin:0 0 6px}.section-desc{font-size:.8125rem;color:#64748b;line-height:1.5;margin:0 0 12px}.assignment-list{max-height:340px;overflow-y:auto;margin-top:12px;border:1px solid #e2e8f0;border-radius:8px}.assignment-item{display:flex;align-items:center;justify-content:space-between;gap:10px;padding:12px 14px;cursor:pointer;border-bottom:1px solid #f1f5f9;transition:background .1s}.assignment-item:last-child{border-bottom:none}.assignment-item:hover{background:#f8fafc}.assignment-item:focus-visible{outline:2px solid #3b82f6;outline-offset:-2px}.assignment-item.assignment-readonly{cursor:default}.assignment-item.assignment-readonly:hover{background:transparent}.assignment-text{display:flex;flex-direction:column;gap:2px;flex:1;min-width:0}.assignment-text strong{font-size:.8125rem;color:#1e293b}.assignment-text span{font-size:.75rem;color:#64748b}.assignment-channels{display:flex;gap:4px;flex-shrink:0}.channel-badge{display:flex;align-items:center;justify-content:center;width:24px;height:24px;border-radius:4px;background:#f1f5f9;color:#94a3b8;transition:all .15s}.channel-badge.active{background:#3b82f6;color:#fff}.channel-badge.disabled{opacity:.4;cursor:not-allowed}.config-desc{font-size:.875rem;color:#64748b;line-height:1.5;margin:0}.config-divider{border:none;border-top:1px solid #e2e8f0;margin:20px 0}.config-section{display:flex;flex-direction:column;gap:12px}.config-section-label{font-size:.6875rem;font-weight:700;color:#3b82f6;text-transform:uppercase;letter-spacing:.04em}.config-field{display:flex;flex-direction:column;gap:6px}.config-field-mt{margin-top:16px}.config-label{font-size:.8125rem;font-weight:600;color:#1e293b}.config-readonly{padding:9px 12px;border:1px solid #e2e8f0;border-radius:8px;background:#f8fafc;font-size:.875rem;color:#1e293b}.config-hint{font-size:.75rem;color:#64748b}.test-save-note{display:flex;align-items:center;gap:8px;padding:10px 14px;background:#fef3c7;border:1px solid #fcd34d;border-radius:8px;font-size:.8125rem;color:#92400e;margin-top:12px}.test-save-note svg{flex-shrink:0}.panel-center{display:flex;flex-direction:column;min-height:0;min-width:0;overflow:hidden}.editor-tabs{display:flex;gap:2px;padding:12px 20px 0;background:#fff;border-bottom:1px solid #e2e8f0;overflow-x:auto;-webkit-overflow-scrolling:touch}.editor-tab{display:flex;align-items:center;gap:6px;padding:10px 16px;border:1px solid #e2e8f0;border-bottom:none;border-radius:8px 8px 0 0;background:#f8fafc;font-size:.8125rem;font-weight:600;color:#64748b;cursor:pointer;font-family:inherit;white-space:nowrap}.editor-tab:hover{background:#fff;color:#1e293b}.editor-tab.active{background:#eff6ff;color:#3b82f6;border-color:#93c5fd}.editor-tab:focus-visible,.right-tab:focus-visible,.block-group-header:focus-visible,.variable-item:focus-visible,.add-block-btn:focus-visible,.block-item:focus-visible,.video-lib-item:focus-visible{outline:2px solid #3b82f6;outline-offset:-2px}.editor-toolbar{display:flex;align-items:center;gap:8px;padding:10px 20px;background:#fff;border-bottom:1px solid #e2e8f0;flex-wrap:wrap}.toolbar-row-2{display:flex;align-items:center;gap:8px;flex-wrap:wrap;padding:8px 20px;background:#fff;border-bottom:1px solid #e2e8f0}.toolbar-group{display:flex;align-items:center;gap:2px;padding-right:8px;border-right:1px solid #e2e8f0}.toolbar-group:last-child{border-right:none;padding-right:0}.toolbar-select{display:block;min-width:96px}.toolbar-label{font-size:.75rem;font-weight:600;color:#64748b;white-space:nowrap;margin-right:6px}.hidden-color-input{position:absolute;width:0;height:0;opacity:0;pointer-events:none;border:none;padding:0}.color-indicator{display:flex;flex-direction:column;align-items:center;gap:2px;color:#475569}.color-bar{display:block;width:16px;height:3px;border-radius:2px;border:1px solid rgba(0,0,0,.1)}.link-dialog{background:#fff;border-bottom:1px solid #e2e8f0;padding:12px 20px}.link-dialog-inner{display:flex;align-items:flex-start;gap:8px;flex-wrap:wrap}.link-dialog-title{font-size:.8125rem;font-weight:700;color:#1e293b;white-space:nowrap;padding-top:10px}.link-dialog-input{display:block;width:240px;max-width:100%}.link-dialog-actions{display:flex;gap:6px}.preview-frame{flex:1;display:flex;justify-content:center;padding:24px;overflow-y:auto;background:#f1f5f9}.preview-frame.mobile{align-items:flex-start}.preview-content{max-width:600px;width:100%;box-sizing:border-box;background:#fff;border:1px solid #e2e8f0;border-radius:8px;padding:32px;min-height:400px;font-size:.9375rem;line-height:1.6;color:#1e293b;overflow-wrap:anywhere}.preview-content p{margin:0 0 8px}.mobile-shell{width:375px;max-width:100%;box-sizing:border-box;min-height:600px;border:2px solid #1e293b;border-radius:24px;padding:40px 12px 24px;background:#fff;box-shadow:0 8px 32px #0000001f}.mobile-shell .preview-content{border:none;border-radius:0;padding:16px;max-width:100%}.blocks-canvas{flex:1 1 0;min-height:0;padding:16px 20px 24px;overflow-y:auto;overscroll-behavior:contain;-webkit-overflow-scrolling:touch;background:#f1f5f9;display:flex;flex-direction:column}.block-wrapper{flex-shrink:0;position:relative;display:flex;align-items:flex-start;background:#fff;border:2px solid transparent;border-radius:8px;transition:border-color .15s,box-shadow .15s}.block-wrapper:hover,.block-wrapper.selected,.block-wrapper:focus-within{border-color:#3b82f6;box-shadow:0 0 0 3px #3b82f61a}.block-wrapper:hover .block-drag-handle,.block-wrapper.selected .block-drag-handle,.block-wrapper:focus-within .block-drag-handle{opacity:1}.block-wrapper:hover .block-controls,.block-wrapper.selected .block-controls,.block-wrapper:focus-within .block-controls{opacity:1;pointer-events:all}.block-wrapper.dragging{opacity:.4}.block-drag-handle{flex-shrink:0;width:28px;display:flex;align-items:flex-start;justify-content:center;padding-top:14px;opacity:0;transition:opacity .15s;cursor:grab;color:#94a3b8}.block-drag-handle:active{cursor:grabbing}.block-content{flex:1;min-width:0;padding:12px 16px;outline:none;font-size:.9375rem;color:#1e293b;line-height:1.6;min-height:48px;overflow-wrap:anywhere}.block-content:empty:before{content:\"Click to edit...\";color:#94a3b8;font-style:italic;pointer-events:none}.block-content p{margin:0 0 8px}.block-content p:last-child{margin:0}.block-content h1,.block-content h2,.block-content h3{margin:8px 0 6px;color:#1e293b}.block-content a{color:#3b82f6}.block-content img{max-width:100%;border-radius:6px}.block-content ul,.block-content ol{padding-left:20px;margin:0 0 8px}.block-controls{position:absolute;top:6px;right:6px;display:flex;gap:2px;opacity:0;pointer-events:none;transition:opacity .15s;background:#fff;border:1px solid #e2e8f0;border-radius:6px;padding:3px;box-shadow:0 2px 6px #00000014}@media(hover:none){.block-wrapper.selected .block-controls{opacity:1;pointer-events:all}}.drop-zone{flex-shrink:0;height:8px;display:flex;align-items:center;justify-content:center;border-radius:4px;transition:height .15s,background .15s;position:relative}.drop-zone-label{font-size:.75rem;font-weight:600;color:#3b82f6;opacity:0;transition:opacity .1s}.drop-zone.active{height:40px;background:#3b82f614;border:2px dashed #3b82f6}.drop-zone.active .drop-zone-label{opacity:1}.add-block-btn{flex-shrink:0;display:flex;align-items:center;justify-content:center;gap:8px;width:100%;min-height:44px;padding:12px;margin-top:8px;border:2px dashed #e2e8f0;border-radius:8px;background:none;font-size:.875rem;font-weight:600;color:#64748b;cursor:pointer;font-family:inherit;transition:border-color .15s,color .15s,background .15s}.add-block-btn:hover{border-color:#3b82f6;color:#3b82f6;background:#3b82f60a}.panel-right{background:#fff;border-left:1px solid #e2e8f0;display:flex;flex-direction:column;min-height:0;min-width:0}.right-tabs{display:flex;border-bottom:1px solid #e2e8f0}.right-tab{flex:1;display:flex;align-items:center;justify-content:center;gap:6px;padding:12px;min-height:44px;border:none;background:none;font-size:.8125rem;font-weight:600;color:#64748b;cursor:pointer;font-family:inherit;border-bottom:2px solid transparent}.right-tab:hover{color:#1e293b}.right-tab.active{color:#3b82f6;background:#eff6ff;border-bottom-color:#3b82f6}.right-panel-body{flex:1;padding:20px;overflow-y:auto}.right-section-title{font-size:.9375rem;font-weight:700;color:#1e293b;margin:0 0 12px}.right-section-desc{font-size:.8125rem;color:#64748b;margin:0 0 16px;line-height:1.5}.right-section-hint{font-size:.8125rem;color:#64748b;margin:0 0 12px;line-height:1.5}.block-group{border-bottom:1px solid #f1f5f9}.block-group-header{display:flex;align-items:center;gap:8px;width:100%;min-height:44px;padding:12px 0;border:none;background:none;font-size:.875rem;font-weight:600;color:#1e293b;cursor:pointer;font-family:inherit;text-align:left}.block-group-header .chevron{transition:transform .2s;color:#94a3b8}.block-group-header .chevron.expanded{transform:rotate(90deg)}.block-group-header span:nth-of-type(1){flex:1}.block-count{font-size:.75rem;font-weight:600;color:#64748b;background:#f1f5f9;padding:2px 8px;border-radius:10px;margin-left:auto}.block-list{display:flex;flex-direction:column;gap:2px;padding-bottom:8px}.variable-list{display:flex;flex-direction:column;padding-bottom:8px}.variable-item+.variable-item{border-top:1px solid #f1f5f9;border-radius:0}.block-item{display:flex;align-items:center;gap:6px;box-sizing:border-box;width:100%;min-height:44px;padding:8px 12px 8px 28px;font-size:.8125rem;color:#64748b;cursor:pointer;text-align:left;border-radius:4px;font-family:inherit;-webkit-user-select:none;user-select:none}.block-item:hover{background:#f8fafc;color:#1e293b}.block-item-drag{color:#cbd5e1;flex-shrink:0;cursor:grab}.variable-item{display:flex;flex-direction:column;align-items:flex-start;gap:4px;min-height:44px;padding:8px 0;min-width:0;width:100%;box-sizing:border-box;border:none;background:none;cursor:pointer;text-align:left;border-radius:4px;font-family:inherit}.variable-item:hover{background:#f8fafc}.var-tag{max-width:100%;overflow-wrap:anywhere;font-size:.75rem;font-weight:600;color:#3b82f6;background:#3b82f614;padding:2px 6px;border-radius:4px;font-family:ui-monospace,SFMono-Regular,Menlo,monospace}.var-example{font-size:.75rem;color:#64748b;overflow-wrap:anywhere}.var-description{font-size:.75rem;color:#64748b;line-height:1.4;overflow-wrap:anywhere}.video-library-panel{padding:0}.video-library-panel .right-section-title,.video-library-panel .right-section-hint{padding:0 16px}.video-library-panel .right-section-title{padding-top:16px}.video-config-section{display:flex;flex-direction:column;gap:8px;padding:12px 16px;border-bottom:1px solid #f1f5f9}.video-config-section:last-of-type{border-bottom:none}.video-lib-list{display:flex;flex-direction:column;gap:2px;padding:8px 8px 16px}.video-lib-item{display:flex;align-items:center;gap:10px;width:100%;min-height:44px;padding:8px;border:1px solid transparent;border-radius:8px;background:none;cursor:pointer;text-align:left;font-family:inherit;transition:background .15s,border-color .15s}.video-lib-item:hover{background:#f8fafc;border-color:#e2e8f0}.video-lib-item.selected{background:#eff6ff;border-color:#93c5fd}.vli-thumb{position:relative;flex-shrink:0;width:56px;height:40px;border-radius:6px;background:linear-gradient(135deg,#f1f5f9,#e2e8f0);display:flex;align-items:center;justify-content:center}.vli-dur{position:absolute;bottom:2px;right:3px;font-size:.625rem;font-weight:600;color:#fff;background:#000000a6;padding:1px 4px;border-radius:3px}.vli-info{flex:1;min-width:0;display:flex;flex-direction:column;gap:2px}.vli-title{font-size:.8125rem;font-weight:600;color:#1e293b;overflow:hidden;text-overflow:ellipsis;white-space:nowrap}.vli-cat{font-size:.75rem;color:#64748b}.vli-check{flex-shrink:0}.video-lib-loading{padding:8px}.video-lib-skeleton{display:flex;align-items:center;gap:10px;padding:8px;margin-bottom:4px}.vls-info{flex:1;display:flex;flex-direction:column;gap:6px}@media(max-width:1200px){.editor-body{grid-template-columns:280px minmax(0,1fr) 260px}}@media(max-width:900px){:host{flex:none}.editor-page{flex:none;min-height:100vh;min-height:100dvh;overflow:visible}.editor-body{display:flex;flex-direction:column;flex:none;overflow:visible}.panel-left{border-right:none;border-bottom:1px solid #e2e8f0;overflow:visible;padding:16px}.panel-center{overflow:visible;min-height:480px}.blocks-canvas{overflow:visible;min-height:320px}.panel-right{border-left:none;border-top:1px solid #e2e8f0}.right-panel-body{overflow:visible}.editor-toolbar,.toolbar-row-2,.link-dialog,.editor-tabs{padding-left:12px;padding-right:12px}.preview-frame{padding:12px}.preview-content{padding:16px}.form-row-dates{grid-template-columns:1fr}}@media(prefers-reduced-motion:reduce){*{transition:none!important}}\n"]
45957
46312
  }]
45958
46313
  }],
45959
46314
  ctorParameters: () => [],
@@ -46200,6 +46555,6 @@ i0.ɵɵngDeclareClassMetadata({
46200
46555
  }]
46201
46556
  }
46202
46557
  });
46203
- export { ActionBarComponent, AlertComponent, AppShellComponent, AudioPlayerComponent, AvatarComponent, BADGE_VARIANT_STYLES, BadgeComponent, BarRowComponent, BoardCardDirective, BoardComponent, BulkMessagePanelComponent, BusinessHoursComponent, ButtonComponent, CalendarComponent, CardListItemComponent, CheckboxComponent, CheckboxTrailingDirective, ChipComponent, ChipGroupComponent, ColorInputComponent, ColumnFilterComponent, ColumnsComponent, ComboboxComponent, ConfirmOutletComponent, ConfirmService, ContactPickerComponent, DEFAULT_EMAIL_TEMPLATE_BLOCK_GROUPS, DEFAULT_EMAIL_TEMPLATE_VARIABLE_GROUPS, DEFAULT_PASSWORD_RULES, DROPDOWN_GROUP, DataTableComponent, DateInputComponent, DateRangePickerComponent, DatetimeInputComponent, DetailCardComponent, DiscountSelectorComponent, DividerComponent, DropdownComponent, EMAIL_BLOCK_DRAG_TYPE, EMAIL_TEMPLATE_MAX_BODY, EMAIL_TEMPLATE_MAX_TEXT, EMAIL_TEMPLATE_START_TEXT, EmailTemplateEditorComponent, EmptyStateComponent, ErrorComponent, ErrorStateComponent, FORGEROUTE_CONFIG, FadeComponent, FileInputComponent, FormColSpanDirective, FormComponent, FormRowComponent, FormSectionComponent, HintComponent, IDX_BEHAVIOR_SIGNALS, INTEGRATION_CATALOG, INTEGRATION_FIELD_DEFS, INTEGRATION_GROUP_ORDER, INTEGRATION_OPTION_DEFS, IconComponent, ImageComponent, ImageGalleryComponent, ImageGalleryDialogComponent, ImagePreviewComponent, ImageRepositionComponent, ImportExportComponent, ImportSourceGridComponent, KpiCardComponent, LAYOUT_GAP_PX, ListComponent, ListItemComponent, LiveRegionComponent, MAX_EMAIL_ADDRESS_LENGTH, ModalComponent, MoreMenuComponent, MultiSelectComponent, NOTES_MAX_LENGTH, NotesComponent, PHONE_NUMBER_AREA_CODE_LENGTH, PHONE_NUMBER_ZIP_LENGTH, PageComponent, PaginationComponent, PanelInfoListComponent, PasswordRequirementsComponent, PdfHotspotComponent, PhoneNumberPickerComponent, PillTabsComponent, ProgressBarComponent, ProgressRingComponent, QrCodeComponent, QuickFilterTabsComponent, RICH_TEXT_OPTIONS, RadioComponent, RadioGroupComponent, RadioMatrixComponent, RadioOptionContentDirective, ReadonlyFieldsetComponent, RichTextEditorComponent, SEMANTIC_BADGE_MAP, SETUP_DONE_KEY, SETUP_INTEGRATIONS, SearchInputComponent, SectionHeaderComponent, SelectComponent, SetupWizardComponent, SetupWizardStepDirective, SetupWizardStepHeaderDirective, ShowComponent, SidePanelComponent, SidebarLayoutComponent, SignaturePadComponent, SkeletonComponent, StackComponent, StarComponent, StepperComponent, TableToolbarComponent, TextComponent, TextInputComponent, TextareaInputComponent, TimeInputComponent, TimelineComponent, ToastComponent, ToastService, ToggleBadgeComponent, ToggleComponent, TooltipDirective, US_STATES, UiFieldValidity, acceptLabel, appShellGroupsStorageKey, autoVariant, blockHasContent, buildDefaultSchedule, buildVideoBlockHtml, builtInActionIcon, businessTimeOptions, createFieldReveal, decodeFilterValues, digitsOnly, downloadBlob, encodeFilterValue, encodeFilterValues, errorContextInterceptor, escapeHtml, fileMatchesAccept, formatAddress, formatCategoryLabel, formatCurrency, formatFileSize, formatIsoDate, formatIsoDateTime, formatTime, formatVideoDuration, getEligibleIds, getEligibleOptions, getErrorMessage, humanReadableMessage, iconPath, insideEditorBlock, integrationPlainText, integrationsForApp, integrationsOnlyFor, isBlockDrag, isValidEmailAddress, isWebUrl, isoKey, issueToErrors, maxLengthIssue, normalizeHexColor, parseBizHours, parseIso, parseTime, passwordMeetsRules, pluralize, provideForgerouteToast, reorderItems, requiredIssue, resolveLayoutGap, resolvePreset, serializeBizHours, setupIntegrations, splitIntro };
46558
+ export { ActionBarComponent, AlertComponent, AppShellComponent, AudioPlayerComponent, AvatarComponent, BADGE_VARIANT_STYLES, BadgeComponent, BarRowComponent, BoardCardDirective, BoardComponent, BulkMessagePanelComponent, BusinessHoursComponent, ButtonComponent, CalendarComponent, CardListItemComponent, CheckboxComponent, CheckboxTrailingDirective, ChipComponent, ChipGroupComponent, ColorInputComponent, ColumnFilterComponent, ColumnsComponent, ComboboxComponent, ConfirmOutletComponent, ConfirmService, ContactPickerComponent, DEFAULT_EMAIL_TEMPLATE_BLOCK_GROUPS, DEFAULT_EMAIL_TEMPLATE_VARIABLE_GROUPS, DEFAULT_PASSWORD_RULES, DROPDOWN_GROUP, DataTableComponent, DateInputComponent, DateRangePickerComponent, DatetimeInputComponent, DetailCardComponent, DiscountSelectorComponent, DividerComponent, DropdownComponent, EMAIL_BLOCK_DRAG_TYPE, EMAIL_TEMPLATE_MAX_BODY, EMAIL_TEMPLATE_MAX_TEXT, EMAIL_TEMPLATE_START_TEXT, EmailTemplateEditorComponent, EmptyStateComponent, ErrorComponent, ErrorStateComponent, FORGEROUTE_CONFIG, FadeComponent, FileInputComponent, FormColSpanDirective, FormComponent, FormRowComponent, FormSectionComponent, HintComponent, IDX_BEHAVIOR_SIGNALS, INTEGRATION_CATALOG, INTEGRATION_FIELD_DEFS, INTEGRATION_GROUP_ORDER, INTEGRATION_OPTION_DEFS, IconComponent, ImageComponent, ImageGalleryComponent, ImageGalleryDialogComponent, ImagePreviewComponent, ImageRepositionComponent, ImportExportComponent, ImportSourceGridComponent, KpiCardComponent, LAYOUT_GAP_PX, ListComponent, ListItemComponent, LiveRegionComponent, MAX_EMAIL_ADDRESS_LENGTH, ModalComponent, MoreMenuComponent, MultiSelectComponent, NOTES_MAX_LENGTH, NotesComponent, OptionCardComponent, PHONE_NUMBER_AREA_CODE_LENGTH, PHONE_NUMBER_ZIP_LENGTH, PageComponent, PaginationComponent, PanelInfoListComponent, PasswordRequirementsComponent, PdfHotspotComponent, PhoneNumberPickerComponent, PillTabsComponent, ProgressBarComponent, ProgressRingComponent, QrCodeComponent, QuickFilterTabsComponent, RICH_TEXT_OPTIONS, RadioComponent, RadioGroupComponent, RadioMatrixComponent, RadioOptionContentDirective, ReadonlyFieldsetComponent, RichTextEditorComponent, SEMANTIC_BADGE_MAP, SETUP_DONE_KEY, SETUP_INTEGRATIONS, SearchInputComponent, SectionHeaderComponent, SelectComponent, SetupWizardComponent, SetupWizardStepDirective, SetupWizardStepHeaderDirective, ShowComponent, SidePanelComponent, SidebarLayoutComponent, SignaturePadComponent, SkeletonComponent, StackComponent, StarComponent, StepperComponent, TableToolbarComponent, TextComponent, TextInputComponent, TextareaInputComponent, TimeInputComponent, TimelineComponent, ToastComponent, ToastService, ToggleBadgeComponent, ToggleComponent, TooltipDirective, US_STATES, UiFieldValidity, acceptLabel, appShellGroupsStorageKey, autoVariant, blockHasContent, buildDefaultSchedule, buildVideoBlockHtml, builtInActionIcon, businessTimeOptions, createFieldReveal, decodeFilterValues, digitsOnly, downloadBlob, encodeFilterValue, encodeFilterValues, errorContextInterceptor, escapeHtml, fileMatchesAccept, formatAddress, formatCategoryLabel, formatCurrency, formatFileSize, formatIsoDate, formatIsoDateTime, formatTime, formatVideoDuration, getEligibleIds, getEligibleOptions, getErrorMessage, humanReadableMessage, iconPath, insideEditorBlock, integrationPlainText, integrationsForApp, integrationsOnlyFor, isBlockDrag, isValidEmailAddress, isWebUrl, isoKey, issueToErrors, maxLengthIssue, normalizeHexColor, parseBizHours, parseIso, parseTime, passwordMeetsRules, pluralize, provideForgerouteToast, reorderItems, requiredIssue, resolveLayoutGap, resolvePreset, serializeBizHours, setupIntegrations, splitIntro };
46204
46559
 
46205
46560
  //# sourceMappingURL=forgeroute-ui.mjs.map