@forgeroute/ui 0.4.33 → 0.4.34

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.
@@ -4352,6 +4352,7 @@ i0.ɵɵngDeclareClassMetadata({
4352
4352
  }
4353
4353
  });
4354
4354
  let nextTooltipId = 0;
4355
+ let openTooltip = null;
4355
4356
  var TooltipDirective = class TooltipDirective {
4356
4357
  constructor() {
4357
4358
  this.uiTooltip = input("", ...ngDevMode ? [{ debugName: "uiTooltip" }] : /* istanbul ignore next */ []);
@@ -4365,6 +4366,11 @@ var TooltipDirective = class TooltipDirective {
4365
4366
  show() {
4366
4367
  const text = this.uiTooltip();
4367
4368
  if (!text || this.bubble) return;
4369
+ openTooltip?.close();
4370
+ openTooltip = {
4371
+ owner: this,
4372
+ close: () => this.hide()
4373
+ };
4368
4374
  const el = this.doc.createElement("div");
4369
4375
  el.id = this.id;
4370
4376
  el.setAttribute("role", "tooltip");
@@ -4401,6 +4407,7 @@ var TooltipDirective = class TooltipDirective {
4401
4407
  hide() {
4402
4408
  this.bubble?.remove();
4403
4409
  this.bubble = null;
4410
+ if (openTooltip?.owner === this) openTooltip = null;
4404
4411
  this.host.removeAttribute("aria-describedby");
4405
4412
  }
4406
4413
  static {
@@ -18714,6 +18721,7 @@ var ToggleBadgeComponent = class ToggleBadgeComponent {
18714
18721
  this.label = input("", ...ngDevMode ? [{ debugName: "label" }] : /* istanbul ignore next */ []);
18715
18722
  this.active = input(false, ...ngDevMode ? [{ debugName: "active" }] : /* istanbul ignore next */ []);
18716
18723
  this.actions = input([], ...ngDevMode ? [{ debugName: "actions" }] : /* istanbul ignore next */ []);
18724
+ this.tooltip = input("", ...ngDevMode ? [{ debugName: "tooltip" }] : /* istanbul ignore next */ []);
18717
18725
  this.toggle = output();
18718
18726
  this.action = output();
18719
18727
  }
@@ -18755,6 +18763,13 @@ var ToggleBadgeComponent = class ToggleBadgeComponent {
18755
18763
  isSignal: true,
18756
18764
  isRequired: false,
18757
18765
  transformFunction: null
18766
+ },
18767
+ tooltip: {
18768
+ classPropertyName: "tooltip",
18769
+ publicName: "tooltip",
18770
+ isSignal: true,
18771
+ isRequired: false,
18772
+ transformFunction: null
18758
18773
  }
18759
18774
  },
18760
18775
  outputs: {
@@ -18764,7 +18779,7 @@ var ToggleBadgeComponent = class ToggleBadgeComponent {
18764
18779
  ngImport: i0,
18765
18780
  template: `
18766
18781
  <span class="tb" [class.active]="active()" [class.tb-has-actions]="actions().length > 0">
18767
- <button type="button" class="toggle-badge" [class.active]="active()" (click)="toggle.emit()">
18782
+ <button type="button" class="toggle-badge" [class.active]="active()" [uiTooltip]="tooltip()" (click)="toggle.emit()">
18768
18783
  <ng-content />
18769
18784
  {{ label() }}
18770
18785
  </button>
@@ -18807,7 +18822,7 @@ i0.ɵɵngDeclareClassMetadata({
18807
18822
  changeDetection: ChangeDetectionStrategy.OnPush,
18808
18823
  template: `
18809
18824
  <span class="tb" [class.active]="active()" [class.tb-has-actions]="actions().length > 0">
18810
- <button type="button" class="toggle-badge" [class.active]="active()" (click)="toggle.emit()">
18825
+ <button type="button" class="toggle-badge" [class.active]="active()" [uiTooltip]="tooltip()" (click)="toggle.emit()">
18811
18826
  <ng-content />
18812
18827
  {{ label() }}
18813
18828
  </button>
@@ -18852,6 +18867,14 @@ i0.ɵɵngDeclareClassMetadata({
18852
18867
  required: false
18853
18868
  }]
18854
18869
  }],
18870
+ tooltip: [{
18871
+ type: i0.Input,
18872
+ args: [{
18873
+ isSignal: true,
18874
+ alias: "tooltip",
18875
+ required: false
18876
+ }]
18877
+ }],
18855
18878
  toggle: [{
18856
18879
  type: i0.Output,
18857
18880
  args: ["toggle"]
@@ -20577,7 +20600,8 @@ var BulkMessagePanelComponent = class BulkMessagePanelComponent {
20577
20600
  inputs: [
20578
20601
  "label",
20579
20602
  "active",
20580
- "actions"
20603
+ "actions",
20604
+ "tooltip"
20581
20605
  ],
20582
20606
  outputs: ["toggle", "action"]
20583
20607
  },
@@ -42343,6 +42367,8 @@ const str = (v) => typeof v === "string" ? v : "";
42343
42367
  const SETUP_INTEGRATIONS = {
42344
42368
  quickbooks: {
42345
42369
  key: "quickbooks",
42370
+ letter: "Q",
42371
+ color: "#2ca01c",
42346
42372
  title: "QuickBooks Online",
42347
42373
  icon: "bank",
42348
42374
  description: "Sync commissions and expenses to your QuickBooks books.",
@@ -42355,6 +42381,8 @@ const SETUP_INTEGRATIONS = {
42355
42381
  },
42356
42382
  slack: {
42357
42383
  key: "slack",
42384
+ letter: "S",
42385
+ color: "#4a154b",
42358
42386
  title: "Slack",
42359
42387
  icon: "message",
42360
42388
  description: "Get new-lead and deal alerts in a Slack channel.",
@@ -42367,6 +42395,8 @@ const SETUP_INTEGRATIONS = {
42367
42395
  },
42368
42396
  twilio: {
42369
42397
  key: "twilio",
42398
+ letter: "T",
42399
+ color: "#f22f46",
42370
42400
  title: "Twilio (calls & texts)",
42371
42401
  icon: "call",
42372
42402
  description: "Get a business phone number for texting and calling clients.",
@@ -42379,6 +42409,8 @@ const SETUP_INTEGRATIONS = {
42379
42409
  },
42380
42410
  gmail: {
42381
42411
  key: "gmail",
42412
+ letter: "G",
42413
+ color: "#ea4335",
42382
42414
  title: "Gmail / Google Workspace",
42383
42415
  icon: "email",
42384
42416
  description: "Connect your Google account for two-way email sync.",
@@ -42392,6 +42424,8 @@ const SETUP_INTEGRATIONS = {
42392
42424
  },
42393
42425
  outlook: {
42394
42426
  key: "outlook",
42427
+ letter: "O",
42428
+ color: "#0078d4",
42395
42429
  title: "Outlook / Microsoft 365",
42396
42430
  icon: "email",
42397
42431
  description: "Connect your Microsoft account for two-way email sync.",
@@ -42405,6 +42439,8 @@ const SETUP_INTEGRATIONS = {
42405
42439
  },
42406
42440
  "google-calendar": {
42407
42441
  key: "google-calendar",
42442
+ letter: "G",
42443
+ color: "#4285f4",
42408
42444
  title: "Google Calendar",
42409
42445
  icon: "link",
42410
42446
  description: "Two-way sync with your Google Calendar.",
@@ -42418,6 +42454,8 @@ const SETUP_INTEGRATIONS = {
42418
42454
  },
42419
42455
  "outlook-calendar": {
42420
42456
  key: "outlook-calendar",
42457
+ letter: "O",
42458
+ color: "#0078d4",
42421
42459
  title: "Outlook Calendar",
42422
42460
  icon: "link",
42423
42461
  description: "Two-way sync with your Outlook / Microsoft 365 calendar.",
@@ -42618,7 +42656,8 @@ var SetupWizardComponent = class SetupWizardComponent {
42618
42656
  this.busy = signal(false, ...ngDevMode ? [{ debugName: "busy" }] : /* istanbul ignore next */ []);
42619
42657
  this.api = {
42620
42658
  saveAndContinue: () => this.saveAndContinue(),
42621
- busy: () => this.busy()
42659
+ busy: () => this.busy(),
42660
+ markCompleted: (...keys) => this.markStepsCompleted(keys)
42622
42661
  };
42623
42662
  this.error = signal("", ...ngDevMode ? [{ debugName: "error" }] : /* istanbul ignore next */ []);
42624
42663
  this.areaCodeOpen = signal("", ...ngDevMode ? [{ debugName: "areaCodeOpen" }] : /* istanbul ignore next */ []);
@@ -42699,6 +42738,10 @@ var SetupWizardComponent = class SetupWizardComponent {
42699
42738
  this.skipped.update((s) => new Set(s).add(key));
42700
42739
  this.advanceFrom(key);
42701
42740
  }
42741
+ markStepsCompleted(keys) {
42742
+ const known = new Set(this.steps().map((s) => s.key));
42743
+ for (const key of keys) if (known.has(key)) this.markCompleted(key);
42744
+ }
42702
42745
  markCompleted(key) {
42703
42746
  this.completed.update((s) => new Set(s).add(key));
42704
42747
  this.skipped.update((s) => {
@@ -42925,6 +42968,9 @@ var SetupWizardComponent = class SetupWizardComponent {
42925
42968
  @if (headerTemplateFor(current().key); as ht) {
42926
42969
  <div card-header-action class="sw-header-action" data-testid="wizard-card-header-action"><ng-container [ngTemplateOutlet]="ht" [ngTemplateOutletContext]="{ $implicit: api }" /></div>
42927
42970
  }
42971
+ @if (current().kind !== 'custom' && templateFor(current().key); as extra) {
42972
+ <ng-container [ngTemplateOutlet]="extra" [ngTemplateOutletContext]="{ $implicit: api }" />
42973
+ }
42928
42974
  @switch (current().kind) {
42929
42975
  @case ('custom') {
42930
42976
  @if (templateFor(current().key); as tpl) { <ng-container [ngTemplateOutlet]="tpl" [ngTemplateOutletContext]="{ $implicit: api }" /> }
@@ -42956,22 +43002,21 @@ var SetupWizardComponent = class SetupWizardComponent {
42956
43002
  @case ('integrations') {
42957
43003
  <div class="sw-provider-grid">
42958
43004
  @for (it of current().integrations ?? []; track it.key) {
42959
- <ui-detail-card class="sw-integration" [attr.data-testid]="'integration-' + it.key" [title]="it.title" [uppercaseTitle]="false" [headingLevel]="current().cardTitle ? 4 : 3" [collapsible]="false"
42960
- headerBackground="rgb(248, 250, 252)" footerBackground="rgb(248, 250, 252)">
42961
- <span card-header-leading class="sw-int-icon" aria-hidden="true"><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>
42962
- @if (isConnected(it)) { <ui-badge card-header-action [label]="t().connected" variant="green" /> }
42963
- <p class="sw-int-detail">{{ detailFor(it) }}</p>
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>
42964
43014
  @if (areaCodeOpen() === it.key) {
42965
43015
  <div class="sw-area-code" [attr.data-testid]="'area-code-' + it.key">
42966
43016
  <ui-text-input [label]="areaCodeLabelFor(it)" [maxlength]="3" inputmode="numeric" [ngModel]="areaCode()" (ngModelChange)="areaCode.set($event ?? '')" [inputTestId]="'area-code-input-' + it.key" />
42967
43017
  <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>
42968
43018
  </div>
42969
43019
  }
42970
- <div card-footer class="sw-int-footer">
42971
- <ui-button variant="secondary" size="sm" [ariaLabel]="(isConnected(it) ? t().reconnect : t().connect) + ' ' + it.title" (click)="connect(it)">
42972
- <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> {{ isConnected(it) ? t().reconnect : t().connect }}
42973
- </ui-button>
42974
- </div>
42975
43020
  </ui-detail-card>
42976
43021
  }
42977
43022
  </div>
@@ -43006,7 +43051,7 @@ var SetupWizardComponent = class SetupWizardComponent {
43006
43051
  </div>
43007
43052
  `,
43008
43053
  isInline: true,
43009
- 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:16px;margin-bottom:8px}@media(max-width:768px){.sw-provider-grid{grid-template-columns:1fr}}.sw-provider-grid .sw-integration{margin-bottom:0}.sw-int-icon{display:inline-flex;color:#2563eb}.sw-int-detail{margin:0;font-size:.875rem;line-height:1.5;color:#475569}.sw-int-footer{display:flex;justify-content:flex-end}.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"],
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"],
43010
43055
  dependencies: [
43011
43056
  {
43012
43057
  kind: "directive",
@@ -43341,6 +43386,9 @@ i0.ɵɵngDeclareClassMetadata({
43341
43386
  @if (headerTemplateFor(current().key); as ht) {
43342
43387
  <div card-header-action class="sw-header-action" data-testid="wizard-card-header-action"><ng-container [ngTemplateOutlet]="ht" [ngTemplateOutletContext]="{ $implicit: api }" /></div>
43343
43388
  }
43389
+ @if (current().kind !== 'custom' && templateFor(current().key); as extra) {
43390
+ <ng-container [ngTemplateOutlet]="extra" [ngTemplateOutletContext]="{ $implicit: api }" />
43391
+ }
43344
43392
  @switch (current().kind) {
43345
43393
  @case ('custom') {
43346
43394
  @if (templateFor(current().key); as tpl) { <ng-container [ngTemplateOutlet]="tpl" [ngTemplateOutletContext]="{ $implicit: api }" /> }
@@ -43372,22 +43420,21 @@ i0.ɵɵngDeclareClassMetadata({
43372
43420
  @case ('integrations') {
43373
43421
  <div class="sw-provider-grid">
43374
43422
  @for (it of current().integrations ?? []; track it.key) {
43375
- <ui-detail-card class="sw-integration" [attr.data-testid]="'integration-' + it.key" [title]="it.title" [uppercaseTitle]="false" [headingLevel]="current().cardTitle ? 4 : 3" [collapsible]="false"
43376
- headerBackground="rgb(248, 250, 252)" footerBackground="rgb(248, 250, 252)">
43377
- <span card-header-leading class="sw-int-icon" aria-hidden="true"><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>
43378
- @if (isConnected(it)) { <ui-badge card-header-action [label]="t().connected" variant="green" /> }
43379
- <p class="sw-int-detail">{{ detailFor(it) }}</p>
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>
43380
43432
  @if (areaCodeOpen() === it.key) {
43381
43433
  <div class="sw-area-code" [attr.data-testid]="'area-code-' + it.key">
43382
43434
  <ui-text-input [label]="areaCodeLabelFor(it)" [maxlength]="3" inputmode="numeric" [ngModel]="areaCode()" (ngModelChange)="areaCode.set($event ?? '')" [inputTestId]="'area-code-input-' + it.key" />
43383
43435
  <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>
43384
43436
  </div>
43385
43437
  }
43386
- <div card-footer class="sw-int-footer">
43387
- <ui-button variant="secondary" size="sm" [ariaLabel]="(isConnected(it) ? t().reconnect : t().connect) + ' ' + it.title" (click)="connect(it)">
43388
- <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> {{ isConnected(it) ? t().reconnect : t().connect }}
43389
- </ui-button>
43390
- </div>
43391
43438
  </ui-detail-card>
43392
43439
  }
43393
43440
  </div>
@@ -43421,7 +43468,7 @@ i0.ɵɵngDeclareClassMetadata({
43421
43468
  </main>
43422
43469
  </div>
43423
43470
  `,
43424
- 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:16px;margin-bottom:8px}@media(max-width:768px){.sw-provider-grid{grid-template-columns:1fr}}.sw-provider-grid .sw-integration{margin-bottom:0}.sw-int-icon{display:inline-flex;color:#2563eb}.sw-int-detail{margin:0;font-size:.875rem;line-height:1.5;color:#475569}.sw-int-footer{display:flex;justify-content:flex-end}.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"]
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"]
43425
43472
  }]
43426
43473
  }],
43427
43474
  ctorParameters: () => [],
@@ -43736,16 +43783,15 @@ var EmailTemplateEditorComponent = class EmailTemplateEditorComponent {
43736
43783
  constructor() {
43737
43784
  this.host = inject(ElementRef);
43738
43785
  this.injector = inject(Injector);
43739
- this.toast = inject(ToastService);
43740
43786
  this.template = input(null, ...ngDevMode ? [{ debugName: "template" }] : /* istanbul ignore next */ []);
43741
43787
  this.categories = input([], ...ngDevMode ? [{ debugName: "categories" }] : /* istanbul ignore next */ []);
43742
43788
  this.categoryPlaceholder = input("Select category...", ...ngDevMode ? [{ debugName: "categoryPlaceholder" }] : /* istanbul ignore next */ []);
43743
43789
  this.assignmentOptions = input([], ...ngDevMode ? [{ debugName: "assignmentOptions" }] : /* istanbul ignore next */ []);
43744
43790
  this.featuredAssignmentKey = input(null, ...ngDevMode ? [{ debugName: "featuredAssignmentKey" }] : /* istanbul ignore next */ []);
43745
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 */ []);
43746
- this.textEnabled = input(false, ...ngDevMode ? [{ debugName: "textEnabled" }] : /* istanbul ignore next */ []);
43747
43792
  this.variableGroups = input(DEFAULT_EMAIL_TEMPLATE_VARIABLE_GROUPS, ...ngDevMode ? [{ debugName: "variableGroups" }] : /* istanbul ignore next */ []);
43748
43793
  this.blockGroups = input(DEFAULT_EMAIL_TEMPLATE_BLOCK_GROUPS, ...ngDevMode ? [{ debugName: "blockGroups" }] : /* istanbul ignore next */ []);
43794
+ this.heading = input("", ...ngDevMode ? [{ debugName: "heading" }] : /* istanbul ignore next */ []);
43749
43795
  this.namePlaceholder = input("e.g. Follow-Up — Friendly", ...ngDevMode ? [{ debugName: "namePlaceholder" }] : /* istanbul ignore next */ []);
43750
43796
  this.subjectPlaceholder = input("e.g. Following up on {{property_address}}", ...ngDevMode ? [{ debugName: "subjectPlaceholder" }] : /* istanbul ignore next */ []);
43751
43797
  this.systemNote = input("This is a built-in system template, so it can be viewed but not changed.", ...ngDevMode ? [{ debugName: "systemNote" }] : /* istanbul ignore next */ []);
@@ -43780,11 +43826,10 @@ var EmailTemplateEditorComponent = class EmailTemplateEditorComponent {
43780
43826
  this.activeTo = signal("", ...ngDevMode ? [{ debugName: "activeTo" }] : /* istanbul ignore next */ []);
43781
43827
  this.videoId = signal(null, ...ngDevMode ? [{ debugName: "videoId" }] : /* istanbul ignore next */ []);
43782
43828
  this.videoTitle = signal(null, ...ngDevMode ? [{ debugName: "videoTitle" }] : /* istanbul ignore next */ []);
43783
- this.assignmentChannels = signal({}, ...ngDevMode ? [{ debugName: "assignmentChannels" }] : /* istanbul ignore next */ []);
43829
+ this.assignedKeys = signal([], ...ngDevMode ? [{ debugName: "assignedKeys" }] : /* istanbul ignore next */ []);
43784
43830
  this.assignmentState = computed(() => this.assignmentOptions().map((o) => ({
43785
43831
  ...o,
43786
- email: !!this.assignmentChannels()[o.key]?.email,
43787
- text: !!this.assignmentChannels()[o.key]?.text
43832
+ assigned: this.assignedKeys().includes(o.key)
43788
43833
  })), ...ngDevMode ? [{ debugName: "assignmentState" }] : /* istanbul ignore next */ []);
43789
43834
  this.blocks = signal([], ...ngDevMode ? [{ debugName: "blocks" }] : /* istanbul ignore next */ []);
43790
43835
  this.selectedBlockId = signal(null, ...ngDevMode ? [{ debugName: "selectedBlockId" }] : /* istanbul ignore next */ []);
@@ -43816,10 +43861,6 @@ var EmailTemplateEditorComponent = class EmailTemplateEditorComponent {
43816
43861
  this.imageAlt = signal("", ...ngDevMode ? [{ debugName: "imageAlt" }] : /* istanbul ignore next */ []);
43817
43862
  this.showTestSendDialog = signal(false, ...ngDevMode ? [{ debugName: "showTestSendDialog" }] : /* istanbul ignore next */ []);
43818
43863
  this.testSendEmail = signal("", ...ngDevMode ? [{ debugName: "testSendEmail" }] : /* istanbul ignore next */ []);
43819
- this.showAssignmentConfig = signal(false, ...ngDevMode ? [{ debugName: "showAssignmentConfig" }] : /* istanbul ignore next */ []);
43820
- this.configTarget = signal(null, ...ngDevMode ? [{ debugName: "configTarget" }] : /* istanbul ignore next */ []);
43821
- this.configEmail = signal(false, ...ngDevMode ? [{ debugName: "configEmail" }] : /* istanbul ignore next */ []);
43822
- this.configText = signal(false, ...ngDevMode ? [{ debugName: "configText" }] : /* istanbul ignore next */ []);
43823
43864
  this.activeEditorTab = signal("edit", ...ngDevMode ? [{ debugName: "activeEditorTab" }] : /* istanbul ignore next */ []);
43824
43865
  this.activeRightTab = signal("blocks", ...ngDevMode ? [{ debugName: "activeRightTab" }] : /* istanbul ignore next */ []);
43825
43866
  this.blockSearch = signal("", ...ngDevMode ? [{ debugName: "blockSearch" }] : /* istanbul ignore next */ []);
@@ -43972,10 +44013,7 @@ var EmailTemplateEditorComponent = class EmailTemplateEditorComponent {
43972
44013
  this.submitAttempted.set(false);
43973
44014
  this.nameTouched.set(false);
43974
44015
  this.subjectTouched.set(false);
43975
- this.assignmentChannels.set(Object.fromEntries((t?.assignments ?? []).map((c) => [c.key, {
43976
- email: !!c.email,
43977
- text: !!c.text
43978
- }])));
44016
+ this.assignedKeys.set([...t?.assignments ?? []]);
43979
44017
  this.savedSnapshot.set(t?.id ? this.snapshot() : null);
43980
44018
  }
43981
44019
  onSave() {
@@ -43995,11 +44033,7 @@ var EmailTemplateEditorComponent = class EmailTemplateEditorComponent {
43995
44033
  activeFrom: !this.useAllYear() && this.activeFrom() ? this.activeFrom() : null,
43996
44034
  activeTo: !this.useAllYear() && this.activeTo() ? this.activeTo() : null,
43997
44035
  videoId: this.videoId(),
43998
- assignments: this.assignmentState().filter((a) => a.email || a.text).map((a) => ({
43999
- key: a.key,
44000
- email: a.email,
44001
- text: a.text
44002
- }))
44036
+ assignments: this.assignmentState().filter((a) => a.assigned).map((a) => a.key)
44003
44037
  });
44004
44038
  }
44005
44039
  snapshot() {
@@ -44422,27 +44456,9 @@ var EmailTemplateEditorComponent = class EmailTemplateEditorComponent {
44422
44456
  categoryLabel(cat) {
44423
44457
  return formatCategoryLabel(cat);
44424
44458
  }
44425
- openAssignmentConfig(item) {
44459
+ toggleAssignment(item) {
44426
44460
  if (!this.canWrite()) return;
44427
- this.configTarget.set(item);
44428
- this.configEmail.set(item.email);
44429
- this.configText.set(item.text);
44430
- this.showAssignmentConfig.set(true);
44431
- }
44432
- saveAssignmentConfig() {
44433
- const target = this.configTarget();
44434
- if (!this.canWrite() || !target) return;
44435
- const email = this.configEmail();
44436
- const text = this.configText();
44437
- this.assignmentChannels.update((m) => ({
44438
- ...m,
44439
- [target.key]: {
44440
- email,
44441
- text
44442
- }
44443
- }));
44444
- this.showAssignmentConfig.set(false);
44445
- this.toast.show(`${target.name} automation configured`);
44461
+ this.assignedKeys.update((keys) => keys.includes(item.key) ? keys.filter((k) => k !== item.key) : [...keys, item.key]);
44446
44462
  }
44447
44463
  isOpen(id) {
44448
44464
  return id === "v:" + (this.variableGroups()[0]?.name ?? "") !== this.toggledGroups().has(id);
@@ -44533,13 +44549,6 @@ var EmailTemplateEditorComponent = class EmailTemplateEditorComponent {
44533
44549
  isRequired: false,
44534
44550
  transformFunction: null
44535
44551
  },
44536
- textEnabled: {
44537
- classPropertyName: "textEnabled",
44538
- publicName: "textEnabled",
44539
- isSignal: true,
44540
- isRequired: false,
44541
- transformFunction: null
44542
- },
44543
44552
  variableGroups: {
44544
44553
  classPropertyName: "variableGroups",
44545
44554
  publicName: "variableGroups",
@@ -44554,6 +44563,13 @@ var EmailTemplateEditorComponent = class EmailTemplateEditorComponent {
44554
44563
  isRequired: false,
44555
44564
  transformFunction: null
44556
44565
  },
44566
+ heading: {
44567
+ classPropertyName: "heading",
44568
+ publicName: "heading",
44569
+ isSignal: true,
44570
+ isRequired: false,
44571
+ transformFunction: null
44572
+ },
44557
44573
  namePlaceholder: {
44558
44574
  classPropertyName: "namePlaceholder",
44559
44575
  publicName: "namePlaceholder",
@@ -44704,6 +44720,10 @@ var EmailTemplateEditorComponent = class EmailTemplateEditorComponent {
44704
44720
  <div class="editor-page">
44705
44721
  <!-- Actions (outside the white panels) -->
44706
44722
  <div class="editor-actions">
44723
+ @if (heading()) {
44724
+ <h1 class="editor-heading" data-testid="editor-heading">{{ heading() }}</h1>
44725
+ }
44726
+ <div class="editor-actions-buttons">
44707
44727
  @if (canWrite() && testSendEnabled()) {
44708
44728
  <ui-button variant="secondary" size="sm" (click)="openTestSendDialog()">
44709
44729
  <svg width="14" height="14" viewBox="0 0 24 24" fill="none" stroke="currentColor" stroke-width="2" aria-hidden="true"><line x1="22" y1="2" x2="11" y2="13"/><polygon points="22 2 15 22 11 13 2 9 22 2"/></svg>
@@ -44714,6 +44734,7 @@ var EmailTemplateEditorComponent = class EmailTemplateEditorComponent {
44714
44734
  <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>
44715
44735
  Save Template
44716
44736
  </ui-button>
44737
+ </div>
44717
44738
  </div>
44718
44739
  <ui-divider />
44719
44740
 
@@ -44769,20 +44790,17 @@ var EmailTemplateEditorComponent = class EmailTemplateEditorComponent {
44769
44790
  }
44770
44791
  <div class="assignment-list" [hidden]="filteredAssignments().length === 0">
44771
44792
  @for (item of filteredAssignments(); track item.key) {
44772
- <div class="assignment-item" [class.assignment-readonly]="!canWrite()" [attr.role]="canWrite() ? 'button' : null" [attr.tabindex]="canWrite() ? 0 : null"
44773
- [attr.aria-label]="canWrite() ? 'Configure ' + item.name : null"
44774
- (click)="openAssignmentConfig(item)" (keydown.enter)="openAssignmentConfig(item); $event.preventDefault()" (keydown.space)="openAssignmentConfig(item); $event.preventDefault()">
44793
+ <div class="assignment-item" [class.assignment-readonly]="!canWrite()" [attr.role]="canWrite() ? 'switch' : null" [attr.tabindex]="canWrite() ? 0 : null"
44794
+ [attr.aria-checked]="canWrite() ? item.assigned : null" [attr.aria-label]="canWrite() ? item.name : null"
44795
+ (click)="toggleAssignment(item)" (keydown.enter)="toggleAssignment(item); $event.preventDefault()" (keydown.space)="toggleAssignment(item); $event.preventDefault()">
44775
44796
  <div class="assignment-text">
44776
44797
  <strong>{{ item.name }}</strong>
44777
44798
  <span>{{ item.description }}</span>
44778
44799
  </div>
44779
44800
  <div class="assignment-channels">
44780
- <span class="channel-badge" [class.active]="item.email" role="img" [attr.aria-label]="'Email ' + (item.email ? 'on' : 'off')">
44801
+ <span class="channel-badge" [class.active]="item.assigned" role="img" [attr.aria-label]="'Email ' + (item.assigned ? 'on' : 'off')">
44781
44802
  <svg width="10" height="10" viewBox="0 0 24 24" fill="none" stroke="currentColor" stroke-width="2" aria-hidden="true"><rect x="2" y="4" width="20" height="16" rx="2"/><path d="m22 7-8.97 5.7a1.94 1.94 0 0 1-2.06 0L2 7"/></svg>
44782
44803
  </span>
44783
- <span class="channel-badge" [class.active]="item.text" [class.disabled]="!textEnabled()" role="img" [attr.aria-label]="'Text ' + (item.text ? 'on' : 'off')">
44784
- <svg width="10" height="10" viewBox="0 0 24 24" fill="none" stroke="currentColor" stroke-width="2" aria-hidden="true"><path d="M21 15a2 2 0 0 1-2 2H7l-4 4V5a2 2 0 0 1 2-2h14a2 2 0 0 1 2 2z"/></svg>
44785
- </span>
44786
44804
  </div>
44787
44805
  </div>
44788
44806
  }
@@ -45157,31 +45175,9 @@ var EmailTemplateEditorComponent = class EmailTemplateEditorComponent {
45157
45175
  </ui-side-panel>
45158
45176
 
45159
45177
 
45160
- <!-- Assignment config -->
45161
- <ui-side-panel [wide]="true" [open]="showAssignmentConfig()" [title]="configTarget()?.name || 'Configure Automation'" primaryLabel="Save Configuration"
45162
- [primaryDisabled]="!configEmail() && !configText()" (closed)="showAssignmentConfig.set(false)" (primaryClick)="saveAssignmentConfig()">
45163
- @if (configTarget(); as target) {
45164
- <p class="config-desc">{{ target.description }}</p>
45165
- <hr class="config-divider" />
45166
- <div class="config-section">
45167
- <span class="config-section-label">EMAIL TEMPLATE</span>
45168
- <div class="config-field">
45169
- <span class="config-label">Assigned Template</span>
45170
- <div class="config-readonly">{{ name() || 'Current template' }}</div>
45171
- <span class="config-hint">This template will be used when this automation is triggered.</span>
45172
- </div>
45173
- </div>
45174
- <hr class="config-divider" />
45175
- <div class="config-section">
45176
- <span class="config-section-label">CHANNELS <span class="required" aria-hidden="true">*</span></span>
45177
- <ui-checkbox label="Email" [(checked)]="configEmail" />
45178
- <ui-checkbox label="Text (SMS)" [(checked)]="configText" [disabled]="!textEnabled()" [hint]="textEnabled() ? '' : '(not enabled)'" />
45179
- </div>
45180
- }
45181
- </ui-side-panel>
45182
45178
  `,
45183
45179
  isInline: true,
45184
- 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:flex-end;align-items:center;gap:8px;flex-wrap:wrap;padding:0 0 12px;flex-shrink:0}.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"],
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"],
45185
45181
  dependencies: [
45186
45182
  {
45187
45183
  kind: "ngmodule",
@@ -45501,6 +45497,10 @@ i0.ɵɵngDeclareClassMetadata({
45501
45497
  <div class="editor-page">
45502
45498
  <!-- Actions (outside the white panels) -->
45503
45499
  <div class="editor-actions">
45500
+ @if (heading()) {
45501
+ <h1 class="editor-heading" data-testid="editor-heading">{{ heading() }}</h1>
45502
+ }
45503
+ <div class="editor-actions-buttons">
45504
45504
  @if (canWrite() && testSendEnabled()) {
45505
45505
  <ui-button variant="secondary" size="sm" (click)="openTestSendDialog()">
45506
45506
  <svg width="14" height="14" viewBox="0 0 24 24" fill="none" stroke="currentColor" stroke-width="2" aria-hidden="true"><line x1="22" y1="2" x2="11" y2="13"/><polygon points="22 2 15 22 11 13 2 9 22 2"/></svg>
@@ -45511,6 +45511,7 @@ i0.ɵɵngDeclareClassMetadata({
45511
45511
  <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
45512
  Save Template
45513
45513
  </ui-button>
45514
+ </div>
45514
45515
  </div>
45515
45516
  <ui-divider />
45516
45517
 
@@ -45566,20 +45567,17 @@ i0.ɵɵngDeclareClassMetadata({
45566
45567
  }
45567
45568
  <div class="assignment-list" [hidden]="filteredAssignments().length === 0">
45568
45569
  @for (item of filteredAssignments(); track item.key) {
45569
- <div class="assignment-item" [class.assignment-readonly]="!canWrite()" [attr.role]="canWrite() ? 'button' : null" [attr.tabindex]="canWrite() ? 0 : null"
45570
- [attr.aria-label]="canWrite() ? 'Configure ' + item.name : null"
45571
- (click)="openAssignmentConfig(item)" (keydown.enter)="openAssignmentConfig(item); $event.preventDefault()" (keydown.space)="openAssignmentConfig(item); $event.preventDefault()">
45570
+ <div class="assignment-item" [class.assignment-readonly]="!canWrite()" [attr.role]="canWrite() ? 'switch' : null" [attr.tabindex]="canWrite() ? 0 : null"
45571
+ [attr.aria-checked]="canWrite() ? item.assigned : null" [attr.aria-label]="canWrite() ? item.name : null"
45572
+ (click)="toggleAssignment(item)" (keydown.enter)="toggleAssignment(item); $event.preventDefault()" (keydown.space)="toggleAssignment(item); $event.preventDefault()">
45572
45573
  <div class="assignment-text">
45573
45574
  <strong>{{ item.name }}</strong>
45574
45575
  <span>{{ item.description }}</span>
45575
45576
  </div>
45576
45577
  <div class="assignment-channels">
45577
- <span class="channel-badge" [class.active]="item.email" role="img" [attr.aria-label]="'Email ' + (item.email ? 'on' : 'off')">
45578
+ <span class="channel-badge" [class.active]="item.assigned" role="img" [attr.aria-label]="'Email ' + (item.assigned ? 'on' : 'off')">
45578
45579
  <svg width="10" height="10" viewBox="0 0 24 24" fill="none" stroke="currentColor" stroke-width="2" aria-hidden="true"><rect x="2" y="4" width="20" height="16" rx="2"/><path d="m22 7-8.97 5.7a1.94 1.94 0 0 1-2.06 0L2 7"/></svg>
45579
45580
  </span>
45580
- <span class="channel-badge" [class.active]="item.text" [class.disabled]="!textEnabled()" role="img" [attr.aria-label]="'Text ' + (item.text ? 'on' : 'off')">
45581
- <svg width="10" height="10" viewBox="0 0 24 24" fill="none" stroke="currentColor" stroke-width="2" aria-hidden="true"><path d="M21 15a2 2 0 0 1-2 2H7l-4 4V5a2 2 0 0 1 2-2h14a2 2 0 0 1 2 2z"/></svg>
45582
- </span>
45583
45581
  </div>
45584
45582
  </div>
45585
45583
  }
@@ -45954,30 +45952,8 @@ i0.ɵɵngDeclareClassMetadata({
45954
45952
  </ui-side-panel>
45955
45953
 
45956
45954
 
45957
- <!-- Assignment config -->
45958
- <ui-side-panel [wide]="true" [open]="showAssignmentConfig()" [title]="configTarget()?.name || 'Configure Automation'" primaryLabel="Save Configuration"
45959
- [primaryDisabled]="!configEmail() && !configText()" (closed)="showAssignmentConfig.set(false)" (primaryClick)="saveAssignmentConfig()">
45960
- @if (configTarget(); as target) {
45961
- <p class="config-desc">{{ target.description }}</p>
45962
- <hr class="config-divider" />
45963
- <div class="config-section">
45964
- <span class="config-section-label">EMAIL TEMPLATE</span>
45965
- <div class="config-field">
45966
- <span class="config-label">Assigned Template</span>
45967
- <div class="config-readonly">{{ name() || 'Current template' }}</div>
45968
- <span class="config-hint">This template will be used when this automation is triggered.</span>
45969
- </div>
45970
- </div>
45971
- <hr class="config-divider" />
45972
- <div class="config-section">
45973
- <span class="config-section-label">CHANNELS <span class="required" aria-hidden="true">*</span></span>
45974
- <ui-checkbox label="Email" [(checked)]="configEmail" />
45975
- <ui-checkbox label="Text (SMS)" [(checked)]="configText" [disabled]="!textEnabled()" [hint]="textEnabled() ? '' : '(not enabled)'" />
45976
- </div>
45977
- }
45978
- </ui-side-panel>
45979
45955
  `,
45980
- 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:flex-end;align-items:center;gap:8px;flex-wrap:wrap;padding:0 0 12px;flex-shrink:0}.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"]
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"]
45981
45957
  }]
45982
45958
  }],
45983
45959
  ctorParameters: () => [],
@@ -46030,27 +46006,27 @@ i0.ɵɵngDeclareClassMetadata({
46030
46006
  required: false
46031
46007
  }]
46032
46008
  }],
46033
- textEnabled: [{
46009
+ variableGroups: [{
46034
46010
  type: i0.Input,
46035
46011
  args: [{
46036
46012
  isSignal: true,
46037
- alias: "textEnabled",
46013
+ alias: "variableGroups",
46038
46014
  required: false
46039
46015
  }]
46040
46016
  }],
46041
- variableGroups: [{
46017
+ blockGroups: [{
46042
46018
  type: i0.Input,
46043
46019
  args: [{
46044
46020
  isSignal: true,
46045
- alias: "variableGroups",
46021
+ alias: "blockGroups",
46046
46022
  required: false
46047
46023
  }]
46048
46024
  }],
46049
- blockGroups: [{
46025
+ heading: [{
46050
46026
  type: i0.Input,
46051
46027
  args: [{
46052
46028
  isSignal: true,
46053
- alias: "blockGroups",
46029
+ alias: "heading",
46054
46030
  required: false
46055
46031
  }]
46056
46032
  }],