@forgeroute/ui 0.4.75 → 0.4.77

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.
@@ -4705,7 +4705,11 @@ const EXTRA_ICONS = {
4705
4705
  "cup": "M18 8h1a4 4 0 0 1 0 8h-1 M2 8h16v9a4 4 0 0 1-4 4H6a4 4 0 0 1-4-4V8z M6 1v3 M10 1v3 M14 1v3",
4706
4706
  "cash": "M3 6h18a1 1 0 0 1 1 1v10a1 1 0 0 1-1 1H3a1 1 0 0 1-1-1V7a1 1 0 0 1 1-1z M12 9a3 3 0 1 0 0 6 3 3 0 0 0 0-6z M6 12h.01 M18 12h.01",
4707
4707
  "dollar": "M12 1v22 M17 5H9.5a3.5 3.5 0 0 0 0 7h5a3.5 3.5 0 0 1 0 7H6",
4708
- "wrench": "M14.7 6.3a1 1 0 0 0 0 1.4l1.6 1.6a1 1 0 0 0 1.4 0l3.77-3.77a6 6 0 0 1-7.94 7.94l-6.91 6.91a2.12 2.12 0 0 1-3-3l6.91-6.91a6 6 0 0 1 7.94-7.94l-3.76 3.76z"
4708
+ "wrench": "M14.7 6.3a1 1 0 0 0 0 1.4l1.6 1.6a1 1 0 0 0 1.4 0l3.77-3.77a6 6 0 0 1-7.94 7.94l-6.91 6.91a2.12 2.12 0 0 1-3-3l6.91-6.91a6 6 0 0 1 7.94-7.94l-3.76 3.76z",
4709
+ "star": "M12 2l3.09 6.26L22 9.27l-5 4.87 1.18 6.88L12 17.77l-6.18 3.25L7 14.14 2 9.27l6.91-1.01L12 2z",
4710
+ "gift": "M20 12v10H4V12 M2 7h20v5H2z M12 22V7 M12 7H7.5a2.5 2.5 0 0 1 0-5C11 2 12 7 12 7z M12 7h4.5a2.5 2.5 0 0 0 0-5C13 2 12 7 12 7z",
4711
+ "award": "M12 1a7 7 0 1 0 0 14 7 7 0 0 0 0-14z M8.21 13.89L7 23l5-3 5 3-1.21-9.12",
4712
+ "calendar-check": "M19 4H5a2 2 0 0 0-2 2v14a2 2 0 0 0 2 2h14a2 2 0 0 0 2-2V6a2 2 0 0 0-2-2z M16 2v4 M8 2v4 M3 10h18 M9 16l2 2 4-4"
4709
4713
  };
4710
4714
  const ICON_NAMES = Object.freeze(Object.keys(EXTRA_ICONS));
4711
4715
  function iconPath(name) {
@@ -5132,6 +5136,52 @@ var TextInputComponent = class TextInputComponent {
5132
5136
  focus(options) {
5133
5137
  this._fieldEl()?.nativeElement.focus(options);
5134
5138
  }
5139
+ getSelection() {
5140
+ const el = this._fieldEl()?.nativeElement;
5141
+ if (!el) return null;
5142
+ try {
5143
+ if (el.selectionStart === null || el.selectionEnd === null) return null;
5144
+ return {
5145
+ start: el.selectionStart,
5146
+ end: el.selectionEnd
5147
+ };
5148
+ } catch {
5149
+ return null;
5150
+ }
5151
+ }
5152
+ setSelection(start, end = start) {
5153
+ const el = this._fieldEl()?.nativeElement;
5154
+ if (!el) return;
5155
+ const max = el.value.length;
5156
+ const from = Math.min(Math.max(0, start), max);
5157
+ const to = Math.min(Math.max(from, end), max);
5158
+ try {
5159
+ el.setSelectionRange(from, to);
5160
+ } catch {}
5161
+ }
5162
+ insertAtCaret(text) {
5163
+ const el = this._fieldEl()?.nativeElement;
5164
+ if (!el || el.disabled || el.readOnly || !text) return;
5165
+ const value = el.value;
5166
+ let from = value.length;
5167
+ let to = value.length;
5168
+ try {
5169
+ if (el.selectionStart !== null && el.selectionEnd !== null) {
5170
+ from = el.selectionStart;
5171
+ to = el.selectionEnd;
5172
+ }
5173
+ } catch {}
5174
+ const max = this.maxlength();
5175
+ const room = max === void 0 ? text.length : max - (value.length - (to - from));
5176
+ const insert = text.slice(0, Math.max(0, room));
5177
+ if (!insert) return;
5178
+ el.value = value.slice(0, from) + insert + value.slice(to);
5179
+ const caret = from + insert.length;
5180
+ try {
5181
+ el.setSelectionRange(caret, caret);
5182
+ } catch {}
5183
+ el.dispatchEvent(new Event("input", { bubbles: true }));
5184
+ }
5135
5185
  constructor() {
5136
5186
  this.label = input("", ...ngDevMode ? [{ debugName: "label" }] : /* istanbul ignore next */ []);
5137
5187
  this.ariaLabel = input("", ...ngDevMode ? [{ debugName: "ariaLabel" }] : /* istanbul ignore next */ []);
@@ -7341,7 +7391,7 @@ i0.ɵɵngDeclareClassMetadata({
7341
7391
  }]
7342
7392
  }
7343
7393
  });
7344
- const MIN_VISIBLE_PERCENT = 2;
7394
+ const MIN_VISIBLE_PERCENT$1 = 2;
7345
7395
  var ProgressBarComponent = class ProgressBarComponent {
7346
7396
  constructor() {
7347
7397
  this.value = input(0, ...ngDevMode ? [{ debugName: "value" }] : /* istanbul ignore next */ []);
@@ -7363,7 +7413,7 @@ var ProgressBarComponent = class ProgressBarComponent {
7363
7413
  }, ...ngDevMode ? [{ debugName: "clampedValue" }] : /* istanbul ignore next */ []);
7364
7414
  this.percent = computed(() => {
7365
7415
  if (this.safeMax() <= 0 || this.clampedValue() <= 0) return 0;
7366
- return Math.max(Math.round(this.clampedValue() / this.safeMax() * 100), MIN_VISIBLE_PERCENT);
7416
+ return Math.max(Math.round(this.clampedValue() / this.safeMax() * 100), MIN_VISIBLE_PERCENT$1);
7367
7417
  }, ...ngDevMode ? [{ debugName: "percent" }] : /* istanbul ignore next */ []);
7368
7418
  this.effectiveVariant = computed(() => {
7369
7419
  const fixed = this.variant();
@@ -8113,12 +8163,15 @@ var ToastService = class ToastService {
8113
8163
  info(msg, durationOrOptions = 3e3) {
8114
8164
  this._enter("info", msg, 3e3, durationOrOptions);
8115
8165
  }
8166
+ warning(msg, durationOrOptions = 4e3) {
8167
+ this._enter("warning", msg, 4e3, durationOrOptions);
8168
+ }
8116
8169
  error(msg, durationOrOptions = 4e3) {
8117
8170
  this._enter("error", msg, 4e3, durationOrOptions);
8118
8171
  }
8119
8172
  notify(msg, options = {}) {
8120
8173
  const type = options.type ?? "success";
8121
- this._enter(type, msg, type === "error" ? 4e3 : 3e3, options);
8174
+ this._enter(type, msg, type === "error" || type === "warning" ? 4e3 : 3e3, options);
8122
8175
  }
8123
8176
  dismiss() {
8124
8177
  this._finish();
@@ -8494,6 +8547,7 @@ var ToastComponent = class ToastComponent {
8494
8547
  [class.t-rich]="isRich()"
8495
8548
  [class.t-error]="toast.type() === 'error'"
8496
8549
  [class.t-info]="toast.type() === 'info'"
8550
+ [class.t-warning]="toast.type() === 'warning'"
8497
8551
  [class.t-adopted]="adopted()"
8498
8552
  [attr.role]="adopted() || persistent() ? null : (toast.type() === 'error' ? 'alert' : 'status')"
8499
8553
  [attr.aria-live]="adopted() || persistent() ? null : (toast.type() === 'error' ? 'assertive' : 'polite')"
@@ -8504,6 +8558,10 @@ var ToastComponent = class ToastComponent {
8504
8558
  <svg width="16" height="16" viewBox="0 0 24 24" fill="none" stroke="currentColor" stroke-width="2" aria-hidden="true">
8505
8559
  <circle cx="12" cy="12" r="10"/><line x1="15" y1="9" x2="9" y2="15"/><line x1="9" y1="9" x2="15" y2="15"/>
8506
8560
  </svg>
8561
+ } @else if (toast.type() === 'warning') {
8562
+ <svg width="16" height="16" viewBox="0 0 24 24" fill="none" stroke="currentColor" stroke-width="2" aria-hidden="true">
8563
+ <path d="M10.29 3.86L1.82 18a2 2 0 0 0 1.71 3h16.94a2 2 0 0 0 1.71-3L13.71 3.86a2 2 0 0 0-3.42 0z"/><line x1="12" y1="9" x2="12" y2="13"/><line x1="12" y1="17" x2="12.01" y2="17"/>
8564
+ </svg>
8507
8565
  } @else if (toast.type() === 'info') {
8508
8566
  <svg width="16" height="16" viewBox="0 0 24 24" fill="none" stroke="currentColor" stroke-width="2" aria-hidden="true">
8509
8567
  <circle cx="12" cy="12" r="10"/><line x1="12" y1="16" x2="12" y2="12"/><line x1="12" y1="8" x2="12.01" y2="8"/>
@@ -8553,7 +8611,7 @@ var ToastComponent = class ToastComponent {
8553
8611
  </ng-template>
8554
8612
  `,
8555
8613
  isInline: true,
8556
- styles: [".t-live{position:absolute;width:0;height:0;margin:0;padding:0;overflow:visible}.t-toast{position:fixed;bottom:max(24px,env(safe-area-inset-bottom,0px));left:50%;transform:translate(-50%);background:#047857;color:#fff;padding:11px 20px;border-radius:12px;font-size:.875rem;font-weight:500;z-index:9999;box-shadow:0 4px 16px #0000002e;animation:t-in .28s cubic-bezier(.16,1,.3,1);display:flex;align-items:center;gap:8px;max-width:calc(100vw - 32px - env(safe-area-inset-left,0px) - env(safe-area-inset-right,0px));overflow-wrap:anywhere;word-break:break-word}.t-error{background:#dc2626}.t-info{background:#2563eb}.t-adopted{animation:none}.t-text{min-width:0}.t-close{position:relative;flex:none;display:inline-flex;align-items:center;justify-content:center;width:28px;height:28px;margin:-4px -10px -4px 0;padding:0;border:0;border-radius:50%;background:transparent;color:inherit;cursor:pointer}.t-close:after{content:\"\";position:absolute;inset:-8px}.t-close:hover{background:#fff3}.t-close:focus-visible{outline:2px solid #fff;outline-offset:1px}.t-rich{display:grid;grid-template-columns:auto minmax(0,1fr) auto;align-items:start;column-gap:8px;row-gap:10px;min-width:min(320px,calc(100vw - 32px))}.t-rich>svg:first-child{margin-top:2px}.t-content{display:flex;flex-direction:column;gap:2px;min-width:0}.t-title{font-weight:700}.t-queue{grid-column:1 / -1;justify-self:end;font-size:.75rem;font-weight:600;padding:1px 8px;border-radius:999px;background:#ffffff38}.t-actions{grid-column:1 / -1;display:flex;flex-wrap:wrap;gap:8px}.t-action{min-height:32px;padding:6px 14px;border-radius:8px;font:inherit;font-size:.8125rem;font-weight:600;cursor:pointer;color:#fff;background:#ffffff2e;border:1px solid rgba(255,255,255,.6)}.t-action:hover:not(:disabled){background:#ffffff4d}.t-action:focus-visible{outline:2px solid #fff;outline-offset:2px}.t-action:disabled{opacity:.5;cursor:not-allowed}.t-action-primary{background:#fff;color:#0f172a;border-color:#fff}.t-action-primary:hover:not(:disabled){background:#f1f5f9}.t-action-danger{background:#7f1d1d;border-color:#ffffffb3}.t-action-danger:hover:not(:disabled){background:#991b1b}.t-countdown{grid-column:1 / -1;display:flex;flex-direction:column;gap:4px}.t-countdown-bar{height:4px;border-radius:2px;background:#ffffff47;overflow:hidden}.t-countdown-fill{height:100%;background:#fff;transition:width .2s linear}.t-countdown-label{font-size:.75rem;opacity:.85;font-variant-numeric:tabular-nums}@media(prefers-reduced-motion:reduce){.t-countdown-fill{transition:none}}@media(pointer:coarse),(max-width:480px){.t-action{min-height:44px}}@keyframes t-in{0%{opacity:0;transform:translate(-50%) translateY(10px)}to{opacity:1;transform:translate(-50%) translateY(0)}}@media(prefers-reduced-motion:reduce){.t-toast{animation:none}}@media(max-width:480px){.t-toast{bottom:max(16px,env(safe-area-inset-bottom,16px));font-size:.8125rem;padding:10px 16px}}\n"],
8614
+ styles: [".t-live{position:absolute;width:0;height:0;margin:0;padding:0;overflow:visible}.t-toast{position:fixed;bottom:max(24px,env(safe-area-inset-bottom,0px));left:50%;transform:translate(-50%);background:#047857;color:#fff;padding:11px 20px;border-radius:12px;font-size:.875rem;font-weight:500;z-index:9999;box-shadow:0 4px 16px #0000002e;animation:t-in .28s cubic-bezier(.16,1,.3,1);display:flex;align-items:center;gap:8px;max-width:calc(100vw - 32px - env(safe-area-inset-left,0px) - env(safe-area-inset-right,0px));overflow-wrap:anywhere;word-break:break-word}.t-error{background:#dc2626}.t-info{background:#2563eb}.t-warning{background:#b45309}.t-adopted{animation:none}.t-text{min-width:0}.t-close{position:relative;flex:none;display:inline-flex;align-items:center;justify-content:center;width:28px;height:28px;margin:-4px -10px -4px 0;padding:0;border:0;border-radius:50%;background:transparent;color:inherit;cursor:pointer}.t-close:after{content:\"\";position:absolute;inset:-8px}.t-close:hover{background:#fff3}.t-close:focus-visible{outline:2px solid #fff;outline-offset:1px}.t-rich{display:grid;grid-template-columns:auto minmax(0,1fr) auto;align-items:start;column-gap:8px;row-gap:10px;min-width:min(320px,calc(100vw - 32px))}.t-rich>svg:first-child{margin-top:2px}.t-content{display:flex;flex-direction:column;gap:2px;min-width:0}.t-title{font-weight:700}.t-queue{grid-column:1 / -1;justify-self:end;font-size:.75rem;font-weight:600;padding:1px 8px;border-radius:999px;background:#ffffff38}.t-actions{grid-column:1 / -1;display:flex;flex-wrap:wrap;gap:8px}.t-action{min-height:32px;padding:6px 14px;border-radius:8px;font:inherit;font-size:.8125rem;font-weight:600;cursor:pointer;color:#fff;background:#ffffff2e;border:1px solid rgba(255,255,255,.6)}.t-action:hover:not(:disabled){background:#ffffff4d}.t-action:focus-visible{outline:2px solid #fff;outline-offset:2px}.t-action:disabled{opacity:.5;cursor:not-allowed}.t-action-primary{background:#fff;color:#0f172a;border-color:#fff}.t-action-primary:hover:not(:disabled){background:#f1f5f9}.t-action-danger{background:#7f1d1d;border-color:#ffffffb3}.t-action-danger:hover:not(:disabled){background:#991b1b}.t-countdown{grid-column:1 / -1;display:flex;flex-direction:column;gap:4px}.t-countdown-bar{height:4px;border-radius:2px;background:#ffffff47;overflow:hidden}.t-countdown-fill{height:100%;background:#fff;transition:width .2s linear}.t-countdown-label{font-size:.75rem;opacity:.85;font-variant-numeric:tabular-nums}@media(prefers-reduced-motion:reduce){.t-countdown-fill{transition:none}}@media(pointer:coarse),(max-width:480px){.t-action{min-height:44px}}@keyframes t-in{0%{opacity:0;transform:translate(-50%) translateY(10px)}to{opacity:1;transform:translate(-50%) translateY(0)}}@media(prefers-reduced-motion:reduce){.t-toast{animation:none}}@media(max-width:480px){.t-toast{bottom:max(16px,env(safe-area-inset-bottom,16px));font-size:.8125rem;padding:10px 16px}}\n"],
8557
8615
  dependencies: [{
8558
8616
  kind: "directive",
8559
8617
  type: NgTemplateOutlet,
@@ -8600,6 +8658,7 @@ i0.ɵɵngDeclareClassMetadata({
8600
8658
  [class.t-rich]="isRich()"
8601
8659
  [class.t-error]="toast.type() === 'error'"
8602
8660
  [class.t-info]="toast.type() === 'info'"
8661
+ [class.t-warning]="toast.type() === 'warning'"
8603
8662
  [class.t-adopted]="adopted()"
8604
8663
  [attr.role]="adopted() || persistent() ? null : (toast.type() === 'error' ? 'alert' : 'status')"
8605
8664
  [attr.aria-live]="adopted() || persistent() ? null : (toast.type() === 'error' ? 'assertive' : 'polite')"
@@ -8610,6 +8669,10 @@ i0.ɵɵngDeclareClassMetadata({
8610
8669
  <svg width="16" height="16" viewBox="0 0 24 24" fill="none" stroke="currentColor" stroke-width="2" aria-hidden="true">
8611
8670
  <circle cx="12" cy="12" r="10"/><line x1="15" y1="9" x2="9" y2="15"/><line x1="9" y1="9" x2="15" y2="15"/>
8612
8671
  </svg>
8672
+ } @else if (toast.type() === 'warning') {
8673
+ <svg width="16" height="16" viewBox="0 0 24 24" fill="none" stroke="currentColor" stroke-width="2" aria-hidden="true">
8674
+ <path d="M10.29 3.86L1.82 18a2 2 0 0 0 1.71 3h16.94a2 2 0 0 0 1.71-3L13.71 3.86a2 2 0 0 0-3.42 0z"/><line x1="12" y1="9" x2="12" y2="13"/><line x1="12" y1="17" x2="12.01" y2="17"/>
8675
+ </svg>
8613
8676
  } @else if (toast.type() === 'info') {
8614
8677
  <svg width="16" height="16" viewBox="0 0 24 24" fill="none" stroke="currentColor" stroke-width="2" aria-hidden="true">
8615
8678
  <circle cx="12" cy="12" r="10"/><line x1="12" y1="16" x2="12" y2="12"/><line x1="12" y1="8" x2="12.01" y2="8"/>
@@ -8658,7 +8721,7 @@ i0.ɵɵngDeclareClassMetadata({
8658
8721
  }
8659
8722
  </ng-template>
8660
8723
  `,
8661
- styles: [".t-live{position:absolute;width:0;height:0;margin:0;padding:0;overflow:visible}.t-toast{position:fixed;bottom:max(24px,env(safe-area-inset-bottom,0px));left:50%;transform:translate(-50%);background:#047857;color:#fff;padding:11px 20px;border-radius:12px;font-size:.875rem;font-weight:500;z-index:9999;box-shadow:0 4px 16px #0000002e;animation:t-in .28s cubic-bezier(.16,1,.3,1);display:flex;align-items:center;gap:8px;max-width:calc(100vw - 32px - env(safe-area-inset-left,0px) - env(safe-area-inset-right,0px));overflow-wrap:anywhere;word-break:break-word}.t-error{background:#dc2626}.t-info{background:#2563eb}.t-adopted{animation:none}.t-text{min-width:0}.t-close{position:relative;flex:none;display:inline-flex;align-items:center;justify-content:center;width:28px;height:28px;margin:-4px -10px -4px 0;padding:0;border:0;border-radius:50%;background:transparent;color:inherit;cursor:pointer}.t-close:after{content:\"\";position:absolute;inset:-8px}.t-close:hover{background:#fff3}.t-close:focus-visible{outline:2px solid #fff;outline-offset:1px}.t-rich{display:grid;grid-template-columns:auto minmax(0,1fr) auto;align-items:start;column-gap:8px;row-gap:10px;min-width:min(320px,calc(100vw - 32px))}.t-rich>svg:first-child{margin-top:2px}.t-content{display:flex;flex-direction:column;gap:2px;min-width:0}.t-title{font-weight:700}.t-queue{grid-column:1 / -1;justify-self:end;font-size:.75rem;font-weight:600;padding:1px 8px;border-radius:999px;background:#ffffff38}.t-actions{grid-column:1 / -1;display:flex;flex-wrap:wrap;gap:8px}.t-action{min-height:32px;padding:6px 14px;border-radius:8px;font:inherit;font-size:.8125rem;font-weight:600;cursor:pointer;color:#fff;background:#ffffff2e;border:1px solid rgba(255,255,255,.6)}.t-action:hover:not(:disabled){background:#ffffff4d}.t-action:focus-visible{outline:2px solid #fff;outline-offset:2px}.t-action:disabled{opacity:.5;cursor:not-allowed}.t-action-primary{background:#fff;color:#0f172a;border-color:#fff}.t-action-primary:hover:not(:disabled){background:#f1f5f9}.t-action-danger{background:#7f1d1d;border-color:#ffffffb3}.t-action-danger:hover:not(:disabled){background:#991b1b}.t-countdown{grid-column:1 / -1;display:flex;flex-direction:column;gap:4px}.t-countdown-bar{height:4px;border-radius:2px;background:#ffffff47;overflow:hidden}.t-countdown-fill{height:100%;background:#fff;transition:width .2s linear}.t-countdown-label{font-size:.75rem;opacity:.85;font-variant-numeric:tabular-nums}@media(prefers-reduced-motion:reduce){.t-countdown-fill{transition:none}}@media(pointer:coarse),(max-width:480px){.t-action{min-height:44px}}@keyframes t-in{0%{opacity:0;transform:translate(-50%) translateY(10px)}to{opacity:1;transform:translate(-50%) translateY(0)}}@media(prefers-reduced-motion:reduce){.t-toast{animation:none}}@media(max-width:480px){.t-toast{bottom:max(16px,env(safe-area-inset-bottom,16px));font-size:.8125rem;padding:10px 16px}}\n"]
8724
+ styles: [".t-live{position:absolute;width:0;height:0;margin:0;padding:0;overflow:visible}.t-toast{position:fixed;bottom:max(24px,env(safe-area-inset-bottom,0px));left:50%;transform:translate(-50%);background:#047857;color:#fff;padding:11px 20px;border-radius:12px;font-size:.875rem;font-weight:500;z-index:9999;box-shadow:0 4px 16px #0000002e;animation:t-in .28s cubic-bezier(.16,1,.3,1);display:flex;align-items:center;gap:8px;max-width:calc(100vw - 32px - env(safe-area-inset-left,0px) - env(safe-area-inset-right,0px));overflow-wrap:anywhere;word-break:break-word}.t-error{background:#dc2626}.t-info{background:#2563eb}.t-warning{background:#b45309}.t-adopted{animation:none}.t-text{min-width:0}.t-close{position:relative;flex:none;display:inline-flex;align-items:center;justify-content:center;width:28px;height:28px;margin:-4px -10px -4px 0;padding:0;border:0;border-radius:50%;background:transparent;color:inherit;cursor:pointer}.t-close:after{content:\"\";position:absolute;inset:-8px}.t-close:hover{background:#fff3}.t-close:focus-visible{outline:2px solid #fff;outline-offset:1px}.t-rich{display:grid;grid-template-columns:auto minmax(0,1fr) auto;align-items:start;column-gap:8px;row-gap:10px;min-width:min(320px,calc(100vw - 32px))}.t-rich>svg:first-child{margin-top:2px}.t-content{display:flex;flex-direction:column;gap:2px;min-width:0}.t-title{font-weight:700}.t-queue{grid-column:1 / -1;justify-self:end;font-size:.75rem;font-weight:600;padding:1px 8px;border-radius:999px;background:#ffffff38}.t-actions{grid-column:1 / -1;display:flex;flex-wrap:wrap;gap:8px}.t-action{min-height:32px;padding:6px 14px;border-radius:8px;font:inherit;font-size:.8125rem;font-weight:600;cursor:pointer;color:#fff;background:#ffffff2e;border:1px solid rgba(255,255,255,.6)}.t-action:hover:not(:disabled){background:#ffffff4d}.t-action:focus-visible{outline:2px solid #fff;outline-offset:2px}.t-action:disabled{opacity:.5;cursor:not-allowed}.t-action-primary{background:#fff;color:#0f172a;border-color:#fff}.t-action-primary:hover:not(:disabled){background:#f1f5f9}.t-action-danger{background:#7f1d1d;border-color:#ffffffb3}.t-action-danger:hover:not(:disabled){background:#991b1b}.t-countdown{grid-column:1 / -1;display:flex;flex-direction:column;gap:4px}.t-countdown-bar{height:4px;border-radius:2px;background:#ffffff47;overflow:hidden}.t-countdown-fill{height:100%;background:#fff;transition:width .2s linear}.t-countdown-label{font-size:.75rem;opacity:.85;font-variant-numeric:tabular-nums}@media(prefers-reduced-motion:reduce){.t-countdown-fill{transition:none}}@media(pointer:coarse),(max-width:480px){.t-action{min-height:44px}}@keyframes t-in{0%{opacity:0;transform:translate(-50%) translateY(10px)}to{opacity:1;transform:translate(-50%) translateY(0)}}@media(prefers-reduced-motion:reduce){.t-toast{animation:none}}@media(max-width:480px){.t-toast{bottom:max(16px,env(safe-area-inset-bottom,16px));font-size:.8125rem;padding:10px 16px}}\n"]
8662
8725
  }]
8663
8726
  }],
8664
8727
  ctorParameters: () => [],
@@ -12032,6 +12095,23 @@ var DataTableComponent = class DataTableComponent {
12032
12095
  });
12033
12096
  return true;
12034
12097
  }
12098
+ _totalsParams() {
12099
+ const { sort: _s, direction: _d, ...rest } = this._exportParams();
12100
+ return rest;
12101
+ }
12102
+ _fetchTotals(keepShown = false) {
12103
+ this._totalsSub?.unsubscribe();
12104
+ const ep = this.totalsEndpoint();
12105
+ if (!ep) {
12106
+ this._totals.set(null);
12107
+ return;
12108
+ }
12109
+ if (!keepShown) this._totals.set(null);
12110
+ this._totalsSub = this.http.get(`${this.config.baseUrl}${ep}`, { params: tableQueryParams(this._totalsParams()) }).pipe(takeUntilDestroyed(this.destroyRef)).subscribe({
12111
+ next: (totals) => this._totals.set(totals && typeof totals === "object" ? totals : null),
12112
+ error: () => this._totals.set(null)
12113
+ });
12114
+ }
12035
12115
  _actionKeyLabel(key) {
12036
12116
  const words = key.replace(/([a-z0-9])([A-Z])/g, "$1 $2").split(/[\s_-]+/).filter(Boolean).join(" ").toLowerCase();
12037
12117
  return words.charAt(0).toUpperCase() + words.slice(1);
@@ -12094,6 +12174,9 @@ var DataTableComponent = class DataTableComponent {
12094
12174
  this._selectedIds.set(current);
12095
12175
  this.selectionChange.emit(new Set(current));
12096
12176
  }
12177
+ currentQuery() {
12178
+ return { ...this._exportParams() };
12179
+ }
12097
12180
  clearSelection() {
12098
12181
  this._selectedIds.set(/* @__PURE__ */ new Set());
12099
12182
  this._activeBulkType.set(null);
@@ -12549,6 +12632,8 @@ var DataTableComponent = class DataTableComponent {
12549
12632
  this.tableTitle = input("", ...ngDevMode ? [{ debugName: "tableTitle" }] : /* istanbul ignore next */ []);
12550
12633
  this._showHeader = computed(() => !!this.tableTitle() || this.showSearch() || this.showToolbar() || this._effectiveTabs().length > 0, ...ngDevMode ? [{ debugName: "_showHeader" }] : /* istanbul ignore next */ []);
12551
12634
  this.countsEndpoint = input("", ...ngDevMode ? [{ debugName: "countsEndpoint" }] : /* istanbul ignore next */ []);
12635
+ this.totalsEndpoint = input("", ...ngDevMode ? [{ debugName: "totalsEndpoint" }] : /* istanbul ignore next */ []);
12636
+ this.totalsLabel = input("Total", ...ngDevMode ? [{ debugName: "totalsLabel" }] : /* istanbul ignore next */ []);
12552
12637
  this.params = input(null, ...ngDevMode ? [{ debugName: "params" }] : /* istanbul ignore next */ []);
12553
12638
  this.tableButtons = input([], ...ngDevMode ? [{ debugName: "tableButtons" }] : /* istanbul ignore next */ []);
12554
12639
  this.filterCountsEndpoint = input("", ...ngDevMode ? [{ debugName: "filterCountsEndpoint" }] : /* istanbul ignore next */ []);
@@ -12700,6 +12785,28 @@ var DataTableComponent = class DataTableComponent {
12700
12785
  equal: (a, b) => JSON.stringify(a) === JSON.stringify(b)
12701
12786
  });
12702
12787
  this._searchFields = computed(() => this.visibleCols().filter((c) => c.searchable).map((c) => c.key).join(","), ...ngDevMode ? [{ debugName: "_searchFields" }] : /* istanbul ignore next */ []);
12788
+ this._totals = signal(null, ...ngDevMode ? [{ debugName: "_totals" }] : /* istanbul ignore next */ []);
12789
+ this._totalsSkipNext = false;
12790
+ this._footerVisible = computed(() => !!this.totalsEndpoint() && this._totals() !== null && this._hasLoaded() && !this._loading() && !this._error() && this._items().length > 0, ...ngDevMode ? [{ debugName: "_footerVisible" }] : /* istanbul ignore next */ []);
12791
+ this._footerCells = computed(() => {
12792
+ const totals = this._totals();
12793
+ const out = {};
12794
+ if (!totals) return out;
12795
+ for (const col of this.visibleCols()) {
12796
+ if (col.cellType === "actions" || !col.footerFn) continue;
12797
+ const v = col.footerFn(totals);
12798
+ if (v != null && v !== "") out[col.key] = String(v);
12799
+ }
12800
+ return out;
12801
+ }, ...ngDevMode ? [{ debugName: "_footerCells" }] : /* istanbul ignore next */ []);
12802
+ this._footerPhoneLines = computed(() => {
12803
+ const cells = this._footerCells();
12804
+ return this.visibleCols().filter((c) => cells[c.key] !== void 0).map((c) => ({
12805
+ key: c.key,
12806
+ label: c.label,
12807
+ value: cells[c.key]
12808
+ }));
12809
+ }, ...ngDevMode ? [{ debugName: "_footerPhoneLines" }] : /* istanbul ignore next */ []);
12703
12810
  this._exportParams = computed(() => {
12704
12811
  const params = { ...this._extraParams() };
12705
12812
  if (this._search()) {
@@ -12907,11 +13014,14 @@ var DataTableComponent = class DataTableComponent {
12907
13014
  untracked(() => this.resetToFirstPage());
12908
13015
  });
12909
13016
  this.triggerLoad$.pipe(switchMap(() => {
12910
- if (!this._silentNext) this._loading.set(true);
13017
+ const silentLoad = this._silentNext;
13018
+ if (!silentLoad) this._loading.set(true);
12911
13019
  this._silentNext = false;
12912
13020
  this._searchLoading.set(this._searchPending);
12913
13021
  this._searchPending = false;
12914
13022
  this._error.set(null);
13023
+ if (this._totalsSkipNext) this._totalsSkipNext = false;
13024
+ else this._fetchTotals(silentLoad);
12915
13025
  let params = tableQueryParams(this._extraParams()).set("page", this._page() - 1).set("size", this.pageSize());
12916
13026
  if (this._search()) {
12917
13027
  params = params.set("search", this._searchParam());
@@ -13032,10 +13142,12 @@ var DataTableComponent = class DataTableComponent {
13032
13142
  this._sortDir.set("asc");
13033
13143
  }
13034
13144
  this._page.set(1);
13145
+ this._totalsSkipNext = true;
13035
13146
  this.load();
13036
13147
  }
13037
13148
  onPageChange(p) {
13038
13149
  this._page.set(p);
13150
+ this._totalsSkipNext = true;
13039
13151
  this.load();
13040
13152
  }
13041
13153
  onTabChange(value) {
@@ -13216,7 +13328,7 @@ var DataTableComponent = class DataTableComponent {
13216
13328
  e.preventDefault();
13217
13329
  this.rowClick.emit(item);
13218
13330
  }
13219
- onInternalButtonClick(type) {
13331
+ async onInternalButtonClick(type) {
13220
13332
  if (type === "import") {
13221
13333
  this._ieRef()?.openImport();
13222
13334
  return;
@@ -13225,6 +13337,18 @@ var DataTableComponent = class DataTableComponent {
13225
13337
  this._ieRef()?.exportAll();
13226
13338
  return;
13227
13339
  }
13340
+ const confirm = this._effectiveButtons().find((b) => b.type === type)?.confirm;
13341
+ if (confirm) {
13342
+ const message = typeof confirm.message === "function" ? confirm.message() : confirm.message;
13343
+ if (!await this._confirmSvc.confirm({
13344
+ title: confirm.title,
13345
+ message,
13346
+ confirmLabel: confirm.confirmLabel,
13347
+ cancelLabel: confirm.cancelLabel,
13348
+ variant: confirm.variant,
13349
+ ...confirm.details?.length ? { details: confirm.details } : {}
13350
+ })) return;
13351
+ }
13228
13352
  this.tableButtonClick.emit(type);
13229
13353
  }
13230
13354
  onImported() {
@@ -13435,6 +13559,37 @@ var DataTableComponent = class DataTableComponent {
13435
13559
  const days = item[col.daysKey ?? col.key];
13436
13560
  return days != null && days > (col.overdueThreshold ?? 30);
13437
13561
  }
13562
+ static {
13563
+ this._NO_ICON_TYPES = [
13564
+ "avatar-name",
13565
+ "link",
13566
+ "tags",
13567
+ "progress",
13568
+ "image",
13569
+ "actions",
13570
+ "days-ago"
13571
+ ];
13572
+ }
13573
+ cellIconPath(col, item) {
13574
+ if (!col.iconFn || DataTableComponent._NO_ICON_TYPES.includes(col.cellType ?? "")) return null;
13575
+ let raw;
13576
+ try {
13577
+ raw = col.iconFn(item);
13578
+ } catch {
13579
+ return null;
13580
+ }
13581
+ const v = (raw ?? "").trim();
13582
+ if (!v) return null;
13583
+ return iconPath(v) ?? (/^[Mm][\d\s.,\-MmLlHhVvCcSsQqTtAaZz]+$/.test(v) ? v : null);
13584
+ }
13585
+ cellIconLabel(col, item) {
13586
+ if (!col.iconLabelFn || !this.cellIconPath(col, item)) return "";
13587
+ try {
13588
+ return (col.iconLabelFn(item) ?? "").trim();
13589
+ } catch {
13590
+ return "";
13591
+ }
13592
+ }
13438
13593
  cardCellText(col, item) {
13439
13594
  switch (col.cellType) {
13440
13595
  case "date": {
@@ -13621,6 +13776,20 @@ var DataTableComponent = class DataTableComponent {
13621
13776
  isRequired: false,
13622
13777
  transformFunction: null
13623
13778
  },
13779
+ totalsEndpoint: {
13780
+ classPropertyName: "totalsEndpoint",
13781
+ publicName: "totalsEndpoint",
13782
+ isSignal: true,
13783
+ isRequired: false,
13784
+ transformFunction: null
13785
+ },
13786
+ totalsLabel: {
13787
+ classPropertyName: "totalsLabel",
13788
+ publicName: "totalsLabel",
13789
+ isSignal: true,
13790
+ isRequired: false,
13791
+ transformFunction: null
13792
+ },
13624
13793
  params: {
13625
13794
  classPropertyName: "params",
13626
13795
  publicName: "params",
@@ -13850,6 +14019,14 @@ var DataTableComponent = class DataTableComponent {
13850
14019
  </div>
13851
14020
  }
13852
14021
 
14022
+ <!-- Optional leading icon (ColumnDef.iconFn, library source 2026-11-05): decorative svg, plus sr-only text only when iconLabelFn returns one. Draws nothing when there is no valid icon. -->
14023
+ <ng-template #cellIcon let-col="col" let-item="item">
14024
+ @if (cellIconPath(col, item); as iconD) {
14025
+ <svg class="dt-cell-icon" width="16" height="16" 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" /></svg>
14026
+ @if (cellIconLabel(col, item); as iconLbl) { <span class="dt-sr-only">{{ iconLbl }}</span> }
14027
+ }
14028
+ </ng-template>
14029
+
13853
14030
  <!-- Shared image-cell markup (table cell + mobile card header) -->
13854
14031
  <ng-template #imageCell let-col="col" let-item="item" let-small="small">
13855
14032
  @let imgUrl = imageUrl(col, item);
@@ -14057,16 +14234,18 @@ var DataTableComponent = class DataTableComponent {
14057
14234
  <!-- Badge cell -->
14058
14235
  @case ('badge') {
14059
14236
  @let bCfg = resolveBadge(col, item);
14060
- @if (bCfg) { <ui-badge [label]="bCfg.label" [variant]="bCfg.variant" /> } @else { — }
14237
+ @if (bCfg) { @if (col.iconFn) { <ng-container [ngTemplateOutlet]="cellIcon" [ngTemplateOutletContext]="{ col: col, item: item }" /> } <ui-badge [label]="bCfg.label" [variant]="bCfg.variant" /> } @else { — }
14061
14238
  }
14062
14239
 
14063
14240
  <!-- Date cell -->
14064
14241
  @case ('date') {
14242
+ @if (col.iconFn) { <ng-container [ngTemplateOutlet]="cellIcon" [ngTemplateOutletContext]="{ col: col, item: item }" /> }
14065
14243
  {{ item[col.key] ? (item[col.key] | date:(col.dateFormat ?? 'MMM d, y')) : '—' }}
14066
14244
  }
14067
14245
 
14068
14246
  <!-- Phone cell -->
14069
14247
  @case ('phone') {
14248
+ @if (col.iconFn) { <ng-container [ngTemplateOutlet]="cellIcon" [ngTemplateOutletContext]="{ col: col, item: item }" /> }
14070
14249
  {{ phoneCell(item[col.key]) }}
14071
14250
  }
14072
14251
 
@@ -14154,6 +14333,7 @@ var DataTableComponent = class DataTableComponent {
14154
14333
 
14155
14334
  <!-- Default: plain text -->
14156
14335
  @default {
14336
+ @if (col.iconFn) { <ng-container [ngTemplateOutlet]="cellIcon" [ngTemplateOutletContext]="{ col: col, item: item }" /> }
14157
14337
  @if (col.starFn?.(item); as starTip) {
14158
14338
  <ui-star class="dt-cell-star" [tooltip]="starTip" />
14159
14339
  }
@@ -14167,6 +14347,35 @@ var DataTableComponent = class DataTableComponent {
14167
14347
  }
14168
14348
  }
14169
14349
  </tbody>
14350
+ @if (_footerVisible()) {
14351
+ <tfoot data-testid="dt-footer">
14352
+ <tr>
14353
+ @if (_reorderOn()) { <td class="dt-td-grip"></td> }
14354
+ @if (_isSelectable()) { <td class="dt-td-cb"></td> }
14355
+ @for (col of visibleCols(); track col.key; let first = $first) {
14356
+ @if (first) {
14357
+ <th scope="row" class="dt-foot-label"
14358
+ [style.text-align]="col.align ?? (col.cellType === 'number' ? 'right' : 'left')"
14359
+ [style.width]="col.width ?? null"
14360
+ [style.min-width]="col.width ?? null"
14361
+ [style.max-width]="col.width ?? null">
14362
+ @if (_footerCells()[col.key]; as ft) {
14363
+ <span class="dt-sr-only">{{ totalsLabel() }}: </span>{{ ft }}
14364
+ } @else {
14365
+ {{ totalsLabel() }}
14366
+ }
14367
+ </th>
14368
+ } @else {
14369
+ <td class="dt-foot-cell"
14370
+ [style.text-align]="col.align ?? (col.cellType === 'number' ? 'right' : 'left')"
14371
+ [style.width]="col.width ?? null"
14372
+ [style.min-width]="col.width ?? null"
14373
+ [style.max-width]="col.width ?? null">{{ _footerCells()[col.key] || '' }}</td>
14374
+ }
14375
+ }
14376
+ </tr>
14377
+ </tfoot>
14378
+ }
14170
14379
  </table>
14171
14380
  </div>
14172
14381
  }
@@ -14282,6 +14491,7 @@ var DataTableComponent = class DataTableComponent {
14282
14491
  </span>
14283
14492
  } @else {
14284
14493
  <span class="dt-card-name dt-card-name-plain">
14494
+ @if (tc.iconFn) { <ng-container [ngTemplateOutlet]="cellIcon" [ngTemplateOutletContext]="{ col: tc, item: item }" /> }
14285
14495
  @if (tc.starFn?.(item); as starTip) {
14286
14496
  <ui-star class="dt-cell-star" [tooltip]="starTip" />
14287
14497
  }
@@ -14319,7 +14529,7 @@ var DataTableComponent = class DataTableComponent {
14319
14529
  <div class="dt-card-badges">
14320
14530
  @for (bc of _cardCols().badgeCols; track bc.key) {
14321
14531
  @let bCfg = resolveBadge(bc, item);
14322
- @if (bCfg) { <ui-badge [label]="bCfg.label" [variant]="bCfg.variant" /> }
14532
+ @if (bCfg) { @if (bc.iconFn) { <ng-container [ngTemplateOutlet]="cellIcon" [ngTemplateOutletContext]="{ col: bc, item: item }" /> } <ui-badge [label]="bCfg.label" [variant]="bCfg.variant" /> }
14323
14533
  }
14324
14534
  </div>
14325
14535
  }
@@ -14350,6 +14560,7 @@ var DataTableComponent = class DataTableComponent {
14350
14560
  @if (dc.cellType === 'link') {
14351
14561
  <ng-container [ngTemplateOutlet]="linkCell" [ngTemplateOutletContext]="{ col: dc, item: item }" />
14352
14562
  } @else {
14563
+ @if (dc.iconFn) { <ng-container [ngTemplateOutlet]="cellIcon" [ngTemplateOutletContext]="{ col: dc, item: item }" /> }
14353
14564
  {{ val }}
14354
14565
  }</span>
14355
14566
  </div>
@@ -14363,6 +14574,18 @@ var DataTableComponent = class DataTableComponent {
14363
14574
  }
14364
14575
 
14365
14576
  </div>
14577
+ @if (_footerVisible()) {
14578
+ <div class="dt-card dt-card-totals" role="group" [attr.aria-label]="totalsLabel()" data-testid="dt-footer-card">
14579
+ <div class="dt-card-details">
14580
+ @for (fc of _footerPhoneLines(); track fc.key) {
14581
+ <div class="dt-card-detail-row">
14582
+ <span class="dt-card-detail-label">{{ fc.label }}</span>
14583
+ <span class="dt-card-detail-value">{{ fc.value }}</span>
14584
+ </div>
14585
+ }
14586
+ </div>
14587
+ </div>
14588
+ }
14366
14589
  }
14367
14590
 
14368
14591
  @if (_reorderOn()) {
@@ -14431,7 +14654,7 @@ var DataTableComponent = class DataTableComponent {
14431
14654
  </div>
14432
14655
  `,
14433
14656
  isInline: true,
14434
- styles: [":host{display:flex;flex-direction:column;flex:1;min-height:0}.dt-host{display:flex;flex-direction:column;height:100%;min-height:0}.dt-header{display:flex;align-items:center;gap:12px;margin-bottom:16px;flex-wrap:wrap;justify-content:space-between;position:relative;z-index:10}.dt-header-left{display:flex;align-items:center;gap:10px;flex-wrap:wrap;flex:1;min-width:0}.dt-header-right{display:flex;align-items:center;gap:8px;flex-shrink:0;flex-wrap:wrap;justify-content:flex-end}.dt-title{margin:0;font-size:.8125rem;font-weight:700;letter-spacing:.06em;text-transform:uppercase;color:#64748b;overflow-wrap:anywhere}.dt-sk-shimmer{position:relative;overflow:hidden;background:#f1f5f9}.dt-sk-shimmer:after{content:\"\";position:absolute;inset:0;background:linear-gradient(90deg,transparent 25%,rgba(255,255,255,.65) 50%,transparent 75%);transform:translate(-100%);animation:dt-shimmer 1.4s ease-in-out infinite}@keyframes dt-shimmer{to{transform:translate(200%)}}.dt-sk-toolbar{display:flex;align-items:center;justify-content:space-between;gap:12px;margin-bottom:16px}.dt-sk-toolbar-left{display:flex;align-items:center;gap:10px;flex-wrap:wrap}.dt-sk-toolbar-right{display:flex;align-items:center;gap:8px;flex-shrink:0}.dt-sk-search{display:flex;align-items:center;gap:10px;width:380px;height:36px;padding:0 12px;border:1px solid #e2e8f0;border-radius:6px;background:#f8fafc;box-sizing:border-box}.dt-sk-search-icon{width:16px;height:16px;border-radius:50%;flex-shrink:0}.dt-sk-search-text{flex:1;height:11px;border-radius:4px}.dt-sk-tab-strip{display:flex;gap:2px;padding:3px;background:#f1f5f9;border-radius:8px}.dt-sk-tab{height:28px;width:70px;border-radius:6px}.dt-sk-icon-btn{width:32px;height:32px;border-radius:6px}.dt-skeleton{border:1px solid #e2e8f0;border-radius:10px;overflow:hidden}.dt-sk-header{display:flex;gap:24px;padding:12px 16px;background:#f8fafc;border-bottom:1px solid #e2e8f0}.dt-sk-row{display:flex;gap:24px;padding:13px 16px;border-bottom:1px solid #f1f5f9}.dt-sk-row:last-child{border-bottom:none}.dt-sk-cell{flex:1;height:13px;border-radius:4px;position:relative;overflow:hidden;background:#f1f5f9}.dt-sk-cell:first-child{max-width:100px}.dt-sk-cell:after{content:\"\";position:absolute;inset:0;background:linear-gradient(90deg,transparent 25%,rgba(255,255,255,.65) 50%,transparent 75%);transform:translate(-100%);animation:dt-shimmer 1.4s ease-in-out infinite}.dt-sk-head{height:10px}.dt-table-wrap{flex:1;min-height:0;overflow:auto;border:1px solid #e2e8f0;border-radius:10px 10px 0 0}.dt-sk-reload-row td{padding:10px 14px;border-bottom:1px solid #f1f5f9}table{width:100%;border-collapse:collapse;font-size:.875rem}thead tr{background:#f8fafc;border-bottom:1px solid #e2e8f0}thead{position:sticky;top:0;z-index:2}th{padding:10px 14px;font-size:.75rem;font-weight:600;color:#64748b;text-transform:uppercase;letter-spacing:.04em;white-space:nowrap;border-right:1px solid #e2e8f0;text-align:center;background:#f8fafc}th:last-child{border-right:none}th.dt-th-sorted{background:#f1f5f9}th.dt-th-actions{width:48px}.dt-th-inner{display:flex;align-items:center;justify-content:center;gap:4px}.dt-sort-btn{display:inline-flex;align-items:center;gap:4px;background:none;border:none;cursor:pointer;font-size:inherit;font-weight:inherit;color:inherit;font-family:inherit;padding:0;text-transform:inherit;letter-spacing:inherit}.dt-sort-btn:hover{color:#1e293b}.dt-sort-btn:focus-visible{outline:2px solid #60a5fa;outline-offset:2px;border-radius:2px}@media(pointer:coarse){.dt-sort-btn{position:relative}.dt-sort-btn:after{content:\"\";position:absolute;left:-4px;right:-4px;top:50%;height:44px;transform:translateY(-50%)}}.dt-sort-icon{transition:transform .15s}.dt-sort-desc{transform:rotate(180deg)}.dt-sort-inactive{opacity:.4}tbody tr{border-bottom:1px solid #f1f5f9;background:#fff;transition:background .1s}tbody tr:last-child{border-bottom:none}tbody tr:hover{background:#f8fafc}.dt-row-clickable{cursor:pointer}.dt-row-clickable:focus-visible{outline:2px solid #3b82f6;outline-offset:-2px}td{padding:10px 14px;color:#334155;vertical-align:middle;white-space:nowrap;border-right:1px solid #f1f5f9}td:last-child{border-right:none}.dt-td-actions{text-align:center;padding:6px 8px}.dt-sticky-actions th.dt-th-actions,.dt-sticky-actions td.dt-td-actions{position:sticky;right:0;box-shadow:-1px 0 #e2e8f0}.dt-sticky-actions th.dt-th-actions{z-index:3;background:#f8fafc}.dt-sticky-actions td.dt-td-actions{z-index:1;background:#fff}.dt-sticky-actions td.dt-td-actions:focus-within,.dt-sticky-actions td.dt-td-actions:has(.mm-dropdown){z-index:2}.dt-sticky-actions tbody tr:hover td.dt-td-actions{background:#f8fafc}.dt-sticky-actions tbody tr.dt-row-selected td.dt-td-actions{background:#eff6ff}.dt-sticky-actions tbody tr.dt-row-selected:hover td.dt-td-actions{background:#dbeafe}.dt-td-width{overflow:hidden;text-overflow:ellipsis}.dt-img{display:inline-block;vertical-align:middle;object-fit:cover;border:1px solid #e2e8f0;background:#f1f5f9;flex-shrink:0}.dt-img-ph{display:inline-flex;align-items:center;justify-content:center;vertical-align:middle;color:#94a3b8;background:#f1f5f9;border:1px solid #e2e8f0;flex-shrink:0}.dt-img-ph svg{width:55%;height:55%}.dt-img-circle-md{width:40px;height:40px;border-radius:50%}.dt-img-circle-sm{width:28px;height:28px;border-radius:50%}.dt-img-rounded-md{width:48px;height:32px;border-radius:6px}.dt-img-rounded-sm{width:36px;height:24px;border-radius:5px}.dt-avatar-name{display:flex;align-items:center;gap:8px}.dt-name-text{color:#1e293b}.dt-overdue{color:#dc2626;font-weight:500}.dt-none{color:#64748b}.dt-link{position:relative;display:inline-block;max-width:100%;padding:1px 2px;vertical-align:bottom;overflow:hidden;text-overflow:ellipsis;white-space:nowrap;color:#2563eb;text-decoration:none;border-radius:3px;cursor:pointer}.dt-link:hover{text-decoration:underline;color:#1d4ed8}.dt-link:focus-visible{outline:2px solid #3b82f6;outline-offset:-2px;text-decoration:underline}.dt-card-detail-value .dt-link,.dt-card-name .dt-link{white-space:normal;overflow-wrap:anywhere}.dt-sr-only{position:absolute;width:1px;height:1px;margin:-1px;padding:0;overflow:hidden;clip:rect(0,0,0,0);white-space:nowrap;border:0}.dt-tags{display:flex;align-items:center;gap:4px}.dt-tags-more{font-size:.75rem;font-weight:600;color:#475569;background:#f1f5f9;border-radius:999px;padding:2px 7px;cursor:default;-webkit-user-select:none;user-select:none;border:1px solid #e2e8f0}.dt-tags-more:focus-visible{outline:2px solid #60a5fa;outline-offset:2px;border-radius:999px}.dt-tag-tooltip{position:fixed;z-index:9999;pointer-events:none;background:#1e293b;border-radius:10px;padding:8px 10px;display:flex;flex-direction:column;gap:5px;box-shadow:0 4px 6px #0000000f,0 10px 24px #00000024;transform:translate(-50%) translateY(-100%);animation:dt-tip-in .12s ease;max-width:220px}@keyframes dt-tip-in{0%{opacity:0;transform:translate(-50%) translateY(calc(-100% + 4px))}to{opacity:1;transform:translate(-50%) translateY(-100%)}}.dt-cell-star{margin-right:6px}.dt-actions-cell{display:flex;align-items:center;justify-content:center}.dt-bulk-bar{display:flex;align-items:center;gap:10px;flex-wrap:wrap;align-self:flex-start;padding:10px 14px;margin-bottom:8px;background:#eff6ff;border:1px solid #bfdbfe;border-radius:8px}.dt-bulk-count{font-size:.875rem;font-weight:600;color:#1e40af;white-space:nowrap;flex-shrink:0}.dt-bulk-actions{display:flex;align-items:center;gap:8px;flex-wrap:wrap;flex:1;min-width:0}.dt-bulk-actions ui-select{max-width:180px;min-width:120px}.dt-bulk-hint{font-size:.8125rem;line-height:1.35;color:#475569}.dt-card-cb{display:flex;align-items:center;padding:0 0 6px}.dt-card-selected{background:#eff6ff!important;border-color:#bfdbfe!important}.dt-th-cb{width:44px;padding:0 10px!important;text-align:center!important;border-right:1px solid #e2e8f0;background:#f8fafc}.dt-td-cb{width:44px;padding:0 10px!important;text-align:center!important;border-right:1px solid #f1f5f9}.dt-th-grip{width:36px;padding:0!important;border-right:1px solid #e2e8f0;background:#f8fafc}.dt-td-grip{width:36px;padding:0!important;text-align:center!important;border-right:1px solid #f1f5f9}.dt-grip{display:inline-flex;align-items:center;justify-content:center;width:28px;height:28px;border-radius:6px;color:#64748b;cursor:grab;-webkit-user-select:none;user-select:none;touch-action:none}.dt-grip:hover{background:#f1f5f9;color:#334155}.dt-grip:active{cursor:grabbing}.dt-grip:focus-visible{outline:2px solid #3b82f6;outline-offset:1px}.dt-grip-off{color:#cbd5e1;cursor:not-allowed}.dt-grip-off:hover{background:none;color:#cbd5e1}.dt-row-move{display:none}@media(pointer:coarse){.dt-grip{display:none}.dt-row-move{display:inline-flex;flex-direction:column;align-items:center}.dt-th-grip,.dt-td-grip{width:56px}}.dt-row-dragging{opacity:.45}.dt-row-over-before>td{box-shadow:inset 0 2px #3b82f6}.dt-row-over-after>td{box-shadow:inset 0 -2px #3b82f6}.dt-card-move{display:inline-flex;align-items:center;gap:2px;flex-shrink:0}@media(forced-colors:active){.dt-row-over-before>td{box-shadow:inset 0 2px 0 Highlight}.dt-row-over-after>td{box-shadow:inset 0 -2px 0 Highlight}.dt-grip:focus-visible{outline-color:Highlight}}.dt-row-selected{background:#eff6ff!important}.dt-row-selected:hover{background:#dbeafe!important}.dt-state-cell{padding:0!important;border:none!important;background:#fff!important}@media(max-width:1024px){th{padding:10px 12px}td{padding:11px 12px}.dt-sort-btn{padding:4px 0}.dt-td-actions{padding:6px}.dt-bulk-bar{align-self:stretch}}@media(max-width:820px){.dt-header-left{flex-basis:100%}.dt-header-right{flex-basis:100%;justify-content:flex-start}}@media(max-width:768px){th{padding:9px 10px;font-size:.8125rem}td{padding:10px;font-size:.8125rem}.dt-sk-search{width:100%}}@media(max-width:640px){.dt-header{flex-direction:column;flex-wrap:nowrap;flex-shrink:0;align-items:stretch}.dt-header-left,.dt-header-right{width:100%;flex-basis:auto}.dt-table-wrap{display:none}.dt-sk-search{width:100%}.dt-sk-toolbar{flex-direction:column;align-items:stretch;gap:8px}.dt-sk-toolbar-right{align-self:flex-end}.dt-bulk-bar{align-self:stretch;padding:10px 12px;row-gap:8px}.dt-bulk-count{flex:1 1 100%}.dt-bulk-actions{flex:1 1 auto;width:auto}.dt-bulk-hint{flex-basis:100%}.dt-bulk-actions ui-select{max-width:100%;flex:1}}.dt-confirm-msg{margin:0;font-size:.9375rem;color:#334155;line-height:1.5;overflow-wrap:anywhere;word-break:break-word;white-space:pre-line}.dt-confirm-details{margin:10px 0 0;padding-left:20px;font-size:.875rem;color:#64748b;line-height:1.5;overflow-wrap:anywhere;word-break:break-word}.dt-confirm-details li+li{margin-top:4px}ui-pagination{flex-shrink:0;--ui-pagination-bg: #f8fafc}.dt-phone-controls{display:flex;flex-direction:column;gap:8px;margin-bottom:8px;flex-shrink:0}.dt-phone-sort{display:flex;align-items:center;gap:8px}.dt-phone-sort-label{font-size:.8125rem;font-weight:600;color:#475569;flex-shrink:0}.dt-phone-sort-select{flex:1;min-width:0;min-height:44px;box-sizing:border-box;padding:0 36px 0 12px;font-family:inherit;font-size:1rem;color:#1e293b;border:1px solid #7c8ba1;border-radius:8px;-webkit-appearance:none;appearance:none;background:#fff url(\"data:image/svg+xml,%3Csvg xmlns='http://www.w3.org/2000/svg' width='12' height='8' viewBox='0 0 12 8' fill='none' stroke='%2394a3b8' stroke-width='2' stroke-linecap='round' stroke-linejoin='round'%3E%3Cpath d='M1 1.5l5 5 5-5'/%3E%3C/svg%3E\") no-repeat right 12px center}.dt-phone-filters{display:flex;flex-wrap:wrap;gap:8px}.dt-card-list{display:none;flex-direction:column;gap:8px;flex:1;min-height:0;overflow-y:auto}@media(max-width:640px){.dt-card-list{display:flex;padding-bottom:8px}}.dt-card{background:#fff;border:1px solid #e2e8f0;border-radius:10px;contain:layout style;padding:14px 16px;display:flex;flex-direction:column;gap:10px;transition:background .1s}.dt-card:has(.mm-dropdown){position:relative;z-index:1}.dt-card-clickable{cursor:pointer}.dt-card-clickable:active{background:#f8fafc}.dt-card-clickable:focus-visible{outline:2px solid #3b82f6;outline-offset:2px}.dt-card-header{display:flex;align-items:center;gap:10px}.dt-card-title{display:flex;align-items:center;gap:10px;flex:1;min-width:0}.dt-card-name{min-width:0;font-weight:600;color:#1e293b;font-size:.9375rem;overflow:hidden;text-overflow:ellipsis;overflow-wrap:anywhere;display:-webkit-box;-webkit-box-orient:vertical;-webkit-line-clamp:3;line-clamp:3}.dt-card-name-plain{flex:1}.dt-card-actions{margin-left:auto;flex-shrink:0}.dt-card-badges{display:flex;flex-wrap:wrap;gap:6px}.dt-card-tags{display:flex;flex-wrap:wrap;gap:4px}.dt-card-details{display:flex;flex-direction:column;gap:5px}.dt-card-detail-row{display:flex;justify-content:space-between;align-items:baseline;gap:8px;font-size:.8125rem}.dt-card-detail-label{color:#64748b;flex-shrink:0}.dt-card-detail-value{color:#334155;font-weight:500;text-align:right;min-width:0;overflow-wrap:anywhere;word-break:break-word}.dt-card-sk{gap:12px}.dt-card-sk-header{display:flex;align-items:center;gap:10px}.dt-card-sk-badges{display:flex;gap:6px}.dt-card-sk-rows{display:flex;flex-direction:column;gap:8px}@media(prefers-reduced-motion:reduce){.dt-sk-shimmer:after,.dt-sk-cell:after{animation:none;transform:none;opacity:0}.dt-tag-tooltip{animation:none}.dt-sort-icon{transition:none}}\n"],
14657
+ styles: [":host{display:flex;flex-direction:column;flex:1;min-height:0}.dt-host{display:flex;flex-direction:column;height:100%;min-height:0}.dt-header{display:flex;align-items:center;gap:12px;margin-bottom:16px;flex-wrap:wrap;justify-content:space-between;position:relative;z-index:10}.dt-header-left{display:flex;align-items:center;gap:10px;flex-wrap:wrap;flex:1;min-width:0}.dt-header-right{display:flex;align-items:center;gap:8px;flex-shrink:0;flex-wrap:wrap;justify-content:flex-end}.dt-title{margin:0;font-size:.8125rem;font-weight:700;letter-spacing:.06em;text-transform:uppercase;color:#64748b;overflow-wrap:anywhere}.dt-sk-shimmer{position:relative;overflow:hidden;background:#f1f5f9}.dt-sk-shimmer:after{content:\"\";position:absolute;inset:0;background:linear-gradient(90deg,transparent 25%,rgba(255,255,255,.65) 50%,transparent 75%);transform:translate(-100%);animation:dt-shimmer 1.4s ease-in-out infinite}@keyframes dt-shimmer{to{transform:translate(200%)}}.dt-sk-toolbar{display:flex;align-items:center;justify-content:space-between;gap:12px;margin-bottom:16px}.dt-sk-toolbar-left{display:flex;align-items:center;gap:10px;flex-wrap:wrap}.dt-sk-toolbar-right{display:flex;align-items:center;gap:8px;flex-shrink:0}.dt-sk-search{display:flex;align-items:center;gap:10px;width:380px;height:36px;padding:0 12px;border:1px solid #e2e8f0;border-radius:6px;background:#f8fafc;box-sizing:border-box}.dt-sk-search-icon{width:16px;height:16px;border-radius:50%;flex-shrink:0}.dt-sk-search-text{flex:1;height:11px;border-radius:4px}.dt-sk-tab-strip{display:flex;gap:2px;padding:3px;background:#f1f5f9;border-radius:8px}.dt-sk-tab{height:28px;width:70px;border-radius:6px}.dt-sk-icon-btn{width:32px;height:32px;border-radius:6px}.dt-skeleton{border:1px solid #e2e8f0;border-radius:10px;overflow:hidden}.dt-sk-header{display:flex;gap:24px;padding:12px 16px;background:#f8fafc;border-bottom:1px solid #e2e8f0}.dt-sk-row{display:flex;gap:24px;padding:13px 16px;border-bottom:1px solid #f1f5f9}.dt-sk-row:last-child{border-bottom:none}.dt-sk-cell{flex:1;height:13px;border-radius:4px;position:relative;overflow:hidden;background:#f1f5f9}.dt-sk-cell:first-child{max-width:100px}.dt-sk-cell:after{content:\"\";position:absolute;inset:0;background:linear-gradient(90deg,transparent 25%,rgba(255,255,255,.65) 50%,transparent 75%);transform:translate(-100%);animation:dt-shimmer 1.4s ease-in-out infinite}.dt-sk-head{height:10px}.dt-table-wrap{flex:1;min-height:0;overflow:auto;border:1px solid #e2e8f0;border-radius:10px 10px 0 0}.dt-sk-reload-row td{padding:10px 14px;border-bottom:1px solid #f1f5f9}table{width:100%;border-collapse:collapse;font-size:.875rem}thead tr{background:#f8fafc;border-bottom:1px solid #e2e8f0}thead{position:sticky;top:0;z-index:2}th{padding:10px 14px;font-size:.75rem;font-weight:600;color:#64748b;text-transform:uppercase;letter-spacing:.04em;white-space:nowrap;border-right:1px solid #e2e8f0;text-align:center;background:#f8fafc}th:last-child{border-right:none}th.dt-th-sorted{background:#f1f5f9}th.dt-th-actions{width:48px}.dt-th-inner{display:flex;align-items:center;justify-content:center;gap:4px}.dt-sort-btn{display:inline-flex;align-items:center;gap:4px;background:none;border:none;cursor:pointer;font-size:inherit;font-weight:inherit;color:inherit;font-family:inherit;padding:0;text-transform:inherit;letter-spacing:inherit}.dt-sort-btn:hover{color:#1e293b}.dt-sort-btn:focus-visible{outline:2px solid #60a5fa;outline-offset:2px;border-radius:2px}@media(pointer:coarse){.dt-sort-btn{position:relative}.dt-sort-btn:after{content:\"\";position:absolute;left:-4px;right:-4px;top:50%;height:44px;transform:translateY(-50%)}}.dt-sort-icon{transition:transform .15s}.dt-sort-desc{transform:rotate(180deg)}.dt-sort-inactive{opacity:.4}tbody tr{border-bottom:1px solid #f1f5f9;background:#fff;transition:background .1s}tbody tr:last-child{border-bottom:none}tbody tr:hover{background:#f8fafc}tfoot tr{background:#f8fafc;border-top:2px solid #e2e8f0}tfoot th.dt-foot-label{padding:10px 14px;font-size:.875rem;font-weight:700;color:#1e293b;text-transform:none;letter-spacing:normal;background:#f8fafc;border-right:1px solid #f1f5f9;white-space:nowrap}tfoot td{padding:10px 14px;font-weight:700;color:#1e293b;background:#f8fafc}.dt-card-totals{background:#f8fafc;font-weight:600}.dt-row-clickable{cursor:pointer}.dt-row-clickable:focus-visible{outline:2px solid #3b82f6;outline-offset:-2px}td{padding:10px 14px;color:#334155;vertical-align:middle;white-space:nowrap;border-right:1px solid #f1f5f9}td:last-child{border-right:none}.dt-td-actions{text-align:center;padding:6px 8px}.dt-sticky-actions th.dt-th-actions,.dt-sticky-actions td.dt-td-actions{position:sticky;right:0;box-shadow:-1px 0 #e2e8f0}.dt-sticky-actions th.dt-th-actions{z-index:3;background:#f8fafc}.dt-sticky-actions td.dt-td-actions{z-index:1;background:#fff}.dt-sticky-actions td.dt-td-actions:focus-within,.dt-sticky-actions td.dt-td-actions:has(.mm-dropdown){z-index:2}.dt-sticky-actions tbody tr:hover td.dt-td-actions{background:#f8fafc}.dt-sticky-actions tbody tr.dt-row-selected td.dt-td-actions{background:#eff6ff}.dt-sticky-actions tbody tr.dt-row-selected:hover td.dt-td-actions{background:#dbeafe}.dt-td-width{overflow:hidden;text-overflow:ellipsis}.dt-img{display:inline-block;vertical-align:middle;object-fit:cover;border:1px solid #e2e8f0;background:#f1f5f9;flex-shrink:0}.dt-img-ph{display:inline-flex;align-items:center;justify-content:center;vertical-align:middle;color:#94a3b8;background:#f1f5f9;border:1px solid #e2e8f0;flex-shrink:0}.dt-img-ph svg{width:55%;height:55%}.dt-img-circle-md{width:40px;height:40px;border-radius:50%}.dt-img-circle-sm{width:28px;height:28px;border-radius:50%}.dt-img-rounded-md{width:48px;height:32px;border-radius:6px}.dt-img-rounded-sm{width:36px;height:24px;border-radius:5px}.dt-avatar-name{display:flex;align-items:center;gap:8px}.dt-name-text{color:#1e293b}.dt-overdue{color:#dc2626;font-weight:500}.dt-none{color:#64748b}.dt-link{position:relative;display:inline-block;max-width:100%;padding:1px 2px;vertical-align:bottom;overflow:hidden;text-overflow:ellipsis;white-space:nowrap;color:#2563eb;text-decoration:none;border-radius:3px;cursor:pointer}.dt-link:hover{text-decoration:underline;color:#1d4ed8}.dt-link:focus-visible{outline:2px solid #3b82f6;outline-offset:-2px;text-decoration:underline}.dt-card-detail-value .dt-link,.dt-card-name .dt-link{white-space:normal;overflow-wrap:anywhere}.dt-sr-only{position:absolute;width:1px;height:1px;margin:-1px;padding:0;overflow:hidden;clip:rect(0,0,0,0);white-space:nowrap;border:0}.dt-tags{display:flex;align-items:center;gap:4px}.dt-tags-more{font-size:.75rem;font-weight:600;color:#475569;background:#f1f5f9;border-radius:999px;padding:2px 7px;cursor:default;-webkit-user-select:none;user-select:none;border:1px solid #e2e8f0}.dt-tags-more:focus-visible{outline:2px solid #60a5fa;outline-offset:2px;border-radius:999px}.dt-tag-tooltip{position:fixed;z-index:9999;pointer-events:none;background:#1e293b;border-radius:10px;padding:8px 10px;display:flex;flex-direction:column;gap:5px;box-shadow:0 4px 6px #0000000f,0 10px 24px #00000024;transform:translate(-50%) translateY(-100%);animation:dt-tip-in .12s ease;max-width:220px}@keyframes dt-tip-in{0%{opacity:0;transform:translate(-50%) translateY(calc(-100% + 4px))}to{opacity:1;transform:translate(-50%) translateY(-100%)}}.dt-cell-star{margin-right:6px}.dt-cell-icon{flex-shrink:0;display:inline-block;margin-right:6px;vertical-align:-3px;color:#64748b}.dt-actions-cell{display:flex;align-items:center;justify-content:center}.dt-bulk-bar{display:flex;align-items:center;gap:10px;flex-wrap:wrap;align-self:flex-start;padding:10px 14px;margin-bottom:8px;background:#eff6ff;border:1px solid #bfdbfe;border-radius:8px}.dt-bulk-count{font-size:.875rem;font-weight:600;color:#1e40af;white-space:nowrap;flex-shrink:0}.dt-bulk-actions{display:flex;align-items:center;gap:8px;flex-wrap:wrap;flex:1;min-width:0}.dt-bulk-actions ui-select{max-width:180px;min-width:120px}.dt-bulk-hint{font-size:.8125rem;line-height:1.35;color:#475569}.dt-card-cb{display:flex;align-items:center;padding:0 0 6px}.dt-card-selected{background:#eff6ff!important;border-color:#bfdbfe!important}.dt-th-cb{width:44px;padding:0 10px!important;text-align:center!important;border-right:1px solid #e2e8f0;background:#f8fafc}.dt-td-cb{width:44px;padding:0 10px!important;text-align:center!important;border-right:1px solid #f1f5f9}.dt-th-grip{width:36px;padding:0!important;border-right:1px solid #e2e8f0;background:#f8fafc}.dt-td-grip{width:36px;padding:0!important;text-align:center!important;border-right:1px solid #f1f5f9}.dt-grip{display:inline-flex;align-items:center;justify-content:center;width:28px;height:28px;border-radius:6px;color:#64748b;cursor:grab;-webkit-user-select:none;user-select:none;touch-action:none}.dt-grip:hover{background:#f1f5f9;color:#334155}.dt-grip:active{cursor:grabbing}.dt-grip:focus-visible{outline:2px solid #3b82f6;outline-offset:1px}.dt-grip-off{color:#cbd5e1;cursor:not-allowed}.dt-grip-off:hover{background:none;color:#cbd5e1}.dt-row-move{display:none}@media(pointer:coarse){.dt-grip{display:none}.dt-row-move{display:inline-flex;flex-direction:column;align-items:center}.dt-th-grip,.dt-td-grip{width:56px}}.dt-row-dragging{opacity:.45}.dt-row-over-before>td{box-shadow:inset 0 2px #3b82f6}.dt-row-over-after>td{box-shadow:inset 0 -2px #3b82f6}.dt-card-move{display:inline-flex;align-items:center;gap:2px;flex-shrink:0}@media(forced-colors:active){.dt-row-over-before>td{box-shadow:inset 0 2px 0 Highlight}.dt-row-over-after>td{box-shadow:inset 0 -2px 0 Highlight}.dt-grip:focus-visible{outline-color:Highlight}}.dt-row-selected{background:#eff6ff!important}.dt-row-selected:hover{background:#dbeafe!important}.dt-state-cell{padding:0!important;border:none!important;background:#fff!important}@media(max-width:1024px){th{padding:10px 12px}td{padding:11px 12px}.dt-sort-btn{padding:4px 0}.dt-td-actions{padding:6px}.dt-bulk-bar{align-self:stretch}}@media(max-width:820px){.dt-header-left{flex-basis:100%}.dt-header-right{flex-basis:100%;justify-content:flex-start}}@media(max-width:768px){th{padding:9px 10px;font-size:.8125rem}td{padding:10px;font-size:.8125rem}.dt-sk-search{width:100%}}@media(max-width:640px){.dt-header{flex-direction:column;flex-wrap:nowrap;flex-shrink:0;align-items:stretch}.dt-header-left,.dt-header-right{width:100%;flex-basis:auto}.dt-table-wrap{display:none}.dt-sk-search{width:100%}.dt-sk-toolbar{flex-direction:column;align-items:stretch;gap:8px}.dt-sk-toolbar-right{align-self:flex-end}.dt-bulk-bar{align-self:stretch;padding:10px 12px;row-gap:8px}.dt-bulk-count{flex:1 1 100%}.dt-bulk-actions{flex:1 1 auto;width:auto}.dt-bulk-hint{flex-basis:100%}.dt-bulk-actions ui-select{max-width:100%;flex:1}}.dt-confirm-msg{margin:0;font-size:.9375rem;color:#334155;line-height:1.5;overflow-wrap:anywhere;word-break:break-word;white-space:pre-line}.dt-confirm-details{margin:10px 0 0;padding-left:20px;font-size:.875rem;color:#64748b;line-height:1.5;overflow-wrap:anywhere;word-break:break-word}.dt-confirm-details li+li{margin-top:4px}ui-pagination{flex-shrink:0;--ui-pagination-bg: #f8fafc}.dt-phone-controls{display:flex;flex-direction:column;gap:8px;margin-bottom:8px;flex-shrink:0}.dt-phone-sort{display:flex;align-items:center;gap:8px}.dt-phone-sort-label{font-size:.8125rem;font-weight:600;color:#475569;flex-shrink:0}.dt-phone-sort-select{flex:1;min-width:0;min-height:44px;box-sizing:border-box;padding:0 36px 0 12px;font-family:inherit;font-size:1rem;color:#1e293b;border:1px solid #7c8ba1;border-radius:8px;-webkit-appearance:none;appearance:none;background:#fff url(\"data:image/svg+xml,%3Csvg xmlns='http://www.w3.org/2000/svg' width='12' height='8' viewBox='0 0 12 8' fill='none' stroke='%2394a3b8' stroke-width='2' stroke-linecap='round' stroke-linejoin='round'%3E%3Cpath d='M1 1.5l5 5 5-5'/%3E%3C/svg%3E\") no-repeat right 12px center}.dt-phone-filters{display:flex;flex-wrap:wrap;gap:8px}.dt-card-list{display:none;flex-direction:column;gap:8px;flex:1;min-height:0;overflow-y:auto}@media(max-width:640px){.dt-card-list{display:flex;padding-bottom:8px}}.dt-card{background:#fff;border:1px solid #e2e8f0;border-radius:10px;contain:layout style;padding:14px 16px;display:flex;flex-direction:column;gap:10px;transition:background .1s}.dt-card:has(.mm-dropdown){position:relative;z-index:1}.dt-card-clickable{cursor:pointer}.dt-card-clickable:active{background:#f8fafc}.dt-card-clickable:focus-visible{outline:2px solid #3b82f6;outline-offset:2px}.dt-card-header{display:flex;align-items:center;gap:10px}.dt-card-title{display:flex;align-items:center;gap:10px;flex:1;min-width:0}.dt-card-name{min-width:0;font-weight:600;color:#1e293b;font-size:.9375rem;overflow:hidden;text-overflow:ellipsis;overflow-wrap:anywhere;display:-webkit-box;-webkit-box-orient:vertical;-webkit-line-clamp:3;line-clamp:3}.dt-card-name-plain{flex:1}.dt-card-actions{margin-left:auto;flex-shrink:0}.dt-card-badges{display:flex;flex-wrap:wrap;gap:6px}.dt-card-tags{display:flex;flex-wrap:wrap;gap:4px}.dt-card-details{display:flex;flex-direction:column;gap:5px}.dt-card-detail-row{display:flex;justify-content:space-between;align-items:baseline;gap:8px;font-size:.8125rem}.dt-card-detail-label{color:#64748b;flex-shrink:0}.dt-card-detail-value{color:#334155;font-weight:500;text-align:right;min-width:0;overflow-wrap:anywhere;word-break:break-word}.dt-card-sk{gap:12px}.dt-card-sk-header{display:flex;align-items:center;gap:10px}.dt-card-sk-badges{display:flex;gap:6px}.dt-card-sk-rows{display:flex;flex-direction:column;gap:8px}@media(prefers-reduced-motion:reduce){.dt-sk-shimmer:after,.dt-sk-cell:after{animation:none;transform:none;opacity:0}.dt-tag-tooltip{animation:none}.dt-sort-icon{transition:none}}\n"],
14435
14658
  dependencies: [
14436
14659
  {
14437
14660
  kind: "directive",
@@ -14947,6 +15170,14 @@ i0.ɵɵngDeclareClassMetadata({
14947
15170
  </div>
14948
15171
  }
14949
15172
 
15173
+ <!-- Optional leading icon (ColumnDef.iconFn, library source 2026-11-05): decorative svg, plus sr-only text only when iconLabelFn returns one. Draws nothing when there is no valid icon. -->
15174
+ <ng-template #cellIcon let-col="col" let-item="item">
15175
+ @if (cellIconPath(col, item); as iconD) {
15176
+ <svg class="dt-cell-icon" width="16" height="16" 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" /></svg>
15177
+ @if (cellIconLabel(col, item); as iconLbl) { <span class="dt-sr-only">{{ iconLbl }}</span> }
15178
+ }
15179
+ </ng-template>
15180
+
14950
15181
  <!-- Shared image-cell markup (table cell + mobile card header) -->
14951
15182
  <ng-template #imageCell let-col="col" let-item="item" let-small="small">
14952
15183
  @let imgUrl = imageUrl(col, item);
@@ -15154,16 +15385,18 @@ i0.ɵɵngDeclareClassMetadata({
15154
15385
  <!-- Badge cell -->
15155
15386
  @case ('badge') {
15156
15387
  @let bCfg = resolveBadge(col, item);
15157
- @if (bCfg) { <ui-badge [label]="bCfg.label" [variant]="bCfg.variant" /> } @else { — }
15388
+ @if (bCfg) { @if (col.iconFn) { <ng-container [ngTemplateOutlet]="cellIcon" [ngTemplateOutletContext]="{ col: col, item: item }" /> } <ui-badge [label]="bCfg.label" [variant]="bCfg.variant" /> } @else { — }
15158
15389
  }
15159
15390
 
15160
15391
  <!-- Date cell -->
15161
15392
  @case ('date') {
15393
+ @if (col.iconFn) { <ng-container [ngTemplateOutlet]="cellIcon" [ngTemplateOutletContext]="{ col: col, item: item }" /> }
15162
15394
  {{ item[col.key] ? (item[col.key] | date:(col.dateFormat ?? 'MMM d, y')) : '—' }}
15163
15395
  }
15164
15396
 
15165
15397
  <!-- Phone cell -->
15166
15398
  @case ('phone') {
15399
+ @if (col.iconFn) { <ng-container [ngTemplateOutlet]="cellIcon" [ngTemplateOutletContext]="{ col: col, item: item }" /> }
15167
15400
  {{ phoneCell(item[col.key]) }}
15168
15401
  }
15169
15402
 
@@ -15251,6 +15484,7 @@ i0.ɵɵngDeclareClassMetadata({
15251
15484
 
15252
15485
  <!-- Default: plain text -->
15253
15486
  @default {
15487
+ @if (col.iconFn) { <ng-container [ngTemplateOutlet]="cellIcon" [ngTemplateOutletContext]="{ col: col, item: item }" /> }
15254
15488
  @if (col.starFn?.(item); as starTip) {
15255
15489
  <ui-star class="dt-cell-star" [tooltip]="starTip" />
15256
15490
  }
@@ -15264,6 +15498,35 @@ i0.ɵɵngDeclareClassMetadata({
15264
15498
  }
15265
15499
  }
15266
15500
  </tbody>
15501
+ @if (_footerVisible()) {
15502
+ <tfoot data-testid="dt-footer">
15503
+ <tr>
15504
+ @if (_reorderOn()) { <td class="dt-td-grip"></td> }
15505
+ @if (_isSelectable()) { <td class="dt-td-cb"></td> }
15506
+ @for (col of visibleCols(); track col.key; let first = $first) {
15507
+ @if (first) {
15508
+ <th scope="row" class="dt-foot-label"
15509
+ [style.text-align]="col.align ?? (col.cellType === 'number' ? 'right' : 'left')"
15510
+ [style.width]="col.width ?? null"
15511
+ [style.min-width]="col.width ?? null"
15512
+ [style.max-width]="col.width ?? null">
15513
+ @if (_footerCells()[col.key]; as ft) {
15514
+ <span class="dt-sr-only">{{ totalsLabel() }}: </span>{{ ft }}
15515
+ } @else {
15516
+ {{ totalsLabel() }}
15517
+ }
15518
+ </th>
15519
+ } @else {
15520
+ <td class="dt-foot-cell"
15521
+ [style.text-align]="col.align ?? (col.cellType === 'number' ? 'right' : 'left')"
15522
+ [style.width]="col.width ?? null"
15523
+ [style.min-width]="col.width ?? null"
15524
+ [style.max-width]="col.width ?? null">{{ _footerCells()[col.key] || '' }}</td>
15525
+ }
15526
+ }
15527
+ </tr>
15528
+ </tfoot>
15529
+ }
15267
15530
  </table>
15268
15531
  </div>
15269
15532
  }
@@ -15379,6 +15642,7 @@ i0.ɵɵngDeclareClassMetadata({
15379
15642
  </span>
15380
15643
  } @else {
15381
15644
  <span class="dt-card-name dt-card-name-plain">
15645
+ @if (tc.iconFn) { <ng-container [ngTemplateOutlet]="cellIcon" [ngTemplateOutletContext]="{ col: tc, item: item }" /> }
15382
15646
  @if (tc.starFn?.(item); as starTip) {
15383
15647
  <ui-star class="dt-cell-star" [tooltip]="starTip" />
15384
15648
  }
@@ -15416,7 +15680,7 @@ i0.ɵɵngDeclareClassMetadata({
15416
15680
  <div class="dt-card-badges">
15417
15681
  @for (bc of _cardCols().badgeCols; track bc.key) {
15418
15682
  @let bCfg = resolveBadge(bc, item);
15419
- @if (bCfg) { <ui-badge [label]="bCfg.label" [variant]="bCfg.variant" /> }
15683
+ @if (bCfg) { @if (bc.iconFn) { <ng-container [ngTemplateOutlet]="cellIcon" [ngTemplateOutletContext]="{ col: bc, item: item }" /> } <ui-badge [label]="bCfg.label" [variant]="bCfg.variant" /> }
15420
15684
  }
15421
15685
  </div>
15422
15686
  }
@@ -15447,6 +15711,7 @@ i0.ɵɵngDeclareClassMetadata({
15447
15711
  @if (dc.cellType === 'link') {
15448
15712
  <ng-container [ngTemplateOutlet]="linkCell" [ngTemplateOutletContext]="{ col: dc, item: item }" />
15449
15713
  } @else {
15714
+ @if (dc.iconFn) { <ng-container [ngTemplateOutlet]="cellIcon" [ngTemplateOutletContext]="{ col: dc, item: item }" /> }
15450
15715
  {{ val }}
15451
15716
  }</span>
15452
15717
  </div>
@@ -15460,6 +15725,18 @@ i0.ɵɵngDeclareClassMetadata({
15460
15725
  }
15461
15726
 
15462
15727
  </div>
15728
+ @if (_footerVisible()) {
15729
+ <div class="dt-card dt-card-totals" role="group" [attr.aria-label]="totalsLabel()" data-testid="dt-footer-card">
15730
+ <div class="dt-card-details">
15731
+ @for (fc of _footerPhoneLines(); track fc.key) {
15732
+ <div class="dt-card-detail-row">
15733
+ <span class="dt-card-detail-label">{{ fc.label }}</span>
15734
+ <span class="dt-card-detail-value">{{ fc.value }}</span>
15735
+ </div>
15736
+ }
15737
+ </div>
15738
+ </div>
15739
+ }
15463
15740
  }
15464
15741
 
15465
15742
  @if (_reorderOn()) {
@@ -15527,7 +15804,7 @@ i0.ɵɵngDeclareClassMetadata({
15527
15804
  }
15528
15805
  </div>
15529
15806
  `,
15530
- styles: [":host{display:flex;flex-direction:column;flex:1;min-height:0}.dt-host{display:flex;flex-direction:column;height:100%;min-height:0}.dt-header{display:flex;align-items:center;gap:12px;margin-bottom:16px;flex-wrap:wrap;justify-content:space-between;position:relative;z-index:10}.dt-header-left{display:flex;align-items:center;gap:10px;flex-wrap:wrap;flex:1;min-width:0}.dt-header-right{display:flex;align-items:center;gap:8px;flex-shrink:0;flex-wrap:wrap;justify-content:flex-end}.dt-title{margin:0;font-size:.8125rem;font-weight:700;letter-spacing:.06em;text-transform:uppercase;color:#64748b;overflow-wrap:anywhere}.dt-sk-shimmer{position:relative;overflow:hidden;background:#f1f5f9}.dt-sk-shimmer:after{content:\"\";position:absolute;inset:0;background:linear-gradient(90deg,transparent 25%,rgba(255,255,255,.65) 50%,transparent 75%);transform:translate(-100%);animation:dt-shimmer 1.4s ease-in-out infinite}@keyframes dt-shimmer{to{transform:translate(200%)}}.dt-sk-toolbar{display:flex;align-items:center;justify-content:space-between;gap:12px;margin-bottom:16px}.dt-sk-toolbar-left{display:flex;align-items:center;gap:10px;flex-wrap:wrap}.dt-sk-toolbar-right{display:flex;align-items:center;gap:8px;flex-shrink:0}.dt-sk-search{display:flex;align-items:center;gap:10px;width:380px;height:36px;padding:0 12px;border:1px solid #e2e8f0;border-radius:6px;background:#f8fafc;box-sizing:border-box}.dt-sk-search-icon{width:16px;height:16px;border-radius:50%;flex-shrink:0}.dt-sk-search-text{flex:1;height:11px;border-radius:4px}.dt-sk-tab-strip{display:flex;gap:2px;padding:3px;background:#f1f5f9;border-radius:8px}.dt-sk-tab{height:28px;width:70px;border-radius:6px}.dt-sk-icon-btn{width:32px;height:32px;border-radius:6px}.dt-skeleton{border:1px solid #e2e8f0;border-radius:10px;overflow:hidden}.dt-sk-header{display:flex;gap:24px;padding:12px 16px;background:#f8fafc;border-bottom:1px solid #e2e8f0}.dt-sk-row{display:flex;gap:24px;padding:13px 16px;border-bottom:1px solid #f1f5f9}.dt-sk-row:last-child{border-bottom:none}.dt-sk-cell{flex:1;height:13px;border-radius:4px;position:relative;overflow:hidden;background:#f1f5f9}.dt-sk-cell:first-child{max-width:100px}.dt-sk-cell:after{content:\"\";position:absolute;inset:0;background:linear-gradient(90deg,transparent 25%,rgba(255,255,255,.65) 50%,transparent 75%);transform:translate(-100%);animation:dt-shimmer 1.4s ease-in-out infinite}.dt-sk-head{height:10px}.dt-table-wrap{flex:1;min-height:0;overflow:auto;border:1px solid #e2e8f0;border-radius:10px 10px 0 0}.dt-sk-reload-row td{padding:10px 14px;border-bottom:1px solid #f1f5f9}table{width:100%;border-collapse:collapse;font-size:.875rem}thead tr{background:#f8fafc;border-bottom:1px solid #e2e8f0}thead{position:sticky;top:0;z-index:2}th{padding:10px 14px;font-size:.75rem;font-weight:600;color:#64748b;text-transform:uppercase;letter-spacing:.04em;white-space:nowrap;border-right:1px solid #e2e8f0;text-align:center;background:#f8fafc}th:last-child{border-right:none}th.dt-th-sorted{background:#f1f5f9}th.dt-th-actions{width:48px}.dt-th-inner{display:flex;align-items:center;justify-content:center;gap:4px}.dt-sort-btn{display:inline-flex;align-items:center;gap:4px;background:none;border:none;cursor:pointer;font-size:inherit;font-weight:inherit;color:inherit;font-family:inherit;padding:0;text-transform:inherit;letter-spacing:inherit}.dt-sort-btn:hover{color:#1e293b}.dt-sort-btn:focus-visible{outline:2px solid #60a5fa;outline-offset:2px;border-radius:2px}@media(pointer:coarse){.dt-sort-btn{position:relative}.dt-sort-btn:after{content:\"\";position:absolute;left:-4px;right:-4px;top:50%;height:44px;transform:translateY(-50%)}}.dt-sort-icon{transition:transform .15s}.dt-sort-desc{transform:rotate(180deg)}.dt-sort-inactive{opacity:.4}tbody tr{border-bottom:1px solid #f1f5f9;background:#fff;transition:background .1s}tbody tr:last-child{border-bottom:none}tbody tr:hover{background:#f8fafc}.dt-row-clickable{cursor:pointer}.dt-row-clickable:focus-visible{outline:2px solid #3b82f6;outline-offset:-2px}td{padding:10px 14px;color:#334155;vertical-align:middle;white-space:nowrap;border-right:1px solid #f1f5f9}td:last-child{border-right:none}.dt-td-actions{text-align:center;padding:6px 8px}.dt-sticky-actions th.dt-th-actions,.dt-sticky-actions td.dt-td-actions{position:sticky;right:0;box-shadow:-1px 0 #e2e8f0}.dt-sticky-actions th.dt-th-actions{z-index:3;background:#f8fafc}.dt-sticky-actions td.dt-td-actions{z-index:1;background:#fff}.dt-sticky-actions td.dt-td-actions:focus-within,.dt-sticky-actions td.dt-td-actions:has(.mm-dropdown){z-index:2}.dt-sticky-actions tbody tr:hover td.dt-td-actions{background:#f8fafc}.dt-sticky-actions tbody tr.dt-row-selected td.dt-td-actions{background:#eff6ff}.dt-sticky-actions tbody tr.dt-row-selected:hover td.dt-td-actions{background:#dbeafe}.dt-td-width{overflow:hidden;text-overflow:ellipsis}.dt-img{display:inline-block;vertical-align:middle;object-fit:cover;border:1px solid #e2e8f0;background:#f1f5f9;flex-shrink:0}.dt-img-ph{display:inline-flex;align-items:center;justify-content:center;vertical-align:middle;color:#94a3b8;background:#f1f5f9;border:1px solid #e2e8f0;flex-shrink:0}.dt-img-ph svg{width:55%;height:55%}.dt-img-circle-md{width:40px;height:40px;border-radius:50%}.dt-img-circle-sm{width:28px;height:28px;border-radius:50%}.dt-img-rounded-md{width:48px;height:32px;border-radius:6px}.dt-img-rounded-sm{width:36px;height:24px;border-radius:5px}.dt-avatar-name{display:flex;align-items:center;gap:8px}.dt-name-text{color:#1e293b}.dt-overdue{color:#dc2626;font-weight:500}.dt-none{color:#64748b}.dt-link{position:relative;display:inline-block;max-width:100%;padding:1px 2px;vertical-align:bottom;overflow:hidden;text-overflow:ellipsis;white-space:nowrap;color:#2563eb;text-decoration:none;border-radius:3px;cursor:pointer}.dt-link:hover{text-decoration:underline;color:#1d4ed8}.dt-link:focus-visible{outline:2px solid #3b82f6;outline-offset:-2px;text-decoration:underline}.dt-card-detail-value .dt-link,.dt-card-name .dt-link{white-space:normal;overflow-wrap:anywhere}.dt-sr-only{position:absolute;width:1px;height:1px;margin:-1px;padding:0;overflow:hidden;clip:rect(0,0,0,0);white-space:nowrap;border:0}.dt-tags{display:flex;align-items:center;gap:4px}.dt-tags-more{font-size:.75rem;font-weight:600;color:#475569;background:#f1f5f9;border-radius:999px;padding:2px 7px;cursor:default;-webkit-user-select:none;user-select:none;border:1px solid #e2e8f0}.dt-tags-more:focus-visible{outline:2px solid #60a5fa;outline-offset:2px;border-radius:999px}.dt-tag-tooltip{position:fixed;z-index:9999;pointer-events:none;background:#1e293b;border-radius:10px;padding:8px 10px;display:flex;flex-direction:column;gap:5px;box-shadow:0 4px 6px #0000000f,0 10px 24px #00000024;transform:translate(-50%) translateY(-100%);animation:dt-tip-in .12s ease;max-width:220px}@keyframes dt-tip-in{0%{opacity:0;transform:translate(-50%) translateY(calc(-100% + 4px))}to{opacity:1;transform:translate(-50%) translateY(-100%)}}.dt-cell-star{margin-right:6px}.dt-actions-cell{display:flex;align-items:center;justify-content:center}.dt-bulk-bar{display:flex;align-items:center;gap:10px;flex-wrap:wrap;align-self:flex-start;padding:10px 14px;margin-bottom:8px;background:#eff6ff;border:1px solid #bfdbfe;border-radius:8px}.dt-bulk-count{font-size:.875rem;font-weight:600;color:#1e40af;white-space:nowrap;flex-shrink:0}.dt-bulk-actions{display:flex;align-items:center;gap:8px;flex-wrap:wrap;flex:1;min-width:0}.dt-bulk-actions ui-select{max-width:180px;min-width:120px}.dt-bulk-hint{font-size:.8125rem;line-height:1.35;color:#475569}.dt-card-cb{display:flex;align-items:center;padding:0 0 6px}.dt-card-selected{background:#eff6ff!important;border-color:#bfdbfe!important}.dt-th-cb{width:44px;padding:0 10px!important;text-align:center!important;border-right:1px solid #e2e8f0;background:#f8fafc}.dt-td-cb{width:44px;padding:0 10px!important;text-align:center!important;border-right:1px solid #f1f5f9}.dt-th-grip{width:36px;padding:0!important;border-right:1px solid #e2e8f0;background:#f8fafc}.dt-td-grip{width:36px;padding:0!important;text-align:center!important;border-right:1px solid #f1f5f9}.dt-grip{display:inline-flex;align-items:center;justify-content:center;width:28px;height:28px;border-radius:6px;color:#64748b;cursor:grab;-webkit-user-select:none;user-select:none;touch-action:none}.dt-grip:hover{background:#f1f5f9;color:#334155}.dt-grip:active{cursor:grabbing}.dt-grip:focus-visible{outline:2px solid #3b82f6;outline-offset:1px}.dt-grip-off{color:#cbd5e1;cursor:not-allowed}.dt-grip-off:hover{background:none;color:#cbd5e1}.dt-row-move{display:none}@media(pointer:coarse){.dt-grip{display:none}.dt-row-move{display:inline-flex;flex-direction:column;align-items:center}.dt-th-grip,.dt-td-grip{width:56px}}.dt-row-dragging{opacity:.45}.dt-row-over-before>td{box-shadow:inset 0 2px #3b82f6}.dt-row-over-after>td{box-shadow:inset 0 -2px #3b82f6}.dt-card-move{display:inline-flex;align-items:center;gap:2px;flex-shrink:0}@media(forced-colors:active){.dt-row-over-before>td{box-shadow:inset 0 2px 0 Highlight}.dt-row-over-after>td{box-shadow:inset 0 -2px 0 Highlight}.dt-grip:focus-visible{outline-color:Highlight}}.dt-row-selected{background:#eff6ff!important}.dt-row-selected:hover{background:#dbeafe!important}.dt-state-cell{padding:0!important;border:none!important;background:#fff!important}@media(max-width:1024px){th{padding:10px 12px}td{padding:11px 12px}.dt-sort-btn{padding:4px 0}.dt-td-actions{padding:6px}.dt-bulk-bar{align-self:stretch}}@media(max-width:820px){.dt-header-left{flex-basis:100%}.dt-header-right{flex-basis:100%;justify-content:flex-start}}@media(max-width:768px){th{padding:9px 10px;font-size:.8125rem}td{padding:10px;font-size:.8125rem}.dt-sk-search{width:100%}}@media(max-width:640px){.dt-header{flex-direction:column;flex-wrap:nowrap;flex-shrink:0;align-items:stretch}.dt-header-left,.dt-header-right{width:100%;flex-basis:auto}.dt-table-wrap{display:none}.dt-sk-search{width:100%}.dt-sk-toolbar{flex-direction:column;align-items:stretch;gap:8px}.dt-sk-toolbar-right{align-self:flex-end}.dt-bulk-bar{align-self:stretch;padding:10px 12px;row-gap:8px}.dt-bulk-count{flex:1 1 100%}.dt-bulk-actions{flex:1 1 auto;width:auto}.dt-bulk-hint{flex-basis:100%}.dt-bulk-actions ui-select{max-width:100%;flex:1}}.dt-confirm-msg{margin:0;font-size:.9375rem;color:#334155;line-height:1.5;overflow-wrap:anywhere;word-break:break-word;white-space:pre-line}.dt-confirm-details{margin:10px 0 0;padding-left:20px;font-size:.875rem;color:#64748b;line-height:1.5;overflow-wrap:anywhere;word-break:break-word}.dt-confirm-details li+li{margin-top:4px}ui-pagination{flex-shrink:0;--ui-pagination-bg: #f8fafc}.dt-phone-controls{display:flex;flex-direction:column;gap:8px;margin-bottom:8px;flex-shrink:0}.dt-phone-sort{display:flex;align-items:center;gap:8px}.dt-phone-sort-label{font-size:.8125rem;font-weight:600;color:#475569;flex-shrink:0}.dt-phone-sort-select{flex:1;min-width:0;min-height:44px;box-sizing:border-box;padding:0 36px 0 12px;font-family:inherit;font-size:1rem;color:#1e293b;border:1px solid #7c8ba1;border-radius:8px;-webkit-appearance:none;appearance:none;background:#fff url(\"data:image/svg+xml,%3Csvg xmlns='http://www.w3.org/2000/svg' width='12' height='8' viewBox='0 0 12 8' fill='none' stroke='%2394a3b8' stroke-width='2' stroke-linecap='round' stroke-linejoin='round'%3E%3Cpath d='M1 1.5l5 5 5-5'/%3E%3C/svg%3E\") no-repeat right 12px center}.dt-phone-filters{display:flex;flex-wrap:wrap;gap:8px}.dt-card-list{display:none;flex-direction:column;gap:8px;flex:1;min-height:0;overflow-y:auto}@media(max-width:640px){.dt-card-list{display:flex;padding-bottom:8px}}.dt-card{background:#fff;border:1px solid #e2e8f0;border-radius:10px;contain:layout style;padding:14px 16px;display:flex;flex-direction:column;gap:10px;transition:background .1s}.dt-card:has(.mm-dropdown){position:relative;z-index:1}.dt-card-clickable{cursor:pointer}.dt-card-clickable:active{background:#f8fafc}.dt-card-clickable:focus-visible{outline:2px solid #3b82f6;outline-offset:2px}.dt-card-header{display:flex;align-items:center;gap:10px}.dt-card-title{display:flex;align-items:center;gap:10px;flex:1;min-width:0}.dt-card-name{min-width:0;font-weight:600;color:#1e293b;font-size:.9375rem;overflow:hidden;text-overflow:ellipsis;overflow-wrap:anywhere;display:-webkit-box;-webkit-box-orient:vertical;-webkit-line-clamp:3;line-clamp:3}.dt-card-name-plain{flex:1}.dt-card-actions{margin-left:auto;flex-shrink:0}.dt-card-badges{display:flex;flex-wrap:wrap;gap:6px}.dt-card-tags{display:flex;flex-wrap:wrap;gap:4px}.dt-card-details{display:flex;flex-direction:column;gap:5px}.dt-card-detail-row{display:flex;justify-content:space-between;align-items:baseline;gap:8px;font-size:.8125rem}.dt-card-detail-label{color:#64748b;flex-shrink:0}.dt-card-detail-value{color:#334155;font-weight:500;text-align:right;min-width:0;overflow-wrap:anywhere;word-break:break-word}.dt-card-sk{gap:12px}.dt-card-sk-header{display:flex;align-items:center;gap:10px}.dt-card-sk-badges{display:flex;gap:6px}.dt-card-sk-rows{display:flex;flex-direction:column;gap:8px}@media(prefers-reduced-motion:reduce){.dt-sk-shimmer:after,.dt-sk-cell:after{animation:none;transform:none;opacity:0}.dt-tag-tooltip{animation:none}.dt-sort-icon{transition:none}}\n"]
15807
+ styles: [":host{display:flex;flex-direction:column;flex:1;min-height:0}.dt-host{display:flex;flex-direction:column;height:100%;min-height:0}.dt-header{display:flex;align-items:center;gap:12px;margin-bottom:16px;flex-wrap:wrap;justify-content:space-between;position:relative;z-index:10}.dt-header-left{display:flex;align-items:center;gap:10px;flex-wrap:wrap;flex:1;min-width:0}.dt-header-right{display:flex;align-items:center;gap:8px;flex-shrink:0;flex-wrap:wrap;justify-content:flex-end}.dt-title{margin:0;font-size:.8125rem;font-weight:700;letter-spacing:.06em;text-transform:uppercase;color:#64748b;overflow-wrap:anywhere}.dt-sk-shimmer{position:relative;overflow:hidden;background:#f1f5f9}.dt-sk-shimmer:after{content:\"\";position:absolute;inset:0;background:linear-gradient(90deg,transparent 25%,rgba(255,255,255,.65) 50%,transparent 75%);transform:translate(-100%);animation:dt-shimmer 1.4s ease-in-out infinite}@keyframes dt-shimmer{to{transform:translate(200%)}}.dt-sk-toolbar{display:flex;align-items:center;justify-content:space-between;gap:12px;margin-bottom:16px}.dt-sk-toolbar-left{display:flex;align-items:center;gap:10px;flex-wrap:wrap}.dt-sk-toolbar-right{display:flex;align-items:center;gap:8px;flex-shrink:0}.dt-sk-search{display:flex;align-items:center;gap:10px;width:380px;height:36px;padding:0 12px;border:1px solid #e2e8f0;border-radius:6px;background:#f8fafc;box-sizing:border-box}.dt-sk-search-icon{width:16px;height:16px;border-radius:50%;flex-shrink:0}.dt-sk-search-text{flex:1;height:11px;border-radius:4px}.dt-sk-tab-strip{display:flex;gap:2px;padding:3px;background:#f1f5f9;border-radius:8px}.dt-sk-tab{height:28px;width:70px;border-radius:6px}.dt-sk-icon-btn{width:32px;height:32px;border-radius:6px}.dt-skeleton{border:1px solid #e2e8f0;border-radius:10px;overflow:hidden}.dt-sk-header{display:flex;gap:24px;padding:12px 16px;background:#f8fafc;border-bottom:1px solid #e2e8f0}.dt-sk-row{display:flex;gap:24px;padding:13px 16px;border-bottom:1px solid #f1f5f9}.dt-sk-row:last-child{border-bottom:none}.dt-sk-cell{flex:1;height:13px;border-radius:4px;position:relative;overflow:hidden;background:#f1f5f9}.dt-sk-cell:first-child{max-width:100px}.dt-sk-cell:after{content:\"\";position:absolute;inset:0;background:linear-gradient(90deg,transparent 25%,rgba(255,255,255,.65) 50%,transparent 75%);transform:translate(-100%);animation:dt-shimmer 1.4s ease-in-out infinite}.dt-sk-head{height:10px}.dt-table-wrap{flex:1;min-height:0;overflow:auto;border:1px solid #e2e8f0;border-radius:10px 10px 0 0}.dt-sk-reload-row td{padding:10px 14px;border-bottom:1px solid #f1f5f9}table{width:100%;border-collapse:collapse;font-size:.875rem}thead tr{background:#f8fafc;border-bottom:1px solid #e2e8f0}thead{position:sticky;top:0;z-index:2}th{padding:10px 14px;font-size:.75rem;font-weight:600;color:#64748b;text-transform:uppercase;letter-spacing:.04em;white-space:nowrap;border-right:1px solid #e2e8f0;text-align:center;background:#f8fafc}th:last-child{border-right:none}th.dt-th-sorted{background:#f1f5f9}th.dt-th-actions{width:48px}.dt-th-inner{display:flex;align-items:center;justify-content:center;gap:4px}.dt-sort-btn{display:inline-flex;align-items:center;gap:4px;background:none;border:none;cursor:pointer;font-size:inherit;font-weight:inherit;color:inherit;font-family:inherit;padding:0;text-transform:inherit;letter-spacing:inherit}.dt-sort-btn:hover{color:#1e293b}.dt-sort-btn:focus-visible{outline:2px solid #60a5fa;outline-offset:2px;border-radius:2px}@media(pointer:coarse){.dt-sort-btn{position:relative}.dt-sort-btn:after{content:\"\";position:absolute;left:-4px;right:-4px;top:50%;height:44px;transform:translateY(-50%)}}.dt-sort-icon{transition:transform .15s}.dt-sort-desc{transform:rotate(180deg)}.dt-sort-inactive{opacity:.4}tbody tr{border-bottom:1px solid #f1f5f9;background:#fff;transition:background .1s}tbody tr:last-child{border-bottom:none}tbody tr:hover{background:#f8fafc}tfoot tr{background:#f8fafc;border-top:2px solid #e2e8f0}tfoot th.dt-foot-label{padding:10px 14px;font-size:.875rem;font-weight:700;color:#1e293b;text-transform:none;letter-spacing:normal;background:#f8fafc;border-right:1px solid #f1f5f9;white-space:nowrap}tfoot td{padding:10px 14px;font-weight:700;color:#1e293b;background:#f8fafc}.dt-card-totals{background:#f8fafc;font-weight:600}.dt-row-clickable{cursor:pointer}.dt-row-clickable:focus-visible{outline:2px solid #3b82f6;outline-offset:-2px}td{padding:10px 14px;color:#334155;vertical-align:middle;white-space:nowrap;border-right:1px solid #f1f5f9}td:last-child{border-right:none}.dt-td-actions{text-align:center;padding:6px 8px}.dt-sticky-actions th.dt-th-actions,.dt-sticky-actions td.dt-td-actions{position:sticky;right:0;box-shadow:-1px 0 #e2e8f0}.dt-sticky-actions th.dt-th-actions{z-index:3;background:#f8fafc}.dt-sticky-actions td.dt-td-actions{z-index:1;background:#fff}.dt-sticky-actions td.dt-td-actions:focus-within,.dt-sticky-actions td.dt-td-actions:has(.mm-dropdown){z-index:2}.dt-sticky-actions tbody tr:hover td.dt-td-actions{background:#f8fafc}.dt-sticky-actions tbody tr.dt-row-selected td.dt-td-actions{background:#eff6ff}.dt-sticky-actions tbody tr.dt-row-selected:hover td.dt-td-actions{background:#dbeafe}.dt-td-width{overflow:hidden;text-overflow:ellipsis}.dt-img{display:inline-block;vertical-align:middle;object-fit:cover;border:1px solid #e2e8f0;background:#f1f5f9;flex-shrink:0}.dt-img-ph{display:inline-flex;align-items:center;justify-content:center;vertical-align:middle;color:#94a3b8;background:#f1f5f9;border:1px solid #e2e8f0;flex-shrink:0}.dt-img-ph svg{width:55%;height:55%}.dt-img-circle-md{width:40px;height:40px;border-radius:50%}.dt-img-circle-sm{width:28px;height:28px;border-radius:50%}.dt-img-rounded-md{width:48px;height:32px;border-radius:6px}.dt-img-rounded-sm{width:36px;height:24px;border-radius:5px}.dt-avatar-name{display:flex;align-items:center;gap:8px}.dt-name-text{color:#1e293b}.dt-overdue{color:#dc2626;font-weight:500}.dt-none{color:#64748b}.dt-link{position:relative;display:inline-block;max-width:100%;padding:1px 2px;vertical-align:bottom;overflow:hidden;text-overflow:ellipsis;white-space:nowrap;color:#2563eb;text-decoration:none;border-radius:3px;cursor:pointer}.dt-link:hover{text-decoration:underline;color:#1d4ed8}.dt-link:focus-visible{outline:2px solid #3b82f6;outline-offset:-2px;text-decoration:underline}.dt-card-detail-value .dt-link,.dt-card-name .dt-link{white-space:normal;overflow-wrap:anywhere}.dt-sr-only{position:absolute;width:1px;height:1px;margin:-1px;padding:0;overflow:hidden;clip:rect(0,0,0,0);white-space:nowrap;border:0}.dt-tags{display:flex;align-items:center;gap:4px}.dt-tags-more{font-size:.75rem;font-weight:600;color:#475569;background:#f1f5f9;border-radius:999px;padding:2px 7px;cursor:default;-webkit-user-select:none;user-select:none;border:1px solid #e2e8f0}.dt-tags-more:focus-visible{outline:2px solid #60a5fa;outline-offset:2px;border-radius:999px}.dt-tag-tooltip{position:fixed;z-index:9999;pointer-events:none;background:#1e293b;border-radius:10px;padding:8px 10px;display:flex;flex-direction:column;gap:5px;box-shadow:0 4px 6px #0000000f,0 10px 24px #00000024;transform:translate(-50%) translateY(-100%);animation:dt-tip-in .12s ease;max-width:220px}@keyframes dt-tip-in{0%{opacity:0;transform:translate(-50%) translateY(calc(-100% + 4px))}to{opacity:1;transform:translate(-50%) translateY(-100%)}}.dt-cell-star{margin-right:6px}.dt-cell-icon{flex-shrink:0;display:inline-block;margin-right:6px;vertical-align:-3px;color:#64748b}.dt-actions-cell{display:flex;align-items:center;justify-content:center}.dt-bulk-bar{display:flex;align-items:center;gap:10px;flex-wrap:wrap;align-self:flex-start;padding:10px 14px;margin-bottom:8px;background:#eff6ff;border:1px solid #bfdbfe;border-radius:8px}.dt-bulk-count{font-size:.875rem;font-weight:600;color:#1e40af;white-space:nowrap;flex-shrink:0}.dt-bulk-actions{display:flex;align-items:center;gap:8px;flex-wrap:wrap;flex:1;min-width:0}.dt-bulk-actions ui-select{max-width:180px;min-width:120px}.dt-bulk-hint{font-size:.8125rem;line-height:1.35;color:#475569}.dt-card-cb{display:flex;align-items:center;padding:0 0 6px}.dt-card-selected{background:#eff6ff!important;border-color:#bfdbfe!important}.dt-th-cb{width:44px;padding:0 10px!important;text-align:center!important;border-right:1px solid #e2e8f0;background:#f8fafc}.dt-td-cb{width:44px;padding:0 10px!important;text-align:center!important;border-right:1px solid #f1f5f9}.dt-th-grip{width:36px;padding:0!important;border-right:1px solid #e2e8f0;background:#f8fafc}.dt-td-grip{width:36px;padding:0!important;text-align:center!important;border-right:1px solid #f1f5f9}.dt-grip{display:inline-flex;align-items:center;justify-content:center;width:28px;height:28px;border-radius:6px;color:#64748b;cursor:grab;-webkit-user-select:none;user-select:none;touch-action:none}.dt-grip:hover{background:#f1f5f9;color:#334155}.dt-grip:active{cursor:grabbing}.dt-grip:focus-visible{outline:2px solid #3b82f6;outline-offset:1px}.dt-grip-off{color:#cbd5e1;cursor:not-allowed}.dt-grip-off:hover{background:none;color:#cbd5e1}.dt-row-move{display:none}@media(pointer:coarse){.dt-grip{display:none}.dt-row-move{display:inline-flex;flex-direction:column;align-items:center}.dt-th-grip,.dt-td-grip{width:56px}}.dt-row-dragging{opacity:.45}.dt-row-over-before>td{box-shadow:inset 0 2px #3b82f6}.dt-row-over-after>td{box-shadow:inset 0 -2px #3b82f6}.dt-card-move{display:inline-flex;align-items:center;gap:2px;flex-shrink:0}@media(forced-colors:active){.dt-row-over-before>td{box-shadow:inset 0 2px 0 Highlight}.dt-row-over-after>td{box-shadow:inset 0 -2px 0 Highlight}.dt-grip:focus-visible{outline-color:Highlight}}.dt-row-selected{background:#eff6ff!important}.dt-row-selected:hover{background:#dbeafe!important}.dt-state-cell{padding:0!important;border:none!important;background:#fff!important}@media(max-width:1024px){th{padding:10px 12px}td{padding:11px 12px}.dt-sort-btn{padding:4px 0}.dt-td-actions{padding:6px}.dt-bulk-bar{align-self:stretch}}@media(max-width:820px){.dt-header-left{flex-basis:100%}.dt-header-right{flex-basis:100%;justify-content:flex-start}}@media(max-width:768px){th{padding:9px 10px;font-size:.8125rem}td{padding:10px;font-size:.8125rem}.dt-sk-search{width:100%}}@media(max-width:640px){.dt-header{flex-direction:column;flex-wrap:nowrap;flex-shrink:0;align-items:stretch}.dt-header-left,.dt-header-right{width:100%;flex-basis:auto}.dt-table-wrap{display:none}.dt-sk-search{width:100%}.dt-sk-toolbar{flex-direction:column;align-items:stretch;gap:8px}.dt-sk-toolbar-right{align-self:flex-end}.dt-bulk-bar{align-self:stretch;padding:10px 12px;row-gap:8px}.dt-bulk-count{flex:1 1 100%}.dt-bulk-actions{flex:1 1 auto;width:auto}.dt-bulk-hint{flex-basis:100%}.dt-bulk-actions ui-select{max-width:100%;flex:1}}.dt-confirm-msg{margin:0;font-size:.9375rem;color:#334155;line-height:1.5;overflow-wrap:anywhere;word-break:break-word;white-space:pre-line}.dt-confirm-details{margin:10px 0 0;padding-left:20px;font-size:.875rem;color:#64748b;line-height:1.5;overflow-wrap:anywhere;word-break:break-word}.dt-confirm-details li+li{margin-top:4px}ui-pagination{flex-shrink:0;--ui-pagination-bg: #f8fafc}.dt-phone-controls{display:flex;flex-direction:column;gap:8px;margin-bottom:8px;flex-shrink:0}.dt-phone-sort{display:flex;align-items:center;gap:8px}.dt-phone-sort-label{font-size:.8125rem;font-weight:600;color:#475569;flex-shrink:0}.dt-phone-sort-select{flex:1;min-width:0;min-height:44px;box-sizing:border-box;padding:0 36px 0 12px;font-family:inherit;font-size:1rem;color:#1e293b;border:1px solid #7c8ba1;border-radius:8px;-webkit-appearance:none;appearance:none;background:#fff url(\"data:image/svg+xml,%3Csvg xmlns='http://www.w3.org/2000/svg' width='12' height='8' viewBox='0 0 12 8' fill='none' stroke='%2394a3b8' stroke-width='2' stroke-linecap='round' stroke-linejoin='round'%3E%3Cpath d='M1 1.5l5 5 5-5'/%3E%3C/svg%3E\") no-repeat right 12px center}.dt-phone-filters{display:flex;flex-wrap:wrap;gap:8px}.dt-card-list{display:none;flex-direction:column;gap:8px;flex:1;min-height:0;overflow-y:auto}@media(max-width:640px){.dt-card-list{display:flex;padding-bottom:8px}}.dt-card{background:#fff;border:1px solid #e2e8f0;border-radius:10px;contain:layout style;padding:14px 16px;display:flex;flex-direction:column;gap:10px;transition:background .1s}.dt-card:has(.mm-dropdown){position:relative;z-index:1}.dt-card-clickable{cursor:pointer}.dt-card-clickable:active{background:#f8fafc}.dt-card-clickable:focus-visible{outline:2px solid #3b82f6;outline-offset:2px}.dt-card-header{display:flex;align-items:center;gap:10px}.dt-card-title{display:flex;align-items:center;gap:10px;flex:1;min-width:0}.dt-card-name{min-width:0;font-weight:600;color:#1e293b;font-size:.9375rem;overflow:hidden;text-overflow:ellipsis;overflow-wrap:anywhere;display:-webkit-box;-webkit-box-orient:vertical;-webkit-line-clamp:3;line-clamp:3}.dt-card-name-plain{flex:1}.dt-card-actions{margin-left:auto;flex-shrink:0}.dt-card-badges{display:flex;flex-wrap:wrap;gap:6px}.dt-card-tags{display:flex;flex-wrap:wrap;gap:4px}.dt-card-details{display:flex;flex-direction:column;gap:5px}.dt-card-detail-row{display:flex;justify-content:space-between;align-items:baseline;gap:8px;font-size:.8125rem}.dt-card-detail-label{color:#64748b;flex-shrink:0}.dt-card-detail-value{color:#334155;font-weight:500;text-align:right;min-width:0;overflow-wrap:anywhere;word-break:break-word}.dt-card-sk{gap:12px}.dt-card-sk-header{display:flex;align-items:center;gap:10px}.dt-card-sk-badges{display:flex;gap:6px}.dt-card-sk-rows{display:flex;flex-direction:column;gap:8px}@media(prefers-reduced-motion:reduce){.dt-sk-shimmer:after,.dt-sk-cell:after{animation:none;transform:none;opacity:0}.dt-tag-tooltip{animation:none}.dt-sort-icon{transition:none}}\n"]
15531
15808
  }]
15532
15809
  }],
15533
15810
  ctorParameters: () => [],
@@ -15676,6 +15953,22 @@ i0.ɵɵngDeclareClassMetadata({
15676
15953
  required: false
15677
15954
  }]
15678
15955
  }],
15956
+ totalsEndpoint: [{
15957
+ type: i0.Input,
15958
+ args: [{
15959
+ isSignal: true,
15960
+ alias: "totalsEndpoint",
15961
+ required: false
15962
+ }]
15963
+ }],
15964
+ totalsLabel: [{
15965
+ type: i0.Input,
15966
+ args: [{
15967
+ isSignal: true,
15968
+ alias: "totalsLabel",
15969
+ required: false
15970
+ }]
15971
+ }],
15679
15972
  params: [{
15680
15973
  type: i0.Input,
15681
15974
  args: [{
@@ -16402,6 +16695,201 @@ i0.ɵɵngDeclareClassMetadata({
16402
16695
  }]
16403
16696
  }
16404
16697
  });
16698
+ const MIN_VISIBLE_PERCENT = 2;
16699
+ const ROTATION = [
16700
+ "blue",
16701
+ "green",
16702
+ "amber",
16703
+ "orange",
16704
+ "red",
16705
+ "slate"
16706
+ ];
16707
+ var StackedBarComponent = class StackedBarComponent {
16708
+ constructor() {
16709
+ this.segments = input([], ...ngDevMode ? [{ debugName: "segments" }] : /* istanbul ignore next */ []);
16710
+ this.ariaLabel = input("", ...ngDevMode ? [{ debugName: "ariaLabel" }] : /* istanbul ignore next */ []);
16711
+ this.height = input(14, ...ngDevMode ? [{ debugName: "height" }] : /* istanbul ignore next */ []);
16712
+ this.showLegend = input(true, ...ngDevMode ? [{ debugName: "showLegend" }] : /* istanbul ignore next */ []);
16713
+ this.formatValue = input((v) => v.toLocaleString("en-US"), ...ngDevMode ? [{ debugName: "formatValue" }] : /* istanbul ignore next */ []);
16714
+ this.rows = computed(() => {
16715
+ const segs = this.segments().map((s, i) => ({
16716
+ key: `${i}-${s.label}`,
16717
+ label: s.label,
16718
+ color: s.color ?? "",
16719
+ variant: s.variant ?? ROTATION[i % ROTATION.length],
16720
+ value: Number.isFinite(s.value) && s.value > 0 ? s.value : 0
16721
+ }));
16722
+ const total = segs.reduce((n, s) => n + s.value, 0);
16723
+ const format = this.formatValue();
16724
+ return segs.map((s) => {
16725
+ const exact = total > 0 ? s.value / total * 100 : 0;
16726
+ const percent = s.value > 0 ? Math.max(Math.round(exact), MIN_VISIBLE_PERCENT) : 0;
16727
+ const share = Math.round(exact);
16728
+ const text = `${format(s.value)} (${share}%)`;
16729
+ return {
16730
+ ...s,
16731
+ percent,
16732
+ text,
16733
+ title: `${s.label}: ${text}`
16734
+ };
16735
+ });
16736
+ }, ...ngDevMode ? [{ debugName: "rows" }] : /* istanbul ignore next */ []);
16737
+ this.drawn = computed(() => this.rows().filter((r) => r.percent > 0), ...ngDevMode ? [{ debugName: "drawn" }] : /* istanbul ignore next */ []);
16738
+ }
16739
+ static {
16740
+ this.ɵfac = i0.ɵɵngDeclareFactory({
16741
+ minVersion: "12.0.0",
16742
+ version: "22.2.2",
16743
+ ngImport: i0,
16744
+ type: StackedBarComponent,
16745
+ deps: [],
16746
+ target: i0.ɵɵFactoryTarget.Component
16747
+ });
16748
+ }
16749
+ static {
16750
+ this.ɵcmp = i0.ɵɵngDeclareComponent({
16751
+ minVersion: "17.0.0",
16752
+ version: "22.2.2",
16753
+ type: StackedBarComponent,
16754
+ isStandalone: true,
16755
+ selector: "ui-stacked-bar",
16756
+ inputs: {
16757
+ segments: {
16758
+ classPropertyName: "segments",
16759
+ publicName: "segments",
16760
+ isSignal: true,
16761
+ isRequired: false,
16762
+ transformFunction: null
16763
+ },
16764
+ ariaLabel: {
16765
+ classPropertyName: "ariaLabel",
16766
+ publicName: "ariaLabel",
16767
+ isSignal: true,
16768
+ isRequired: false,
16769
+ transformFunction: null
16770
+ },
16771
+ height: {
16772
+ classPropertyName: "height",
16773
+ publicName: "height",
16774
+ isSignal: true,
16775
+ isRequired: false,
16776
+ transformFunction: null
16777
+ },
16778
+ showLegend: {
16779
+ classPropertyName: "showLegend",
16780
+ publicName: "showLegend",
16781
+ isSignal: true,
16782
+ isRequired: false,
16783
+ transformFunction: null
16784
+ },
16785
+ formatValue: {
16786
+ classPropertyName: "formatValue",
16787
+ publicName: "formatValue",
16788
+ isSignal: true,
16789
+ isRequired: false,
16790
+ transformFunction: null
16791
+ }
16792
+ },
16793
+ ngImport: i0,
16794
+ template: `
16795
+ <div class="sb" role="group" [attr.aria-label]="ariaLabel() || null">
16796
+ <div class="sb-track" aria-hidden="true" [style.height.px]="height()">
16797
+ @for (s of drawn(); track s.key) {
16798
+ <span [class]="'sb-seg sb-' + s.variant" [style.width.%]="s.percent" [style.background]="s.color || null" [attr.title]="s.title"></span>
16799
+ }
16800
+ </div>
16801
+ <ul class="sb-legend" role="list" [class.sb-sr]="!showLegend()">
16802
+ @for (s of rows(); track s.key) {
16803
+ <li class="sb-item">
16804
+ <span [class]="'sb-dot sb-' + s.variant" [style.background]="s.color || null" aria-hidden="true"></span>
16805
+ <span class="sb-name">{{ s.label }}</span>
16806
+ <span class="sb-val">{{ s.text }}</span>
16807
+ </li>
16808
+ }
16809
+ </ul>
16810
+ </div>
16811
+ `,
16812
+ isInline: true,
16813
+ styles: [":host{display:block}.sb{position:relative}.sb-track{display:flex;width:100%;background:#e2e8f0;border-radius:7px;overflow:hidden}.sb-seg{display:block;height:100%;min-width:0}.sb-seg+.sb-seg{border-left:1px solid #fff}.sb-blue{background:var(--ui-progress-fill, var(--ui-accent, #3b82f6))}.sb-green{background:#16a34a}.sb-amber{background:#f59e0b}.sb-orange{background:#f97316}.sb-red{background:#ef4444}.sb-slate{background:#94a3b8}.sb-legend{list-style:none;margin:10px 0 0;padding:0;display:flex;flex-wrap:wrap;gap:6px 18px}.sb-item{display:inline-flex;align-items:center;gap:6px;font-size:.8125rem;color:#334155}.sb-dot{width:10px;height:10px;border-radius:50%;flex:none}.sb-val{font-weight:600;color:#0f172a}.sb-sr{position:absolute;width:1px;height:1px;margin:-1px;padding:0;overflow:hidden;clip:rect(0,0,0,0);white-space:nowrap;border:0}@media(forced-colors:active){.sb-track{background:Canvas;border:1px solid CanvasText}.sb-seg{background:Highlight;forced-color-adjust:none;border-left:1px solid CanvasText}}\n"],
16814
+ changeDetection: i0.ChangeDetectionStrategy.OnPush
16815
+ });
16816
+ }
16817
+ };
16818
+ i0.ɵɵngDeclareClassMetadata({
16819
+ minVersion: "12.0.0",
16820
+ version: "22.2.2",
16821
+ ngImport: i0,
16822
+ type: StackedBarComponent,
16823
+ decorators: [{
16824
+ type: Component,
16825
+ args: [{
16826
+ selector: "ui-stacked-bar",
16827
+ standalone: true,
16828
+ changeDetection: ChangeDetectionStrategy.OnPush,
16829
+ template: `
16830
+ <div class="sb" role="group" [attr.aria-label]="ariaLabel() || null">
16831
+ <div class="sb-track" aria-hidden="true" [style.height.px]="height()">
16832
+ @for (s of drawn(); track s.key) {
16833
+ <span [class]="'sb-seg sb-' + s.variant" [style.width.%]="s.percent" [style.background]="s.color || null" [attr.title]="s.title"></span>
16834
+ }
16835
+ </div>
16836
+ <ul class="sb-legend" role="list" [class.sb-sr]="!showLegend()">
16837
+ @for (s of rows(); track s.key) {
16838
+ <li class="sb-item">
16839
+ <span [class]="'sb-dot sb-' + s.variant" [style.background]="s.color || null" aria-hidden="true"></span>
16840
+ <span class="sb-name">{{ s.label }}</span>
16841
+ <span class="sb-val">{{ s.text }}</span>
16842
+ </li>
16843
+ }
16844
+ </ul>
16845
+ </div>
16846
+ `,
16847
+ styles: [":host{display:block}.sb{position:relative}.sb-track{display:flex;width:100%;background:#e2e8f0;border-radius:7px;overflow:hidden}.sb-seg{display:block;height:100%;min-width:0}.sb-seg+.sb-seg{border-left:1px solid #fff}.sb-blue{background:var(--ui-progress-fill, var(--ui-accent, #3b82f6))}.sb-green{background:#16a34a}.sb-amber{background:#f59e0b}.sb-orange{background:#f97316}.sb-red{background:#ef4444}.sb-slate{background:#94a3b8}.sb-legend{list-style:none;margin:10px 0 0;padding:0;display:flex;flex-wrap:wrap;gap:6px 18px}.sb-item{display:inline-flex;align-items:center;gap:6px;font-size:.8125rem;color:#334155}.sb-dot{width:10px;height:10px;border-radius:50%;flex:none}.sb-val{font-weight:600;color:#0f172a}.sb-sr{position:absolute;width:1px;height:1px;margin:-1px;padding:0;overflow:hidden;clip:rect(0,0,0,0);white-space:nowrap;border:0}@media(forced-colors:active){.sb-track{background:Canvas;border:1px solid CanvasText}.sb-seg{background:Highlight;forced-color-adjust:none;border-left:1px solid CanvasText}}\n"]
16848
+ }]
16849
+ }],
16850
+ propDecorators: {
16851
+ segments: [{
16852
+ type: i0.Input,
16853
+ args: [{
16854
+ isSignal: true,
16855
+ alias: "segments",
16856
+ required: false
16857
+ }]
16858
+ }],
16859
+ ariaLabel: [{
16860
+ type: i0.Input,
16861
+ args: [{
16862
+ isSignal: true,
16863
+ alias: "ariaLabel",
16864
+ required: false
16865
+ }]
16866
+ }],
16867
+ height: [{
16868
+ type: i0.Input,
16869
+ args: [{
16870
+ isSignal: true,
16871
+ alias: "height",
16872
+ required: false
16873
+ }]
16874
+ }],
16875
+ showLegend: [{
16876
+ type: i0.Input,
16877
+ args: [{
16878
+ isSignal: true,
16879
+ alias: "showLegend",
16880
+ required: false
16881
+ }]
16882
+ }],
16883
+ formatValue: [{
16884
+ type: i0.Input,
16885
+ args: [{
16886
+ isSignal: true,
16887
+ alias: "formatValue",
16888
+ required: false
16889
+ }]
16890
+ }]
16891
+ }
16892
+ });
16405
16893
  var ProgressRingComponent = class ProgressRingComponent {
16406
16894
  constructor() {
16407
16895
  this.value = input(0, ...ngDevMode ? [{ debugName: "value" }] : /* istanbul ignore next */ []);
@@ -16805,6 +17293,493 @@ i0.ɵɵngDeclareClassMetadata({
16805
17293
  }]
16806
17294
  }
16807
17295
  });
17296
+ var StarRatingComponent = class StarRatingComponent {
17297
+ get _name() {
17298
+ return this.name() || this._generatedName;
17299
+ }
17300
+ constructor() {
17301
+ this.max = input(5, ...ngDevMode ? [{ debugName: "max" }] : /* istanbul ignore next */ []);
17302
+ this.value = input(0, ...ngDevMode ? [{ debugName: "value" }] : /* istanbul ignore next */ []);
17303
+ this.label = input("", ...ngDevMode ? [{ debugName: "label" }] : /* istanbul ignore next */ []);
17304
+ this.ariaLabel = input("", ...ngDevMode ? [{ debugName: "ariaLabel" }] : /* istanbul ignore next */ []);
17305
+ this.hint = input("", ...ngDevMode ? [{ debugName: "hint" }] : /* istanbul ignore next */ []);
17306
+ this.error = input("", ...ngDevMode ? [{ debugName: "error" }] : /* istanbul ignore next */ []);
17307
+ this.required = input(false, ...ngDevMode ? [{ debugName: "required" }] : /* istanbul ignore next */ []);
17308
+ this.showErrors = input(false, ...ngDevMode ? [{ debugName: "showErrors" }] : /* istanbul ignore next */ []);
17309
+ this.size = input(24, ...ngDevMode ? [{ debugName: "size" }] : /* istanbul ignore next */ []);
17310
+ this.readonly = input(false, ...ngDevMode ? [{ debugName: "readonly" }] : /* istanbul ignore next */ []);
17311
+ this.name = input("", ...ngDevMode ? [{ debugName: "name" }] : /* istanbul ignore next */ []);
17312
+ this._disabledInput = input(false, {
17313
+ ...ngDevMode ? { debugName: "_disabledInput" } : /* istanbul ignore next */ {},
17314
+ alias: "disabled"
17315
+ });
17316
+ this._cvaDisabled = signal(false, ...ngDevMode ? [{ debugName: "_cvaDisabled" }] : /* istanbul ignore next */ []);
17317
+ this.disabled = computed(() => this._disabledInput() || this._cvaDisabled(), ...ngDevMode ? [{ debugName: "disabled" }] : /* istanbul ignore next */ []);
17318
+ this.valueChange = output();
17319
+ this.invalidChange = output();
17320
+ this._value = linkedSignal(() => StarRatingComponent._norm(this.value()), ...ngDevMode ? [{ debugName: "_value" }] : /* istanbul ignore next */ []);
17321
+ this._max = computed(() => {
17322
+ const m = Math.floor(Number(this.max()));
17323
+ return Number.isFinite(m) && m >= 1 ? m : 1;
17324
+ }, ...ngDevMode ? [{ debugName: "_max" }] : /* istanbul ignore next */ []);
17325
+ this._stars = computed(() => Array.from({ length: this._max() }, (_, i) => i + 1), ...ngDevMode ? [{ debugName: "_stars" }] : /* istanbul ignore next */ []);
17326
+ this._shown = computed(() => Math.min(Math.max(Math.floor(this._value()), 0), this._max()), ...ngDevMode ? [{ debugName: "_shown" }] : /* istanbul ignore next */ []);
17327
+ this._readonlyText = computed(() => {
17328
+ const n = this._shown();
17329
+ const text = n === 0 ? "No rating" : `${n} ${n === 1 ? "star" : "stars"} out of ${this._max()}`;
17330
+ return this.label() ? `${this.label()}: ${text}` : text;
17331
+ }, ...ngDevMode ? [{ debugName: "_readonlyText" }] : /* istanbul ignore next */ []);
17332
+ this._path = "M10 1.5l2.6 5.3 5.9.9-4.25 4.15 1 5.85L10 14.9l-5.25 2.8 1-5.85L1.5 7.7l5.9-.9L10 1.5z";
17333
+ this._generatedName = `sr-${Math.random().toString(36).slice(2, 8)}`;
17334
+ this._descId = `${this._generatedName}-desc`;
17335
+ this._host = inject(ElementRef);
17336
+ this._reveal = createFieldReveal(this.showErrors);
17337
+ this._issue = computed(() => this._check(this._value()), ...ngDevMode ? [{ debugName: "_issue" }] : /* istanbul ignore next */ []);
17338
+ this.invalid = computed(() => !!this.error() || !!this._issue(), ...ngDevMode ? [{ debugName: "invalid" }] : /* istanbul ignore next */ []);
17339
+ this.errorMessage = computed(() => this._issue()?.message ?? "", ...ngDevMode ? [{ debugName: "errorMessage" }] : /* istanbul ignore next */ []);
17340
+ this._activeError = computed(() => this.error() || (this._reveal.revealed() ? this.errorMessage() : ""), ...ngDevMode ? [{ debugName: "_activeError" }] : /* istanbul ignore next */ []);
17341
+ this._onValidatorChange = () => {};
17342
+ this._onChange = (_) => {};
17343
+ this._onTouched = () => {};
17344
+ effect(() => {
17345
+ this.invalidChange.emit(this.invalid());
17346
+ });
17347
+ }
17348
+ ngOnChanges() {
17349
+ this._onValidatorChange();
17350
+ }
17351
+ validate(control) {
17352
+ return issueToErrors(this._check(StarRatingComponent._norm(control.value)));
17353
+ }
17354
+ registerOnValidatorChange(fn) {
17355
+ this._onValidatorChange = fn;
17356
+ }
17357
+ writeValue(val) {
17358
+ this._value.set(StarRatingComponent._norm(val));
17359
+ }
17360
+ registerOnChange(fn) {
17361
+ this._onChange = fn;
17362
+ }
17363
+ registerOnTouched(fn) {
17364
+ this._onTouched = fn;
17365
+ }
17366
+ setDisabledState(d) {
17367
+ this._cvaDisabled.set(d);
17368
+ }
17369
+ static _norm(v) {
17370
+ if (v === null || v === void 0 || v === "") return 0;
17371
+ const n = Number(v);
17372
+ return Number.isFinite(n) ? n : 0;
17373
+ }
17374
+ onSelect(n) {
17375
+ if (this.disabled()) return;
17376
+ this._value.set(n);
17377
+ this._onChange(n);
17378
+ this.valueChange.emit(n);
17379
+ }
17380
+ onKeydown(event, n) {
17381
+ if (this.disabled()) return;
17382
+ let target = null;
17383
+ if (event.key === "Enter") target = n;
17384
+ else if (event.key === "Home") target = 1;
17385
+ else if (event.key === "End") target = this._max();
17386
+ if (target === null) return;
17387
+ event.preventDefault();
17388
+ this.onSelect(target);
17389
+ this._host.nativeElement.querySelectorAll("input[type=\"radio\"]")[target - 1]?.focus();
17390
+ }
17391
+ onFocusOut(event) {
17392
+ const next = event.relatedTarget;
17393
+ if (next && event.currentTarget.contains(next)) return;
17394
+ this._onTouched();
17395
+ this._reveal.touched.set(true);
17396
+ }
17397
+ _check(value) {
17398
+ if (this.disabled() || this.readonly()) return null;
17399
+ if (value === 0) return this.required() ? requiredIssue(this.label()) : null;
17400
+ if (!Number.isInteger(value) || value < 0 || value > this._max()) return {
17401
+ key: "option",
17402
+ message: "Select a valid option."
17403
+ };
17404
+ return null;
17405
+ }
17406
+ static {
17407
+ this.ɵfac = i0.ɵɵngDeclareFactory({
17408
+ minVersion: "12.0.0",
17409
+ version: "22.2.2",
17410
+ ngImport: i0,
17411
+ type: StarRatingComponent,
17412
+ deps: [],
17413
+ target: i0.ɵɵFactoryTarget.Component
17414
+ });
17415
+ }
17416
+ static {
17417
+ this.ɵcmp = i0.ɵɵngDeclareComponent({
17418
+ minVersion: "17.0.0",
17419
+ version: "22.2.2",
17420
+ type: StarRatingComponent,
17421
+ isStandalone: true,
17422
+ selector: "ui-star-rating",
17423
+ inputs: {
17424
+ max: {
17425
+ classPropertyName: "max",
17426
+ publicName: "max",
17427
+ isSignal: true,
17428
+ isRequired: false,
17429
+ transformFunction: null
17430
+ },
17431
+ value: {
17432
+ classPropertyName: "value",
17433
+ publicName: "value",
17434
+ isSignal: true,
17435
+ isRequired: false,
17436
+ transformFunction: null
17437
+ },
17438
+ label: {
17439
+ classPropertyName: "label",
17440
+ publicName: "label",
17441
+ isSignal: true,
17442
+ isRequired: false,
17443
+ transformFunction: null
17444
+ },
17445
+ ariaLabel: {
17446
+ classPropertyName: "ariaLabel",
17447
+ publicName: "ariaLabel",
17448
+ isSignal: true,
17449
+ isRequired: false,
17450
+ transformFunction: null
17451
+ },
17452
+ hint: {
17453
+ classPropertyName: "hint",
17454
+ publicName: "hint",
17455
+ isSignal: true,
17456
+ isRequired: false,
17457
+ transformFunction: null
17458
+ },
17459
+ error: {
17460
+ classPropertyName: "error",
17461
+ publicName: "error",
17462
+ isSignal: true,
17463
+ isRequired: false,
17464
+ transformFunction: null
17465
+ },
17466
+ required: {
17467
+ classPropertyName: "required",
17468
+ publicName: "required",
17469
+ isSignal: true,
17470
+ isRequired: false,
17471
+ transformFunction: null
17472
+ },
17473
+ showErrors: {
17474
+ classPropertyName: "showErrors",
17475
+ publicName: "showErrors",
17476
+ isSignal: true,
17477
+ isRequired: false,
17478
+ transformFunction: null
17479
+ },
17480
+ size: {
17481
+ classPropertyName: "size",
17482
+ publicName: "size",
17483
+ isSignal: true,
17484
+ isRequired: false,
17485
+ transformFunction: null
17486
+ },
17487
+ readonly: {
17488
+ classPropertyName: "readonly",
17489
+ publicName: "readonly",
17490
+ isSignal: true,
17491
+ isRequired: false,
17492
+ transformFunction: null
17493
+ },
17494
+ name: {
17495
+ classPropertyName: "name",
17496
+ publicName: "name",
17497
+ isSignal: true,
17498
+ isRequired: false,
17499
+ transformFunction: null
17500
+ },
17501
+ _disabledInput: {
17502
+ classPropertyName: "_disabledInput",
17503
+ publicName: "disabled",
17504
+ isSignal: true,
17505
+ isRequired: false,
17506
+ transformFunction: null
17507
+ }
17508
+ },
17509
+ outputs: {
17510
+ valueChange: "valueChange",
17511
+ invalidChange: "invalidChange"
17512
+ },
17513
+ providers: [
17514
+ {
17515
+ provide: NG_VALUE_ACCESSOR,
17516
+ useExisting: forwardRef(() => StarRatingComponent),
17517
+ multi: true
17518
+ },
17519
+ {
17520
+ provide: NG_VALIDATORS,
17521
+ useExisting: forwardRef(() => StarRatingComponent),
17522
+ multi: true
17523
+ },
17524
+ {
17525
+ provide: UiFieldValidity,
17526
+ useExisting: forwardRef(() => StarRatingComponent)
17527
+ }
17528
+ ],
17529
+ usesOnChanges: true,
17530
+ ngImport: i0,
17531
+ template: `
17532
+ @if (readonly()) {
17533
+ <div class="sr-ro">
17534
+ @if (label()) { <span class="sr-label sr-label-ro" aria-hidden="true">{{ label() }}</span> }
17535
+ <span class="sr-stars" role="img" [attr.aria-label]="_readonlyText()">
17536
+ @for (n of _stars(); track n) {
17537
+ <svg class="sr-svg" [class.sr-on]="n <= _shown()" [attr.width]="size()" [attr.height]="size()" viewBox="0 0 20 20" aria-hidden="true" focusable="false"><path class="sr-shape" [attr.d]="_path" /></svg>
17538
+ }
17539
+ </span>
17540
+ </div>
17541
+ } @else {
17542
+ <fieldset
17543
+ class="sr-field"
17544
+ role="radiogroup"
17545
+ [class.sr-error]="_activeError()"
17546
+ [class.sr-disabled]="disabled()"
17547
+ [disabled]="disabled()"
17548
+ [attr.aria-label]="label() ? null : (ariaLabel() || 'Rating')"
17549
+ [attr.aria-required]="required() ? 'true' : null"
17550
+ [attr.aria-invalid]="_activeError() ? 'true' : null"
17551
+ [attr.aria-describedby]="(_activeError() || hint()) ? _descId : null"
17552
+ (focusout)="onFocusOut($event)">
17553
+ @if (label()) {
17554
+ <legend class="sr-label">
17555
+ {{ label() }}
17556
+ @if (required()) { <span class="sr-required" aria-hidden="true">*</span> }
17557
+ </legend>
17558
+ }
17559
+ <div class="sr-stars">
17560
+ @for (n of _stars(); track n) {
17561
+ <label class="sr-star" [class.sr-disabled]="disabled()">
17562
+ <input
17563
+ type="radio"
17564
+ class="sr-hidden"
17565
+ [name]="_name"
17566
+ [value]="n"
17567
+ [checked]="_value() === n"
17568
+ [disabled]="disabled()"
17569
+ [attr.aria-label]="n === 1 ? '1 star' : n + ' stars'"
17570
+ [attr.aria-invalid]="_activeError() ? 'true' : null"
17571
+ (change)="onSelect(n)"
17572
+ (keydown)="onKeydown($event, n)" />
17573
+ <svg class="sr-svg" [class.sr-on]="n <= _shown()" [attr.width]="size()" [attr.height]="size()" viewBox="0 0 20 20" aria-hidden="true" focusable="false"><path class="sr-shape" [attr.d]="_path" /></svg>
17574
+ </label>
17575
+ }
17576
+ </div>
17577
+ @if (_activeError()) {
17578
+ <p class="sr-desc sr-desc-error" [id]="_descId" role="alert">{{ _activeError() }}</p>
17579
+ } @else if (hint()) {
17580
+ <p class="sr-desc" [id]="_descId">{{ hint() }}</p>
17581
+ }
17582
+ </fieldset>
17583
+ }
17584
+ `,
17585
+ isInline: true,
17586
+ styles: [":host{display:block}.sr-field{display:flex;flex-direction:column;gap:6px;border:0;margin:0;padding:0;min-width:0}.sr-label{padding:0;margin-bottom:6px;font-size:.8125rem;font-weight:600;color:#374151;line-height:1}.sr-label-ro{display:block}.sr-required{color:#dc2626;margin-left:2px}.sr-ro{display:flex;flex-direction:column}.sr-stars{display:inline-flex;flex-wrap:nowrap;align-items:center;gap:2px}.sr-star{position:relative;display:inline-flex;align-items:center;justify-content:center;cursor:pointer;border-radius:4px;-webkit-user-select:none;user-select:none;-webkit-tap-highlight-color:transparent}.sr-star.sr-disabled{cursor:not-allowed;opacity:.5}.sr-hidden{position:absolute;width:1px;height:1px;margin:-1px;padding:0;overflow:hidden;clip:rect(0,0,0,0);white-space:nowrap;border:0}.sr-hidden:focus-visible+.sr-svg{outline:2px solid #3b82f6;outline-offset:2px;border-radius:3px}.sr-svg{display:block}.sr-shape{fill:none;stroke:#7c8ba1;stroke-width:1.25;stroke-linejoin:round}.sr-on .sr-shape{fill:#f5b301;stroke:#a16207;stroke-width:.75}.sr-error .sr-svg:not(.sr-on) .sr-shape{stroke:#ef4444}.sr-field:not(.sr-disabled) .sr-star:hover .sr-shape{stroke:#a16207}@media(pointer:coarse),(max-width:480px){.sr-star{min-width:44px;min-height:44px}.sr-hidden{width:100%;height:100%;margin:0;clip:auto;overflow:visible;left:0;top:0;opacity:0;cursor:pointer;z-index:1}.sr-star.sr-disabled .sr-hidden{cursor:not-allowed}.sr-stars{gap:0}}.sr-desc{margin:0;font-size:.75rem;line-height:1.4;color:#64748b}.sr-desc-error{color:#dc2626}@media(forced-colors:active){.sr-shape{stroke:CanvasText}.sr-on .sr-shape{fill:Highlight;stroke:CanvasText}}@media(prefers-reduced-motion:no-preference){.sr-shape{transition:fill .1s,stroke .1s}}\n"],
17587
+ changeDetection: i0.ChangeDetectionStrategy.OnPush
17588
+ });
17589
+ }
17590
+ };
17591
+ i0.ɵɵngDeclareClassMetadata({
17592
+ minVersion: "12.0.0",
17593
+ version: "22.2.2",
17594
+ ngImport: i0,
17595
+ type: StarRatingComponent,
17596
+ decorators: [{
17597
+ type: Component,
17598
+ args: [{
17599
+ selector: "ui-star-rating",
17600
+ standalone: true,
17601
+ changeDetection: ChangeDetectionStrategy.OnPush,
17602
+ providers: [
17603
+ {
17604
+ provide: NG_VALUE_ACCESSOR,
17605
+ useExisting: forwardRef(() => StarRatingComponent),
17606
+ multi: true
17607
+ },
17608
+ {
17609
+ provide: NG_VALIDATORS,
17610
+ useExisting: forwardRef(() => StarRatingComponent),
17611
+ multi: true
17612
+ },
17613
+ {
17614
+ provide: UiFieldValidity,
17615
+ useExisting: forwardRef(() => StarRatingComponent)
17616
+ }
17617
+ ],
17618
+ template: `
17619
+ @if (readonly()) {
17620
+ <div class="sr-ro">
17621
+ @if (label()) { <span class="sr-label sr-label-ro" aria-hidden="true">{{ label() }}</span> }
17622
+ <span class="sr-stars" role="img" [attr.aria-label]="_readonlyText()">
17623
+ @for (n of _stars(); track n) {
17624
+ <svg class="sr-svg" [class.sr-on]="n <= _shown()" [attr.width]="size()" [attr.height]="size()" viewBox="0 0 20 20" aria-hidden="true" focusable="false"><path class="sr-shape" [attr.d]="_path" /></svg>
17625
+ }
17626
+ </span>
17627
+ </div>
17628
+ } @else {
17629
+ <fieldset
17630
+ class="sr-field"
17631
+ role="radiogroup"
17632
+ [class.sr-error]="_activeError()"
17633
+ [class.sr-disabled]="disabled()"
17634
+ [disabled]="disabled()"
17635
+ [attr.aria-label]="label() ? null : (ariaLabel() || 'Rating')"
17636
+ [attr.aria-required]="required() ? 'true' : null"
17637
+ [attr.aria-invalid]="_activeError() ? 'true' : null"
17638
+ [attr.aria-describedby]="(_activeError() || hint()) ? _descId : null"
17639
+ (focusout)="onFocusOut($event)">
17640
+ @if (label()) {
17641
+ <legend class="sr-label">
17642
+ {{ label() }}
17643
+ @if (required()) { <span class="sr-required" aria-hidden="true">*</span> }
17644
+ </legend>
17645
+ }
17646
+ <div class="sr-stars">
17647
+ @for (n of _stars(); track n) {
17648
+ <label class="sr-star" [class.sr-disabled]="disabled()">
17649
+ <input
17650
+ type="radio"
17651
+ class="sr-hidden"
17652
+ [name]="_name"
17653
+ [value]="n"
17654
+ [checked]="_value() === n"
17655
+ [disabled]="disabled()"
17656
+ [attr.aria-label]="n === 1 ? '1 star' : n + ' stars'"
17657
+ [attr.aria-invalid]="_activeError() ? 'true' : null"
17658
+ (change)="onSelect(n)"
17659
+ (keydown)="onKeydown($event, n)" />
17660
+ <svg class="sr-svg" [class.sr-on]="n <= _shown()" [attr.width]="size()" [attr.height]="size()" viewBox="0 0 20 20" aria-hidden="true" focusable="false"><path class="sr-shape" [attr.d]="_path" /></svg>
17661
+ </label>
17662
+ }
17663
+ </div>
17664
+ @if (_activeError()) {
17665
+ <p class="sr-desc sr-desc-error" [id]="_descId" role="alert">{{ _activeError() }}</p>
17666
+ } @else if (hint()) {
17667
+ <p class="sr-desc" [id]="_descId">{{ hint() }}</p>
17668
+ }
17669
+ </fieldset>
17670
+ }
17671
+ `,
17672
+ styles: [":host{display:block}.sr-field{display:flex;flex-direction:column;gap:6px;border:0;margin:0;padding:0;min-width:0}.sr-label{padding:0;margin-bottom:6px;font-size:.8125rem;font-weight:600;color:#374151;line-height:1}.sr-label-ro{display:block}.sr-required{color:#dc2626;margin-left:2px}.sr-ro{display:flex;flex-direction:column}.sr-stars{display:inline-flex;flex-wrap:nowrap;align-items:center;gap:2px}.sr-star{position:relative;display:inline-flex;align-items:center;justify-content:center;cursor:pointer;border-radius:4px;-webkit-user-select:none;user-select:none;-webkit-tap-highlight-color:transparent}.sr-star.sr-disabled{cursor:not-allowed;opacity:.5}.sr-hidden{position:absolute;width:1px;height:1px;margin:-1px;padding:0;overflow:hidden;clip:rect(0,0,0,0);white-space:nowrap;border:0}.sr-hidden:focus-visible+.sr-svg{outline:2px solid #3b82f6;outline-offset:2px;border-radius:3px}.sr-svg{display:block}.sr-shape{fill:none;stroke:#7c8ba1;stroke-width:1.25;stroke-linejoin:round}.sr-on .sr-shape{fill:#f5b301;stroke:#a16207;stroke-width:.75}.sr-error .sr-svg:not(.sr-on) .sr-shape{stroke:#ef4444}.sr-field:not(.sr-disabled) .sr-star:hover .sr-shape{stroke:#a16207}@media(pointer:coarse),(max-width:480px){.sr-star{min-width:44px;min-height:44px}.sr-hidden{width:100%;height:100%;margin:0;clip:auto;overflow:visible;left:0;top:0;opacity:0;cursor:pointer;z-index:1}.sr-star.sr-disabled .sr-hidden{cursor:not-allowed}.sr-stars{gap:0}}.sr-desc{margin:0;font-size:.75rem;line-height:1.4;color:#64748b}.sr-desc-error{color:#dc2626}@media(forced-colors:active){.sr-shape{stroke:CanvasText}.sr-on .sr-shape{fill:Highlight;stroke:CanvasText}}@media(prefers-reduced-motion:no-preference){.sr-shape{transition:fill .1s,stroke .1s}}\n"]
17673
+ }]
17674
+ }],
17675
+ ctorParameters: () => [],
17676
+ propDecorators: {
17677
+ max: [{
17678
+ type: i0.Input,
17679
+ args: [{
17680
+ isSignal: true,
17681
+ alias: "max",
17682
+ required: false
17683
+ }]
17684
+ }],
17685
+ value: [{
17686
+ type: i0.Input,
17687
+ args: [{
17688
+ isSignal: true,
17689
+ alias: "value",
17690
+ required: false
17691
+ }]
17692
+ }],
17693
+ label: [{
17694
+ type: i0.Input,
17695
+ args: [{
17696
+ isSignal: true,
17697
+ alias: "label",
17698
+ required: false
17699
+ }]
17700
+ }],
17701
+ ariaLabel: [{
17702
+ type: i0.Input,
17703
+ args: [{
17704
+ isSignal: true,
17705
+ alias: "ariaLabel",
17706
+ required: false
17707
+ }]
17708
+ }],
17709
+ hint: [{
17710
+ type: i0.Input,
17711
+ args: [{
17712
+ isSignal: true,
17713
+ alias: "hint",
17714
+ required: false
17715
+ }]
17716
+ }],
17717
+ error: [{
17718
+ type: i0.Input,
17719
+ args: [{
17720
+ isSignal: true,
17721
+ alias: "error",
17722
+ required: false
17723
+ }]
17724
+ }],
17725
+ required: [{
17726
+ type: i0.Input,
17727
+ args: [{
17728
+ isSignal: true,
17729
+ alias: "required",
17730
+ required: false
17731
+ }]
17732
+ }],
17733
+ showErrors: [{
17734
+ type: i0.Input,
17735
+ args: [{
17736
+ isSignal: true,
17737
+ alias: "showErrors",
17738
+ required: false
17739
+ }]
17740
+ }],
17741
+ size: [{
17742
+ type: i0.Input,
17743
+ args: [{
17744
+ isSignal: true,
17745
+ alias: "size",
17746
+ required: false
17747
+ }]
17748
+ }],
17749
+ readonly: [{
17750
+ type: i0.Input,
17751
+ args: [{
17752
+ isSignal: true,
17753
+ alias: "readonly",
17754
+ required: false
17755
+ }]
17756
+ }],
17757
+ name: [{
17758
+ type: i0.Input,
17759
+ args: [{
17760
+ isSignal: true,
17761
+ alias: "name",
17762
+ required: false
17763
+ }]
17764
+ }],
17765
+ _disabledInput: [{
17766
+ type: i0.Input,
17767
+ args: [{
17768
+ isSignal: true,
17769
+ alias: "disabled",
17770
+ required: false
17771
+ }]
17772
+ }],
17773
+ valueChange: [{
17774
+ type: i0.Output,
17775
+ args: ["valueChange"]
17776
+ }],
17777
+ invalidChange: [{
17778
+ type: i0.Output,
17779
+ args: ["invalidChange"]
17780
+ }]
17781
+ }
17782
+ });
16808
17783
  const KEY_STEP = 2;
16809
17784
  const KEY_STEP_BIG = 10;
16810
17785
  const clamp = (n) => Math.min(100, Math.max(0, Math.round(n)));
@@ -18603,6 +19578,9 @@ var RadioComponent = class RadioComponent {
18603
19578
  constructor() {
18604
19579
  this.label = input("", ...ngDevMode ? [{ debugName: "label" }] : /* istanbul ignore next */ []);
18605
19580
  this.description = input("", ...ngDevMode ? [{ debugName: "description" }] : /* istanbul ignore next */ []);
19581
+ this.linkLabel = input("", ...ngDevMode ? [{ debugName: "linkLabel" }] : /* istanbul ignore next */ []);
19582
+ this.linkUrl = input("", ...ngDevMode ? [{ debugName: "linkUrl" }] : /* istanbul ignore next */ []);
19583
+ this.linkTestId = input("", ...ngDevMode ? [{ debugName: "linkTestId" }] : /* istanbul ignore next */ []);
18606
19584
  this.icon = input("", ...ngDevMode ? [{ debugName: "icon" }] : /* istanbul ignore next */ []);
18607
19585
  this.ariaLabel = input("", ...ngDevMode ? [{ debugName: "ariaLabel" }] : /* istanbul ignore next */ []);
18608
19586
  this.testId = input("", ...ngDevMode ? [{ debugName: "testId" }] : /* istanbul ignore next */ []);
@@ -18622,10 +19600,20 @@ var RadioComponent = class RadioComponent {
18622
19600
  if (!v) return null;
18623
19601
  return iconPath(v) ?? (/^[Mm][\d\s.,\-MmLlHhVvCcSsQqTtAaZz]+$/.test(v) ? v : null);
18624
19602
  }, ...ngDevMode ? [{ debugName: "_iconD" }] : /* istanbul ignore next */ []);
19603
+ this._linkHref = computed(() => {
19604
+ const label = this.linkLabel().trim();
19605
+ const url = this.linkUrl().trim();
19606
+ if (!label || !url) return null;
19607
+ if (/[\\\u0000-\u001f\u007f]/.test(url)) return null;
19608
+ if (/^(https?:\/\/|mailto:|tel:)/i.test(url)) return url;
19609
+ if (/^(\/(?![\/\\])|#)/.test(url)) return url;
19610
+ return null;
19611
+ }, ...ngDevMode ? [{ debugName: "_linkHref" }] : /* istanbul ignore next */ []);
19612
+ this._linkNewTab = computed(() => /^https?:\/\//i.test(this._linkHref() ?? ""), ...ngDevMode ? [{ debugName: "_linkNewTab" }] : /* istanbul ignore next */ []);
18625
19613
  this.labelId = input("", ...ngDevMode ? [{ debugName: "labelId" }] : /* istanbul ignore next */ []);
18626
19614
  this._generatedLabelId = `rd-${Math.random().toString(36).slice(2, 8)}-label`;
18627
19615
  this._labelId = computed(() => this.labelId() || this._generatedLabelId, ...ngDevMode ? [{ debugName: "_labelId" }] : /* istanbul ignore next */ []);
18628
- this._labelledBy = computed(() => this.label() && this.description() && !this.ariaLabel() ? this._labelId() : null, ...ngDevMode ? [{ debugName: "_labelledBy" }] : /* istanbul ignore next */ []);
19616
+ this._labelledBy = computed(() => this.label() && (this.description() || this._linkHref()) && !this.ariaLabel() ? this._labelId() : null, ...ngDevMode ? [{ debugName: "_labelledBy" }] : /* istanbul ignore next */ []);
18629
19617
  this._descriptionId = `rd-${Math.random().toString(36).slice(2, 8)}-desc`;
18630
19618
  this._describedByIds = computed(() => {
18631
19619
  return [this.describedBy(), this.description() ? this._descriptionId : ""].filter(Boolean).join(" ") || null;
@@ -18667,6 +19655,27 @@ var RadioComponent = class RadioComponent {
18667
19655
  isRequired: false,
18668
19656
  transformFunction: null
18669
19657
  },
19658
+ linkLabel: {
19659
+ classPropertyName: "linkLabel",
19660
+ publicName: "linkLabel",
19661
+ isSignal: true,
19662
+ isRequired: false,
19663
+ transformFunction: null
19664
+ },
19665
+ linkUrl: {
19666
+ classPropertyName: "linkUrl",
19667
+ publicName: "linkUrl",
19668
+ isSignal: true,
19669
+ isRequired: false,
19670
+ transformFunction: null
19671
+ },
19672
+ linkTestId: {
19673
+ classPropertyName: "linkTestId",
19674
+ publicName: "linkTestId",
19675
+ isSignal: true,
19676
+ isRequired: false,
19677
+ transformFunction: null
19678
+ },
18670
19679
  icon: {
18671
19680
  classPropertyName: "icon",
18672
19681
  publicName: "icon",
@@ -18774,12 +19783,16 @@ var RadioComponent = class RadioComponent {
18774
19783
  <span class="rd-text">
18775
19784
  @if (label()) { <span class="rd-label" [id]="_labelId()">{{ label() }}</span> }
18776
19785
  @if (description()) { <span class="rd-description" [id]="_descriptionId">{{ description() }}</span> }
19786
+ @if (_linkHref(); as href) {
19787
+ <!-- Optional link after the description (library source 2026-11-05): a real anchor, so it is its own tab stop; clicking it follows the link and never selects the radio. -->
19788
+ <a class="rd-link" [attr.href]="href" [attr.target]="_linkNewTab() ? '_blank' : null" [attr.rel]="_linkNewTab() ? 'noopener noreferrer' : null" [attr.data-testid]="linkTestId() || null">{{ linkLabel() }}@if (_linkNewTab()) { <span class="rd-sr">(opens in a new tab)</span> }</a>
19789
+ }
18777
19790
  <ng-content />
18778
19791
  </span>
18779
19792
  </label>
18780
19793
  `,
18781
19794
  isInline: true,
18782
- styles: [":host{display:block}.rd-wrap{position:relative;display:inline-flex;align-items:flex-start;gap:9px;vertical-align:top;cursor:pointer;-webkit-user-select:none;user-select:none}.rd-wrap.rd-disabled{cursor:not-allowed;opacity:.5}.rd-hidden{position:absolute;width:1px;height:1px;margin:-1px;padding:0;overflow:hidden;clip:rect(0,0,0,0);white-space:nowrap;border:0}.rd-wrap:has(.rd-hidden:focus-visible) .rd-dot{outline:2px solid #3b82f6;outline-offset:2px}@media(pointer:coarse),(max-width:480px){.rd-wrap{position:relative}.rd-hidden{width:44px;height:44px;margin:0;clip:auto;overflow:visible;left:-12px;top:-2px;opacity:0;cursor:pointer;z-index:1}.rd-wrap.rd-disabled .rd-hidden{cursor:not-allowed}}.rd-dot{flex-shrink:0;width:20px;height:20px;box-sizing:border-box;border:2px solid #7c8ba1;border-radius:50%;background:#fff;display:flex;align-items:center;justify-content:center;transition:background .12s,border-color .12s}.rd-dot.rd-checked{background:#3b82f6;border-color:#3b82f6}.rd-dot.rd-invalid:not(.rd-checked){border-color:#ef4444}.rd-wrap:hover .rd-dot:not(.rd-checked):not(.rd-disabled){border-color:#3b82f6}.rd-core{width:8px;height:8px;border-radius:50%;background:#fff}@media(max-width:640px),(pointer:coarse){.rd-dot{position:relative}.rd-dot:after{content:\"\";position:absolute;inset:-12px}}.rd-icon{flex-shrink:0;margin-top:1px;color:#64748b}.rd-text{display:flex;flex-direction:column;gap:2px}.rd-label{font-size:.875rem;color:#334155;line-height:1.4}.rd-description{font-size:.75rem;color:#64748b;line-height:1.4}\n"],
19795
+ styles: [":host{display:block}.rd-wrap{position:relative;display:inline-flex;align-items:flex-start;gap:9px;vertical-align:top;cursor:pointer;-webkit-user-select:none;user-select:none}.rd-wrap.rd-disabled{cursor:not-allowed;opacity:.5}.rd-hidden{position:absolute;width:1px;height:1px;margin:-1px;padding:0;overflow:hidden;clip:rect(0,0,0,0);white-space:nowrap;border:0}.rd-wrap:has(.rd-hidden:focus-visible) .rd-dot{outline:2px solid #3b82f6;outline-offset:2px}@media(pointer:coarse),(max-width:480px){.rd-wrap{position:relative}.rd-hidden{width:44px;height:44px;margin:0;clip:auto;overflow:visible;left:-12px;top:-2px;opacity:0;cursor:pointer;z-index:1}.rd-wrap.rd-disabled .rd-hidden{cursor:not-allowed}}.rd-dot{flex-shrink:0;width:20px;height:20px;box-sizing:border-box;border:2px solid #7c8ba1;border-radius:50%;background:#fff;display:flex;align-items:center;justify-content:center;transition:background .12s,border-color .12s}.rd-dot.rd-checked{background:#3b82f6;border-color:#3b82f6}.rd-dot.rd-invalid:not(.rd-checked){border-color:#ef4444}.rd-wrap:hover .rd-dot:not(.rd-checked):not(.rd-disabled){border-color:#3b82f6}.rd-core{width:8px;height:8px;border-radius:50%;background:#fff}@media(max-width:640px),(pointer:coarse){.rd-dot{position:relative}.rd-dot:after{content:\"\";position:absolute;inset:-12px}}.rd-icon{flex-shrink:0;margin-top:1px;color:#64748b}.rd-text{display:flex;flex-direction:column;gap:2px}.rd-label{font-size:.875rem;color:#334155;line-height:1.4}.rd-description{font-size:.75rem;color:#64748b;line-height:1.4}.rd-link{font-size:.75rem;line-height:1.4;color:#2563eb;text-decoration:underline;align-self:flex-start;cursor:pointer;display:inline-flex;align-items:center;min-height:24px;box-sizing:border-box;padding:0;margin:-3.6px 0}@media(pointer:coarse),(max-width:480px){.rd-link{min-height:44px;margin:-13.6px 0}}.rd-link:hover{color:#1d4ed8}.rd-link:focus-visible{outline:2px solid #3b82f6;outline-offset:2px;border-radius:2px}.rd-sr{position:absolute;width:1px;height:1px;margin:-1px;padding:0;overflow:hidden;clip:rect(0,0,0,0);white-space:nowrap;border:0}\n"],
18783
19796
  changeDetection: i0.ChangeDetectionStrategy.OnPush
18784
19797
  });
18785
19798
  }
@@ -18822,11 +19835,15 @@ i0.ɵɵngDeclareClassMetadata({
18822
19835
  <span class="rd-text">
18823
19836
  @if (label()) { <span class="rd-label" [id]="_labelId()">{{ label() }}</span> }
18824
19837
  @if (description()) { <span class="rd-description" [id]="_descriptionId">{{ description() }}</span> }
19838
+ @if (_linkHref(); as href) {
19839
+ <!-- Optional link after the description (library source 2026-11-05): a real anchor, so it is its own tab stop; clicking it follows the link and never selects the radio. -->
19840
+ <a class="rd-link" [attr.href]="href" [attr.target]="_linkNewTab() ? '_blank' : null" [attr.rel]="_linkNewTab() ? 'noopener noreferrer' : null" [attr.data-testid]="linkTestId() || null">{{ linkLabel() }}@if (_linkNewTab()) { <span class="rd-sr">(opens in a new tab)</span> }</a>
19841
+ }
18825
19842
  <ng-content />
18826
19843
  </span>
18827
19844
  </label>
18828
19845
  `,
18829
- styles: [":host{display:block}.rd-wrap{position:relative;display:inline-flex;align-items:flex-start;gap:9px;vertical-align:top;cursor:pointer;-webkit-user-select:none;user-select:none}.rd-wrap.rd-disabled{cursor:not-allowed;opacity:.5}.rd-hidden{position:absolute;width:1px;height:1px;margin:-1px;padding:0;overflow:hidden;clip:rect(0,0,0,0);white-space:nowrap;border:0}.rd-wrap:has(.rd-hidden:focus-visible) .rd-dot{outline:2px solid #3b82f6;outline-offset:2px}@media(pointer:coarse),(max-width:480px){.rd-wrap{position:relative}.rd-hidden{width:44px;height:44px;margin:0;clip:auto;overflow:visible;left:-12px;top:-2px;opacity:0;cursor:pointer;z-index:1}.rd-wrap.rd-disabled .rd-hidden{cursor:not-allowed}}.rd-dot{flex-shrink:0;width:20px;height:20px;box-sizing:border-box;border:2px solid #7c8ba1;border-radius:50%;background:#fff;display:flex;align-items:center;justify-content:center;transition:background .12s,border-color .12s}.rd-dot.rd-checked{background:#3b82f6;border-color:#3b82f6}.rd-dot.rd-invalid:not(.rd-checked){border-color:#ef4444}.rd-wrap:hover .rd-dot:not(.rd-checked):not(.rd-disabled){border-color:#3b82f6}.rd-core{width:8px;height:8px;border-radius:50%;background:#fff}@media(max-width:640px),(pointer:coarse){.rd-dot{position:relative}.rd-dot:after{content:\"\";position:absolute;inset:-12px}}.rd-icon{flex-shrink:0;margin-top:1px;color:#64748b}.rd-text{display:flex;flex-direction:column;gap:2px}.rd-label{font-size:.875rem;color:#334155;line-height:1.4}.rd-description{font-size:.75rem;color:#64748b;line-height:1.4}\n"]
19846
+ styles: [":host{display:block}.rd-wrap{position:relative;display:inline-flex;align-items:flex-start;gap:9px;vertical-align:top;cursor:pointer;-webkit-user-select:none;user-select:none}.rd-wrap.rd-disabled{cursor:not-allowed;opacity:.5}.rd-hidden{position:absolute;width:1px;height:1px;margin:-1px;padding:0;overflow:hidden;clip:rect(0,0,0,0);white-space:nowrap;border:0}.rd-wrap:has(.rd-hidden:focus-visible) .rd-dot{outline:2px solid #3b82f6;outline-offset:2px}@media(pointer:coarse),(max-width:480px){.rd-wrap{position:relative}.rd-hidden{width:44px;height:44px;margin:0;clip:auto;overflow:visible;left:-12px;top:-2px;opacity:0;cursor:pointer;z-index:1}.rd-wrap.rd-disabled .rd-hidden{cursor:not-allowed}}.rd-dot{flex-shrink:0;width:20px;height:20px;box-sizing:border-box;border:2px solid #7c8ba1;border-radius:50%;background:#fff;display:flex;align-items:center;justify-content:center;transition:background .12s,border-color .12s}.rd-dot.rd-checked{background:#3b82f6;border-color:#3b82f6}.rd-dot.rd-invalid:not(.rd-checked){border-color:#ef4444}.rd-wrap:hover .rd-dot:not(.rd-checked):not(.rd-disabled){border-color:#3b82f6}.rd-core{width:8px;height:8px;border-radius:50%;background:#fff}@media(max-width:640px),(pointer:coarse){.rd-dot{position:relative}.rd-dot:after{content:\"\";position:absolute;inset:-12px}}.rd-icon{flex-shrink:0;margin-top:1px;color:#64748b}.rd-text{display:flex;flex-direction:column;gap:2px}.rd-label{font-size:.875rem;color:#334155;line-height:1.4}.rd-description{font-size:.75rem;color:#64748b;line-height:1.4}.rd-link{font-size:.75rem;line-height:1.4;color:#2563eb;text-decoration:underline;align-self:flex-start;cursor:pointer;display:inline-flex;align-items:center;min-height:24px;box-sizing:border-box;padding:0;margin:-3.6px 0}@media(pointer:coarse),(max-width:480px){.rd-link{min-height:44px;margin:-13.6px 0}}.rd-link:hover{color:#1d4ed8}.rd-link:focus-visible{outline:2px solid #3b82f6;outline-offset:2px;border-radius:2px}.rd-sr{position:absolute;width:1px;height:1px;margin:-1px;padding:0;overflow:hidden;clip:rect(0,0,0,0);white-space:nowrap;border:0}\n"]
18830
19847
  }]
18831
19848
  }],
18832
19849
  propDecorators: {
@@ -18846,6 +19863,30 @@ i0.ɵɵngDeclareClassMetadata({
18846
19863
  required: false
18847
19864
  }]
18848
19865
  }],
19866
+ linkLabel: [{
19867
+ type: i0.Input,
19868
+ args: [{
19869
+ isSignal: true,
19870
+ alias: "linkLabel",
19871
+ required: false
19872
+ }]
19873
+ }],
19874
+ linkUrl: [{
19875
+ type: i0.Input,
19876
+ args: [{
19877
+ isSignal: true,
19878
+ alias: "linkUrl",
19879
+ required: false
19880
+ }]
19881
+ }],
19882
+ linkTestId: [{
19883
+ type: i0.Input,
19884
+ args: [{
19885
+ isSignal: true,
19886
+ alias: "linkTestId",
19887
+ required: false
19888
+ }]
19889
+ }],
18849
19890
  icon: [{
18850
19891
  type: i0.Input,
18851
19892
  args: [{
@@ -19215,6 +20256,9 @@ var RadioGroupComponent = class RadioGroupComponent {
19215
20256
  [label]="opt.label"
19216
20257
  [description]="opt.description ?? ''"
19217
20258
  [icon]="opt.icon ?? ''"
20259
+ [linkLabel]="opt.descriptionLink?.label ?? ''"
20260
+ [linkUrl]="opt.descriptionLink?.url ?? ''"
20261
+ [linkTestId]="opt.descriptionLink?.testId ?? ''"
19218
20262
  [checked]="_value() === opt.value"
19219
20263
  [disabled]="disabled() || !!opt.disabled"
19220
20264
  [invalid]="!!_activeError()"
@@ -19244,6 +20288,9 @@ var RadioGroupComponent = class RadioGroupComponent {
19244
20288
  inputs: [
19245
20289
  "label",
19246
20290
  "description",
20291
+ "linkLabel",
20292
+ "linkUrl",
20293
+ "linkTestId",
19247
20294
  "icon",
19248
20295
  "ariaLabel",
19249
20296
  "testId",
@@ -19324,6 +20371,9 @@ i0.ɵɵngDeclareClassMetadata({
19324
20371
  [label]="opt.label"
19325
20372
  [description]="opt.description ?? ''"
19326
20373
  [icon]="opt.icon ?? ''"
20374
+ [linkLabel]="opt.descriptionLink?.label ?? ''"
20375
+ [linkUrl]="opt.descriptionLink?.url ?? ''"
20376
+ [linkTestId]="opt.descriptionLink?.testId ?? ''"
19327
20377
  [checked]="_value() === opt.value"
19328
20378
  [disabled]="disabled() || !!opt.disabled"
19329
20379
  [invalid]="!!_activeError()"
@@ -22037,6 +23087,8 @@ var TextareaInputComponent = class TextareaInputComponent {
22037
23087
  this.invalid = computed(() => !!this.error() || !!this._issue(), ...ngDevMode ? [{ debugName: "invalid" }] : /* istanbul ignore next */ []);
22038
23088
  this.errorMessage = computed(() => this._issue()?.message ?? "", ...ngDevMode ? [{ debugName: "errorMessage" }] : /* istanbul ignore next */ []);
22039
23089
  this.invalidChange = output();
23090
+ this.focused = output();
23091
+ this.blurred = output();
22040
23092
  this._activeError = computed(() => this.error() || (this._reveal.revealed() ? this.errorMessage() : ""), ...ngDevMode ? [{ debugName: "_activeError" }] : /* istanbul ignore next */ []);
22041
23093
  this._onValidatorChange = () => {};
22042
23094
  this._inputId = `ta-${Math.random().toString(36).slice(2, 8)}`;
@@ -22060,6 +23112,55 @@ var TextareaInputComponent = class TextareaInputComponent {
22060
23112
  focus(options) {
22061
23113
  this._hostEl.nativeElement.querySelector("textarea")?.focus(options);
22062
23114
  }
23115
+ getSelection() {
23116
+ const el = this._textarea();
23117
+ if (!el) return null;
23118
+ try {
23119
+ if (el.selectionStart === null || el.selectionEnd === null) return null;
23120
+ return {
23121
+ start: el.selectionStart,
23122
+ end: el.selectionEnd
23123
+ };
23124
+ } catch {
23125
+ return null;
23126
+ }
23127
+ }
23128
+ setSelection(start, end = start) {
23129
+ const el = this._textarea();
23130
+ if (!el) return;
23131
+ const max = el.value.length;
23132
+ const from = Math.min(Math.max(0, start), max);
23133
+ const to = Math.min(Math.max(from, end), max);
23134
+ try {
23135
+ el.setSelectionRange(from, to);
23136
+ } catch {}
23137
+ }
23138
+ insertAtCaret(text) {
23139
+ const el = this._textarea();
23140
+ if (!el || el.disabled || el.readOnly || !text) return;
23141
+ const value = el.value;
23142
+ let from = value.length;
23143
+ let to = value.length;
23144
+ try {
23145
+ if (el.selectionStart !== null && el.selectionEnd !== null) {
23146
+ from = el.selectionStart;
23147
+ to = el.selectionEnd;
23148
+ }
23149
+ } catch {}
23150
+ const max = this.maxlength();
23151
+ const room = max === void 0 ? text.length : max - (value.length - (to - from));
23152
+ const insert = text.slice(0, Math.max(0, room));
23153
+ if (!insert) return;
23154
+ el.value = value.slice(0, from) + insert + value.slice(to);
23155
+ const caret = from + insert.length;
23156
+ try {
23157
+ el.setSelectionRange(caret, caret);
23158
+ } catch {}
23159
+ el.dispatchEvent(new Event("input", { bubbles: true }));
23160
+ }
23161
+ _textarea() {
23162
+ return this._hostEl.nativeElement.querySelector("textarea");
23163
+ }
22063
23164
  writeValue(val) {
22064
23165
  this._value.set(val ?? "");
22065
23166
  }
@@ -22077,9 +23178,13 @@ var TextareaInputComponent = class TextareaInputComponent {
22077
23178
  this._value.set(val);
22078
23179
  this._onChange(val);
22079
23180
  }
23181
+ onFocus() {
23182
+ this.focused.emit();
23183
+ }
22080
23184
  onBlur() {
22081
23185
  this._onTouched();
22082
23186
  this._reveal.touched.set(true);
23187
+ this.blurred.emit();
22083
23188
  }
22084
23189
  _check(value) {
22085
23190
  if (this.disabled() || this.readonly()) return null;
@@ -22204,7 +23309,11 @@ var TextareaInputComponent = class TextareaInputComponent {
22204
23309
  transformFunction: null
22205
23310
  }
22206
23311
  },
22207
- outputs: { invalidChange: "invalidChange" },
23312
+ outputs: {
23313
+ invalidChange: "invalidChange",
23314
+ focused: "focused",
23315
+ blurred: "blurred"
23316
+ },
22208
23317
  providers: [
22209
23318
  {
22210
23319
  provide: NG_VALUE_ACCESSOR,
@@ -22257,6 +23366,7 @@ var TextareaInputComponent = class TextareaInputComponent {
22257
23366
  [attr.aria-invalid]="_activeError() ? 'true' : null"
22258
23367
  [attr.aria-describedby]="_describedBy()"
22259
23368
  (input)="onInput($event)"
23369
+ (focus)="onFocus()"
22260
23370
  (blur)="onBlur()"
22261
23371
  ></textarea>
22262
23372
  @if (!_activeError() && _unlabelledHint()) {
@@ -22334,6 +23444,7 @@ i0.ɵɵngDeclareClassMetadata({
22334
23444
  [attr.aria-invalid]="_activeError() ? 'true' : null"
22335
23445
  [attr.aria-describedby]="_describedBy()"
22336
23446
  (input)="onInput($event)"
23447
+ (focus)="onFocus()"
22337
23448
  (blur)="onBlur()"
22338
23449
  ></textarea>
22339
23450
  @if (!_activeError() && _unlabelledHint()) {
@@ -22464,6 +23575,14 @@ i0.ɵɵngDeclareClassMetadata({
22464
23575
  invalidChange: [{
22465
23576
  type: i0.Output,
22466
23577
  args: ["invalidChange"]
23578
+ }],
23579
+ focused: [{
23580
+ type: i0.Output,
23581
+ args: ["focused"]
23582
+ }],
23583
+ blurred: [{
23584
+ type: i0.Output,
23585
+ args: ["blurred"]
22467
23586
  }]
22468
23587
  }
22469
23588
  });
@@ -22741,7 +23860,11 @@ var BulkMessagePanelComponent = class BulkMessagePanelComponent {
22741
23860
  "showErrors",
22742
23861
  "disabled"
22743
23862
  ],
22744
- outputs: ["invalidChange"]
23863
+ outputs: [
23864
+ "invalidChange",
23865
+ "focused",
23866
+ "blurred"
23867
+ ]
22745
23868
  }
22746
23869
  ],
22747
23870
  changeDetection: i0.ChangeDetectionStrategy.OnPush
@@ -29512,15 +30635,30 @@ var ListItemComponent = class ListItemComponent {
29512
30635
  this.select = output();
29513
30636
  this.pressable = () => this.interactive() && this.leading() === "none";
29514
30637
  this.hasImage = signal(false, ...ngDevMode ? [{ debugName: "hasImage" }] : /* istanbul ignore next */ []);
29515
- this.visibleDetails = () => this.details().map((d) => typeof d === "string" ? {
29516
- text: d,
29517
- d: null,
29518
- tone: "default"
29519
- } : d ? {
29520
- text: d.text,
29521
- d: d.icon ? iconPath(d.icon) ?? null : null,
29522
- tone: d.tone ?? "default"
29523
- } : null).filter((d) => !!d && !!d.text);
30638
+ this.visibleDetails = () => this.details().map((d) => {
30639
+ if (typeof d === "string") return {
30640
+ text: d,
30641
+ segs: null,
30642
+ d: null,
30643
+ tone: "default"
30644
+ };
30645
+ if (!d) return null;
30646
+ const segs = d.segments?.length ? d.segments.map((g) => typeof g === "string" ? {
30647
+ text: g,
30648
+ bold: false,
30649
+ code: false
30650
+ } : {
30651
+ text: g.text,
30652
+ bold: !!g.bold,
30653
+ code: !!g.code
30654
+ }) : null;
30655
+ return {
30656
+ text: segs ? segs.map((g) => g.text).join("") : d.text ?? "",
30657
+ segs,
30658
+ d: d.icon ? iconPath(d.icon) ?? null : null,
30659
+ tone: d.tone ?? "default"
30660
+ };
30661
+ }).filter((d) => !!d && !!d.text);
29524
30662
  }
29525
30663
  get _borderedClass() {
29526
30664
  return this.bordered();
@@ -29555,7 +30693,7 @@ var ListItemComponent = class ListItemComponent {
29555
30693
  }
29556
30694
  onRowClick(e) {
29557
30695
  if (!this.pressable() || this.disabled() || this.busy()) return;
29558
- if (e.target.closest("[list-item-action], [li-action]")) return;
30696
+ if (e.target.closest("[list-item-action], [li-action], [list-item-end]")) return;
29559
30697
  this.select.emit();
29560
30698
  }
29561
30699
  onRowKey(e) {
@@ -29730,7 +30868,16 @@ var ListItemComponent = class ListItemComponent {
29730
30868
  @if (detail.d) {
29731
30869
  <svg class="li-detail-icon" 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]="detail.d" /></svg>
29732
30870
  }
29733
- <span class="li-detail-text" data-testid="list-item-detail">{{ detail.text }}</span>
30871
+ <span class="li-detail-text" data-testid="list-item-detail">
30872
+ @if (detail.segs; as segs) {
30873
+ @for (seg of segs; track $index) {
30874
+ @if (seg.bold && seg.code) { <strong><code class="li-code">{{ seg.text }}</code></strong> }
30875
+ @else if (seg.bold) { <strong>{{ seg.text }}</strong> }
30876
+ @else if (seg.code) { <code class="li-code">{{ seg.text }}</code> }
30877
+ @else { <ng-container>{{ seg.text }}</ng-container> }
30878
+ }
30879
+ } @else { <ng-container>{{ detail.text }}</ng-container> }
30880
+ </span>
29734
30881
  </span>
29735
30882
  }
29736
30883
  </div>
@@ -29781,6 +30928,9 @@ var ListItemComponent = class ListItemComponent {
29781
30928
  </label>
29782
30929
  }
29783
30930
 
30931
+ <!-- Row-end content slot (library source 2026-11-05): a rating, a badge... after the text. Outside the label, so it never selects the row. -->
30932
+ <ng-content select="[list-item-end]" />
30933
+
29784
30934
  @if (busy()) {
29785
30935
  <span class="li-spinner" aria-hidden="true"></span>
29786
30936
  }
@@ -29789,7 +30939,7 @@ var ListItemComponent = class ListItemComponent {
29789
30939
  </div>
29790
30940
  `,
29791
30941
  isInline: true,
29792
- styles: ["ui-list-item{display:block}ui-list-item.li-bordered{border:1px solid var(--border, #e2e8f0);border-radius:12px;overflow:hidden;background:var(--surface, #fff);box-shadow:0 1px 2px #0f172a0a;margin-bottom:8px;transition:border-color .15s ease,box-shadow .15s ease}ui-list-item.li-bordered:last-child{margin-bottom:0}ui-list-item.li-bordered:hover{border-color:#cbd5e1;box-shadow:0 2px 6px #0f172a12}@media(prefers-reduced-motion:reduce){ui-list-item.li-bordered{transition:none}}.li-row{display:flex;align-items:flex-start;gap:14px;padding:12px 16px;border-bottom:1px solid var(--border, #e2e8f0);transition:background .12s}.li-row:last-child{border-bottom:none}.li-row:hover{background:var(--surface-hover, #f8fafc)}ui-list-item.li-bordered .li-row{border-bottom:none;padding:14px 16px}.li-row.li-row--highlighted{background:#f0fdf4}.li-row.li-row--highlighted:hover{background:#dcfce7}.li-row.li-row--static:hover{background:transparent}.li-row.li-row--static.li-row--highlighted,.li-row.li-row--static.li-row--highlighted:hover{background:#f0fdf4}.li-row.li-row--pressable{cursor:pointer}.li-row.li-row--pressable:focus-visible{outline:2px solid var(--primary, #2563eb);outline-offset:-2px}.li-body.li-body--static{cursor:default}.li-row [list-item-action],.li-row [li-action]{flex-shrink:0;align-self:center}.li-row>[list-item-image]{flex:0 0 auto;align-self:center}.li-row.li-row--disabled,.li-row.li-row--disabled:hover{opacity:.72;cursor:not-allowed;background-color:var(--surface-muted, #f8fafc);background-image:repeating-linear-gradient(135deg,transparent 0,transparent 6px,rgba(100,116,139,.1) 6px,rgba(100,116,139,.1) 12px)}.li-row.li-row--disabled .li-body,.li-row.li-row--disabled .li-input,.li-row.li-row--disabled.li-row--pressable{cursor:not-allowed}ui-list-item.li-disabled.li-bordered,ui-list-item.li-disabled.li-bordered:hover{border-style:dashed;box-shadow:none}.li-row.li-row--busy,.li-row.li-row--busy .li-body{cursor:progress}.li-spinner{flex:0 0 auto;align-self:center;box-sizing:border-box;width:16px;height:16px;border:2px solid rgba(100,116,139,.3);border-top-color:var(--text-secondary, #475569);border-radius:50%;animation:li-spin .6s linear infinite}@keyframes li-spin{to{transform:rotate(360deg)}}@media(prefers-reduced-motion:reduce){.li-spinner{animation-duration:2s}}.li-input{margin-top:3px;flex-shrink:0;accent-color:#16a34a;width:1rem;height:1rem;cursor:pointer}.li-icon{flex:0 0 auto;display:inline-flex;align-items:center;justify-content:center;width:40px;height:40px;border-radius:12px}.li-icon--slate{background:#f1f5f9;color:#475569}.li-icon--amber{background:#fef3c7;color:#b45309}.li-icon--orange{background:#ffedd5;color:#c2410c}.li-icon--red{background:#fee2e2;color:#b91c1c}.li-icon--blue{background:#dbeafe;color:#1d4ed8}.li-icon--green{background:#dcfce7;color:#15803d}.li-icon--purple{background:#f3e8ff;color:#7e22ce}.li-icon--teal{background:#ccfbf1;color:#0f766e}.li-body{flex:1;min-width:0;cursor:pointer;display:flex;flex-direction:column;gap:6px}.li-title-row{display:flex;align-items:center;gap:6px;flex-wrap:wrap}.li-title{font-size:.9375rem;font-weight:600;line-height:1.4;letter-spacing:-.005em;color:var(--text-primary, #0f172a)}.li-row--wrap .li-title{min-width:0;word-break:break-word;overflow-wrap:anywhere}.li-details{display:flex;flex-direction:column;gap:3px;font-size:.8125rem;line-height:1.4;color:var(--text-secondary, #64748b)}.li-detail{display:flex;align-items:center;gap:6px;min-width:0}.li-detail-icon{flex:0 0 auto;color:#94a3b8}.li-detail--warning,.li-detail--warning .li-detail-icon{color:#b45309}.li-detail--danger,.li-detail--danger .li-detail-icon{color:#b91c1c}.li-row--wrap .li-detail-text{min-width:0;word-break:break-word;overflow-wrap:anywhere}\n"],
30942
+ styles: ["ui-list-item{display:block}ui-list-item.li-bordered{border:1px solid var(--border, #e2e8f0);border-radius:12px;overflow:hidden;background:var(--surface, #fff);box-shadow:0 1px 2px #0f172a0a;margin-bottom:8px;transition:border-color .15s ease,box-shadow .15s ease}ui-list-item.li-bordered:last-child{margin-bottom:0}ui-list-item.li-bordered:hover{border-color:#cbd5e1;box-shadow:0 2px 6px #0f172a12}@media(prefers-reduced-motion:reduce){ui-list-item.li-bordered{transition:none}}.li-row{display:flex;align-items:flex-start;gap:14px;padding:12px 16px;border-bottom:1px solid var(--border, #e2e8f0);transition:background .12s}.li-row:last-child{border-bottom:none}.li-row:hover{background:var(--surface-hover, #f8fafc)}ui-list-item.li-bordered .li-row{border-bottom:none;padding:14px 16px}.li-row.li-row--highlighted{background:#f0fdf4}.li-row.li-row--highlighted:hover{background:#dcfce7}.li-row.li-row--static:hover{background:transparent}.li-row.li-row--static.li-row--highlighted,.li-row.li-row--static.li-row--highlighted:hover{background:#f0fdf4}.li-row.li-row--pressable{cursor:pointer}.li-row.li-row--pressable:focus-visible{outline:2px solid var(--primary, #2563eb);outline-offset:-2px}.li-body.li-body--static{cursor:default}.li-row [list-item-action],.li-row [li-action]{flex-shrink:0;align-self:center}.li-row>[list-item-end]{flex:0 0 auto;align-self:center}.li-row>[list-item-image]{flex:0 0 auto;align-self:center}.li-row.li-row--disabled,.li-row.li-row--disabled:hover{opacity:.72;cursor:not-allowed;background-color:var(--surface-muted, #f8fafc);background-image:repeating-linear-gradient(135deg,transparent 0,transparent 6px,rgba(100,116,139,.1) 6px,rgba(100,116,139,.1) 12px)}.li-row.li-row--disabled .li-body,.li-row.li-row--disabled .li-input,.li-row.li-row--disabled.li-row--pressable{cursor:not-allowed}ui-list-item.li-disabled.li-bordered,ui-list-item.li-disabled.li-bordered:hover{border-style:dashed;box-shadow:none}.li-row.li-row--busy,.li-row.li-row--busy .li-body{cursor:progress}.li-spinner{flex:0 0 auto;align-self:center;box-sizing:border-box;width:16px;height:16px;border:2px solid rgba(100,116,139,.3);border-top-color:var(--text-secondary, #475569);border-radius:50%;animation:li-spin .6s linear infinite}@keyframes li-spin{to{transform:rotate(360deg)}}@media(prefers-reduced-motion:reduce){.li-spinner{animation-duration:2s}}.li-input{margin-top:3px;flex-shrink:0;accent-color:#16a34a;width:1rem;height:1rem;cursor:pointer}.li-icon{flex:0 0 auto;display:inline-flex;align-items:center;justify-content:center;width:40px;height:40px;border-radius:12px}.li-icon--slate{background:#f1f5f9;color:#475569}.li-icon--amber{background:#fef3c7;color:#b45309}.li-icon--orange{background:#ffedd5;color:#c2410c}.li-icon--red{background:#fee2e2;color:#b91c1c}.li-icon--blue{background:#dbeafe;color:#1d4ed8}.li-icon--green{background:#dcfce7;color:#15803d}.li-icon--purple{background:#f3e8ff;color:#7e22ce}.li-icon--teal{background:#ccfbf1;color:#0f766e}.li-body{flex:1;min-width:0;cursor:pointer;display:flex;flex-direction:column;gap:6px}.li-title-row{display:flex;align-items:center;gap:6px;flex-wrap:wrap}.li-title{font-size:.9375rem;font-weight:600;line-height:1.4;letter-spacing:-.005em;color:var(--text-primary, #0f172a)}.li-row--wrap .li-title{min-width:0;word-break:break-word;overflow-wrap:anywhere}.li-details{display:flex;flex-direction:column;gap:3px;font-size:.8125rem;line-height:1.4;color:var(--text-secondary, #64748b)}.li-detail{display:flex;align-items:center;gap:6px;min-width:0}.li-detail-icon{flex:0 0 auto;color:#94a3b8}.li-code{font-family:ui-monospace,SFMono-Regular,Menlo,Consolas,monospace;font-size:.92em;background:#f1f5f9;border-radius:4px;padding:1px 4px}.li-detail--warning,.li-detail--warning .li-detail-icon{color:#b45309}.li-detail--danger,.li-detail--danger .li-detail-icon{color:#b91c1c}.li-row--wrap .li-detail-text{min-width:0;word-break:break-word;overflow-wrap:anywhere}\n"],
29793
30943
  dependencies: [{
29794
30944
  kind: "component",
29795
30945
  type: BadgeComponent,
@@ -29849,7 +30999,16 @@ i0.ɵɵngDeclareClassMetadata({
29849
30999
  @if (detail.d) {
29850
31000
  <svg class="li-detail-icon" 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]="detail.d" /></svg>
29851
31001
  }
29852
- <span class="li-detail-text" data-testid="list-item-detail">{{ detail.text }}</span>
31002
+ <span class="li-detail-text" data-testid="list-item-detail">
31003
+ @if (detail.segs; as segs) {
31004
+ @for (seg of segs; track $index) {
31005
+ @if (seg.bold && seg.code) { <strong><code class="li-code">{{ seg.text }}</code></strong> }
31006
+ @else if (seg.bold) { <strong>{{ seg.text }}</strong> }
31007
+ @else if (seg.code) { <code class="li-code">{{ seg.text }}</code> }
31008
+ @else { <ng-container>{{ seg.text }}</ng-container> }
31009
+ }
31010
+ } @else { <ng-container>{{ detail.text }}</ng-container> }
31011
+ </span>
29853
31012
  </span>
29854
31013
  }
29855
31014
  </div>
@@ -29900,6 +31059,9 @@ i0.ɵɵngDeclareClassMetadata({
29900
31059
  </label>
29901
31060
  }
29902
31061
 
31062
+ <!-- Row-end content slot (library source 2026-11-05): a rating, a badge... after the text. Outside the label, so it never selects the row. -->
31063
+ <ng-content select="[list-item-end]" />
31064
+
29903
31065
  @if (busy()) {
29904
31066
  <span class="li-spinner" aria-hidden="true"></span>
29905
31067
  }
@@ -29907,7 +31069,7 @@ i0.ɵɵngDeclareClassMetadata({
29907
31069
 
29908
31070
  </div>
29909
31071
  `,
29910
- styles: ["ui-list-item{display:block}ui-list-item.li-bordered{border:1px solid var(--border, #e2e8f0);border-radius:12px;overflow:hidden;background:var(--surface, #fff);box-shadow:0 1px 2px #0f172a0a;margin-bottom:8px;transition:border-color .15s ease,box-shadow .15s ease}ui-list-item.li-bordered:last-child{margin-bottom:0}ui-list-item.li-bordered:hover{border-color:#cbd5e1;box-shadow:0 2px 6px #0f172a12}@media(prefers-reduced-motion:reduce){ui-list-item.li-bordered{transition:none}}.li-row{display:flex;align-items:flex-start;gap:14px;padding:12px 16px;border-bottom:1px solid var(--border, #e2e8f0);transition:background .12s}.li-row:last-child{border-bottom:none}.li-row:hover{background:var(--surface-hover, #f8fafc)}ui-list-item.li-bordered .li-row{border-bottom:none;padding:14px 16px}.li-row.li-row--highlighted{background:#f0fdf4}.li-row.li-row--highlighted:hover{background:#dcfce7}.li-row.li-row--static:hover{background:transparent}.li-row.li-row--static.li-row--highlighted,.li-row.li-row--static.li-row--highlighted:hover{background:#f0fdf4}.li-row.li-row--pressable{cursor:pointer}.li-row.li-row--pressable:focus-visible{outline:2px solid var(--primary, #2563eb);outline-offset:-2px}.li-body.li-body--static{cursor:default}.li-row [list-item-action],.li-row [li-action]{flex-shrink:0;align-self:center}.li-row>[list-item-image]{flex:0 0 auto;align-self:center}.li-row.li-row--disabled,.li-row.li-row--disabled:hover{opacity:.72;cursor:not-allowed;background-color:var(--surface-muted, #f8fafc);background-image:repeating-linear-gradient(135deg,transparent 0,transparent 6px,rgba(100,116,139,.1) 6px,rgba(100,116,139,.1) 12px)}.li-row.li-row--disabled .li-body,.li-row.li-row--disabled .li-input,.li-row.li-row--disabled.li-row--pressable{cursor:not-allowed}ui-list-item.li-disabled.li-bordered,ui-list-item.li-disabled.li-bordered:hover{border-style:dashed;box-shadow:none}.li-row.li-row--busy,.li-row.li-row--busy .li-body{cursor:progress}.li-spinner{flex:0 0 auto;align-self:center;box-sizing:border-box;width:16px;height:16px;border:2px solid rgba(100,116,139,.3);border-top-color:var(--text-secondary, #475569);border-radius:50%;animation:li-spin .6s linear infinite}@keyframes li-spin{to{transform:rotate(360deg)}}@media(prefers-reduced-motion:reduce){.li-spinner{animation-duration:2s}}.li-input{margin-top:3px;flex-shrink:0;accent-color:#16a34a;width:1rem;height:1rem;cursor:pointer}.li-icon{flex:0 0 auto;display:inline-flex;align-items:center;justify-content:center;width:40px;height:40px;border-radius:12px}.li-icon--slate{background:#f1f5f9;color:#475569}.li-icon--amber{background:#fef3c7;color:#b45309}.li-icon--orange{background:#ffedd5;color:#c2410c}.li-icon--red{background:#fee2e2;color:#b91c1c}.li-icon--blue{background:#dbeafe;color:#1d4ed8}.li-icon--green{background:#dcfce7;color:#15803d}.li-icon--purple{background:#f3e8ff;color:#7e22ce}.li-icon--teal{background:#ccfbf1;color:#0f766e}.li-body{flex:1;min-width:0;cursor:pointer;display:flex;flex-direction:column;gap:6px}.li-title-row{display:flex;align-items:center;gap:6px;flex-wrap:wrap}.li-title{font-size:.9375rem;font-weight:600;line-height:1.4;letter-spacing:-.005em;color:var(--text-primary, #0f172a)}.li-row--wrap .li-title{min-width:0;word-break:break-word;overflow-wrap:anywhere}.li-details{display:flex;flex-direction:column;gap:3px;font-size:.8125rem;line-height:1.4;color:var(--text-secondary, #64748b)}.li-detail{display:flex;align-items:center;gap:6px;min-width:0}.li-detail-icon{flex:0 0 auto;color:#94a3b8}.li-detail--warning,.li-detail--warning .li-detail-icon{color:#b45309}.li-detail--danger,.li-detail--danger .li-detail-icon{color:#b91c1c}.li-row--wrap .li-detail-text{min-width:0;word-break:break-word;overflow-wrap:anywhere}\n"]
31072
+ styles: ["ui-list-item{display:block}ui-list-item.li-bordered{border:1px solid var(--border, #e2e8f0);border-radius:12px;overflow:hidden;background:var(--surface, #fff);box-shadow:0 1px 2px #0f172a0a;margin-bottom:8px;transition:border-color .15s ease,box-shadow .15s ease}ui-list-item.li-bordered:last-child{margin-bottom:0}ui-list-item.li-bordered:hover{border-color:#cbd5e1;box-shadow:0 2px 6px #0f172a12}@media(prefers-reduced-motion:reduce){ui-list-item.li-bordered{transition:none}}.li-row{display:flex;align-items:flex-start;gap:14px;padding:12px 16px;border-bottom:1px solid var(--border, #e2e8f0);transition:background .12s}.li-row:last-child{border-bottom:none}.li-row:hover{background:var(--surface-hover, #f8fafc)}ui-list-item.li-bordered .li-row{border-bottom:none;padding:14px 16px}.li-row.li-row--highlighted{background:#f0fdf4}.li-row.li-row--highlighted:hover{background:#dcfce7}.li-row.li-row--static:hover{background:transparent}.li-row.li-row--static.li-row--highlighted,.li-row.li-row--static.li-row--highlighted:hover{background:#f0fdf4}.li-row.li-row--pressable{cursor:pointer}.li-row.li-row--pressable:focus-visible{outline:2px solid var(--primary, #2563eb);outline-offset:-2px}.li-body.li-body--static{cursor:default}.li-row [list-item-action],.li-row [li-action]{flex-shrink:0;align-self:center}.li-row>[list-item-end]{flex:0 0 auto;align-self:center}.li-row>[list-item-image]{flex:0 0 auto;align-self:center}.li-row.li-row--disabled,.li-row.li-row--disabled:hover{opacity:.72;cursor:not-allowed;background-color:var(--surface-muted, #f8fafc);background-image:repeating-linear-gradient(135deg,transparent 0,transparent 6px,rgba(100,116,139,.1) 6px,rgba(100,116,139,.1) 12px)}.li-row.li-row--disabled .li-body,.li-row.li-row--disabled .li-input,.li-row.li-row--disabled.li-row--pressable{cursor:not-allowed}ui-list-item.li-disabled.li-bordered,ui-list-item.li-disabled.li-bordered:hover{border-style:dashed;box-shadow:none}.li-row.li-row--busy,.li-row.li-row--busy .li-body{cursor:progress}.li-spinner{flex:0 0 auto;align-self:center;box-sizing:border-box;width:16px;height:16px;border:2px solid rgba(100,116,139,.3);border-top-color:var(--text-secondary, #475569);border-radius:50%;animation:li-spin .6s linear infinite}@keyframes li-spin{to{transform:rotate(360deg)}}@media(prefers-reduced-motion:reduce){.li-spinner{animation-duration:2s}}.li-input{margin-top:3px;flex-shrink:0;accent-color:#16a34a;width:1rem;height:1rem;cursor:pointer}.li-icon{flex:0 0 auto;display:inline-flex;align-items:center;justify-content:center;width:40px;height:40px;border-radius:12px}.li-icon--slate{background:#f1f5f9;color:#475569}.li-icon--amber{background:#fef3c7;color:#b45309}.li-icon--orange{background:#ffedd5;color:#c2410c}.li-icon--red{background:#fee2e2;color:#b91c1c}.li-icon--blue{background:#dbeafe;color:#1d4ed8}.li-icon--green{background:#dcfce7;color:#15803d}.li-icon--purple{background:#f3e8ff;color:#7e22ce}.li-icon--teal{background:#ccfbf1;color:#0f766e}.li-body{flex:1;min-width:0;cursor:pointer;display:flex;flex-direction:column;gap:6px}.li-title-row{display:flex;align-items:center;gap:6px;flex-wrap:wrap}.li-title{font-size:.9375rem;font-weight:600;line-height:1.4;letter-spacing:-.005em;color:var(--text-primary, #0f172a)}.li-row--wrap .li-title{min-width:0;word-break:break-word;overflow-wrap:anywhere}.li-details{display:flex;flex-direction:column;gap:3px;font-size:.8125rem;line-height:1.4;color:var(--text-secondary, #64748b)}.li-detail{display:flex;align-items:center;gap:6px;min-width:0}.li-detail-icon{flex:0 0 auto;color:#94a3b8}.li-code{font-family:ui-monospace,SFMono-Regular,Menlo,Consolas,monospace;font-size:.92em;background:#f1f5f9;border-radius:4px;padding:1px 4px}.li-detail--warning,.li-detail--warning .li-detail-icon{color:#b45309}.li-detail--danger,.li-detail--danger .li-detail-icon{color:#b91c1c}.li-row--wrap .li-detail-text{min-width:0;word-break:break-word;overflow-wrap:anywhere}\n"]
29911
31073
  }]
29912
31074
  }],
29913
31075
  propDecorators: {
@@ -31062,7 +32224,11 @@ var NotesComponent = class NotesComponent {
31062
32224
  "showErrors",
31063
32225
  "disabled"
31064
32226
  ],
31065
- outputs: ["invalidChange"]
32227
+ outputs: [
32228
+ "invalidChange",
32229
+ "focused",
32230
+ "blurred"
32231
+ ]
31066
32232
  },
31067
32233
  {
31068
32234
  kind: "component",
@@ -41706,6 +42872,9 @@ var RadioMatrixComponent = class RadioMatrixComponent {
41706
42872
  inputs: [
41707
42873
  "label",
41708
42874
  "description",
42875
+ "linkLabel",
42876
+ "linkUrl",
42877
+ "linkTestId",
41709
42878
  "icon",
41710
42879
  "ariaLabel",
41711
42880
  "testId",
@@ -57473,7 +58642,11 @@ var ConversationsComponent = class ConversationsComponent {
57473
58642
  "showErrors",
57474
58643
  "disabled"
57475
58644
  ],
57476
- outputs: ["invalidChange"]
58645
+ outputs: [
58646
+ "invalidChange",
58647
+ "focused",
58648
+ "blurred"
58649
+ ]
57477
58650
  },
57478
58651
  {
57479
58652
  kind: "directive",
@@ -60449,7 +61622,11 @@ var PaymentSidePanelComponent = class PaymentSidePanelComponent {
60449
61622
  "showErrors",
60450
61623
  "disabled"
60451
61624
  ],
60452
- outputs: ["invalidChange"]
61625
+ outputs: [
61626
+ "invalidChange",
61627
+ "focused",
61628
+ "blurred"
61629
+ ]
60453
61630
  }
60454
61631
  ],
60455
61632
  changeDetection: i0.ChangeDetectionStrategy.OnPush,
@@ -60898,6 +62075,6 @@ i0.ɵɵngDeclareClassMetadata({
60898
62075
  }]
60899
62076
  }
60900
62077
  });
60901
- export { ALLOCATION_CUSTOM, ASCII_SPECIAL_PASSWORD_RULES, ActionBarComponent, AddressInputComponent, AlertComponent, AppShellComponent, AudioPlayerComponent, AvatarComponent, BADGE_VARIANT_STYLES, BadgeComponent, BankAccountFormComponent, BarRowComponent, BoardCardDirective, BoardComponent, BulkMessagePanelComponent, BusinessHoursComponent, ButtonComponent, COMMON_DETAIL_GROUP_STYLES, CalendarComponent, CardListItemComponent, CheckboxComponent, CheckboxTrailingDirective, ChipComponent, ChipGroupComponent, ColorInputComponent, ColumnFilterComponent, ColumnsComponent, ComboboxComponent, ConfirmOutletComponent, ConfirmService, ContactPickerComponent, ConversationRichBodyComponent, ConversationsComponent, CopyFieldComponent, DEFAULT_ALLOCATION_MODES, DEFAULT_BANK_ACCOUNT_TYPE_OPTIONS, DEFAULT_BANK_HOLDER_TYPE_OPTIONS, DEFAULT_BANK_MANDATE_TEXT, DEFAULT_EMAIL_TEMPLATE_BLOCK_GROUPS, DEFAULT_EMAIL_TEMPLATE_VARIABLE_GROUPS, DEFAULT_PASSWORD_RULES, DEFAULT_PAYMENT_METHODS, DETAIL_CARD_HEADER_BG, DETAIL_GROUP_HEADER_BG, DROPDOWN_GROUP, DataTableComponent, DateInputComponent, DateRangePickerComponent, DatetimeInputComponent, DetailCardComponent, DiscountSelectorComponent, DividerComponent, DropdownComponent, EMAIL_BLOCK_DRAG_TYPE, EMAIL_TEMPLATE_MAX_BODY, EMAIL_TEMPLATE_MAX_TEXT, EMAIL_TEMPLATE_START_TEXT, EmailTemplateEditorComponent, EmptyStateComponent, ErrorComponent, ErrorStateComponent, FORGEROUTE_CONFIG, FadeComponent, FileInputComponent, FillViewportDirective, FixedFooterComponent, FormColSpanDirective, FormComponent, FormRowComponent, FormSectionComponent, HintComponent, ICON_NAMES, IDX_BEHAVIOR_SIGNALS, INTEGRATION_CATALOG, INTEGRATION_FIELD_DEFS, INTEGRATION_GROUP_ORDER, INTEGRATION_OPTION_DEFS, IconComponent, IconPickerComponent, ImageComponent, ImageGalleryComponent, ImageGalleryDialogComponent, ImagePreviewComponent, ImageRepositionComponent, ImportExportComponent, ImportSourceGridComponent, KeypadComponent, KpiCardComponent, LAYOUT_GAP_PX, LISTED_SPECIAL_PASSWORD_RULES, ListComponent, ListItemComponent, LiveRegionComponent, MAX_EMAIL_ADDRESS_LENGTH, MAX_PAYMENT_AMOUNT, MIN_PAYMENT_AMOUNT, ModalComponent, MoreMenuComponent, MultiSelectComponent, NOTES_MAX_LENGTH, NotesComponent, OfflineBannerComponent, OptionCardComponent, PASSWORD_MAX_LENGTH, PAYMENT_METHOD, PAYMENT_METHOD_PLUGIN, PHONE_NUMBER_AREA_CODE_LENGTH, PHONE_NUMBER_ZIP_LENGTH, PageComponent, PaginationComponent, PanelInfoListComponent, PasswordRequirementsComponent, PaymentCustomMethodComponent, PaymentMethodPlugin, PaymentSidePanelComponent, PdfHotspotComponent, PhoneNumberPickerComponent, PillTabPanelDirective, PillTabsComponent, ProgressBarComponent, ProgressRingComponent, QrCodeComponent, QuickFilterTabsComponent, RICH_TEXT_OPTIONS, RadioComponent, RadioGroupComponent, RadioMatrixComponent, RadioOptionContentDirective, ReadonlyFieldsetComponent, ReminderAlertsComponent, RichTextEditorComponent, SEMANTIC_BADGE_MAP, SETUP_DONE_KEY, SETUP_INTEGRATIONS, SearchInputComponent, SectionHeaderComponent, SelectComponent, SetupWizardComponent, SetupWizardStepDirective, SetupWizardStepHeaderDirective, ShareMenuComponent, ShowComponent, SidePanelComponent, SidebarLayoutComponent, SignaturePadComponent, SkeletonComponent, SnackbarComponent, SnackbarService, StackComponent, StarComponent, StepperComponent, SwatchPickerComponent, TableToolbarComponent, TextComponent, TextInputComponent, TextTemplatePickerComponent, TextareaInputComponent, TimeInputComponent, TimelineComponent, ToastComponent, ToastService, ToggleBadgeComponent, ToggleComponent, TooltipDirective, US_LOCATIONS, US_STATES, US_STATE_OPTIONS, US_ZIP_PATTERN, UiFieldValidity, acceptLabel, appShellGroupsStorageKey, autoVariant, blockHasContent, buildDefaultSchedule, buildPreviewDocument, buildVideoBlockHtml, builtInActionIcon, businessTimeOptions, callHost, conversationDateLabel, conversationHtmlToText, conversationInitial, conversationMessageStatusLabel, conversationMessageStatusMark, createFieldReveal, createPasswordPolicyValidator, decodeFilterValues, digitsOnly, downloadBlob, emailShareUrl, emptyAddress, encodeFilterValue, encodeFilterValues, errorContextInterceptor, escapeHtml, facebookShareUrl, fileMatchesAccept, fileNameFromContentDisposition, formatAddress, formatAddressValue, formatAddressValueOneLine, formatCategoryLabel, formatConversationPhone, formatConversationTime, formatCurrency, formatDuration, formatFileSize, formatIsoDate, formatIsoDateTime, formatMessageTime, formatPhone, formatPhoneDisplay, formatShortDate, formatTime, formatVideoDuration, getEligibleIds, getEligibleOptions, getErrorMessage, getInitials, gmailShareUrl, groupMessagesByDay, hostErrorMessage, humanReadableMessage, iconPath, insideEditorBlock, integrationPlainText, integrationsForApp, integrationsOnlyFor, isBlockDrag, isEmptyAddress, isValidAmount, isValidEmailAddress, isValidZip, isWebUrl, isoKey, issueToErrors, last4Error, linkedInShareUrl, maxLengthIssue, mergeDescribedBy, normalizeAddress, normalizeHexColor, outlookShareUrl, parseAddressOneLine, parseAddressValue, parseBizHours, parseIso, parseTime, passwordMeetsRules, periodGroup, pillTabDescriptionId, pillTabId, pillTabPanelId, pillTabTitleId, pluralize, provideForgerouteToast, reorderItems, requiredIssue, resolveLayoutGap, resolvePreset, serializeBizHours, serializedTextLength, setupIntegrations, splitIntro, terminalTimeoutText, terminalVerdict, todayInTimezone, truncateConversationText, xShareUrl };
62078
+ export { ALLOCATION_CUSTOM, ASCII_SPECIAL_PASSWORD_RULES, ActionBarComponent, AddressInputComponent, AlertComponent, AppShellComponent, AudioPlayerComponent, AvatarComponent, BADGE_VARIANT_STYLES, BadgeComponent, BankAccountFormComponent, BarRowComponent, BoardCardDirective, BoardComponent, BulkMessagePanelComponent, BusinessHoursComponent, ButtonComponent, COMMON_DETAIL_GROUP_STYLES, CalendarComponent, CardListItemComponent, CheckboxComponent, CheckboxTrailingDirective, ChipComponent, ChipGroupComponent, ColorInputComponent, ColumnFilterComponent, ColumnsComponent, ComboboxComponent, ConfirmOutletComponent, ConfirmService, ContactPickerComponent, ConversationRichBodyComponent, ConversationsComponent, CopyFieldComponent, DEFAULT_ALLOCATION_MODES, DEFAULT_BANK_ACCOUNT_TYPE_OPTIONS, DEFAULT_BANK_HOLDER_TYPE_OPTIONS, DEFAULT_BANK_MANDATE_TEXT, DEFAULT_EMAIL_TEMPLATE_BLOCK_GROUPS, DEFAULT_EMAIL_TEMPLATE_VARIABLE_GROUPS, DEFAULT_PASSWORD_RULES, DEFAULT_PAYMENT_METHODS, DETAIL_CARD_HEADER_BG, DETAIL_GROUP_HEADER_BG, DROPDOWN_GROUP, DataTableComponent, DateInputComponent, DateRangePickerComponent, DatetimeInputComponent, DetailCardComponent, DiscountSelectorComponent, DividerComponent, DropdownComponent, EMAIL_BLOCK_DRAG_TYPE, EMAIL_TEMPLATE_MAX_BODY, EMAIL_TEMPLATE_MAX_TEXT, EMAIL_TEMPLATE_START_TEXT, EmailTemplateEditorComponent, EmptyStateComponent, ErrorComponent, ErrorStateComponent, FORGEROUTE_CONFIG, FadeComponent, FileInputComponent, FillViewportDirective, FixedFooterComponent, FormColSpanDirective, FormComponent, FormRowComponent, FormSectionComponent, HintComponent, ICON_NAMES, IDX_BEHAVIOR_SIGNALS, INTEGRATION_CATALOG, INTEGRATION_FIELD_DEFS, INTEGRATION_GROUP_ORDER, INTEGRATION_OPTION_DEFS, IconComponent, IconPickerComponent, ImageComponent, ImageGalleryComponent, ImageGalleryDialogComponent, ImagePreviewComponent, ImageRepositionComponent, ImportExportComponent, ImportSourceGridComponent, KeypadComponent, KpiCardComponent, LAYOUT_GAP_PX, LISTED_SPECIAL_PASSWORD_RULES, ListComponent, ListItemComponent, LiveRegionComponent, MAX_EMAIL_ADDRESS_LENGTH, MAX_PAYMENT_AMOUNT, MIN_PAYMENT_AMOUNT, ModalComponent, MoreMenuComponent, MultiSelectComponent, NOTES_MAX_LENGTH, NotesComponent, OfflineBannerComponent, OptionCardComponent, PASSWORD_MAX_LENGTH, PAYMENT_METHOD, PAYMENT_METHOD_PLUGIN, PHONE_NUMBER_AREA_CODE_LENGTH, PHONE_NUMBER_ZIP_LENGTH, PageComponent, PaginationComponent, PanelInfoListComponent, PasswordRequirementsComponent, PaymentCustomMethodComponent, PaymentMethodPlugin, PaymentSidePanelComponent, PdfHotspotComponent, PhoneNumberPickerComponent, PillTabPanelDirective, PillTabsComponent, ProgressBarComponent, ProgressRingComponent, QrCodeComponent, QuickFilterTabsComponent, RICH_TEXT_OPTIONS, RadioComponent, RadioGroupComponent, RadioMatrixComponent, RadioOptionContentDirective, ReadonlyFieldsetComponent, ReminderAlertsComponent, RichTextEditorComponent, SEMANTIC_BADGE_MAP, SETUP_DONE_KEY, SETUP_INTEGRATIONS, SearchInputComponent, SectionHeaderComponent, SelectComponent, SetupWizardComponent, SetupWizardStepDirective, SetupWizardStepHeaderDirective, ShareMenuComponent, ShowComponent, SidePanelComponent, SidebarLayoutComponent, SignaturePadComponent, SkeletonComponent, SnackbarComponent, SnackbarService, StackComponent, StackedBarComponent, StarComponent, StarRatingComponent, StepperComponent, SwatchPickerComponent, TableToolbarComponent, TextComponent, TextInputComponent, TextTemplatePickerComponent, TextareaInputComponent, TimeInputComponent, TimelineComponent, ToastComponent, ToastService, ToggleBadgeComponent, ToggleComponent, TooltipDirective, US_LOCATIONS, US_STATES, US_STATE_OPTIONS, US_ZIP_PATTERN, UiFieldValidity, acceptLabel, appShellGroupsStorageKey, autoVariant, blockHasContent, buildDefaultSchedule, buildPreviewDocument, buildVideoBlockHtml, builtInActionIcon, businessTimeOptions, callHost, conversationDateLabel, conversationHtmlToText, conversationInitial, conversationMessageStatusLabel, conversationMessageStatusMark, createFieldReveal, createPasswordPolicyValidator, decodeFilterValues, digitsOnly, downloadBlob, emailShareUrl, emptyAddress, encodeFilterValue, encodeFilterValues, errorContextInterceptor, escapeHtml, facebookShareUrl, fileMatchesAccept, fileNameFromContentDisposition, formatAddress, formatAddressValue, formatAddressValueOneLine, formatCategoryLabel, formatConversationPhone, formatConversationTime, formatCurrency, formatDuration, formatFileSize, formatIsoDate, formatIsoDateTime, formatMessageTime, formatPhone, formatPhoneDisplay, formatShortDate, formatTime, formatVideoDuration, getEligibleIds, getEligibleOptions, getErrorMessage, getInitials, gmailShareUrl, groupMessagesByDay, hostErrorMessage, humanReadableMessage, iconPath, insideEditorBlock, integrationPlainText, integrationsForApp, integrationsOnlyFor, isBlockDrag, isEmptyAddress, isValidAmount, isValidEmailAddress, isValidZip, isWebUrl, isoKey, issueToErrors, last4Error, linkedInShareUrl, maxLengthIssue, mergeDescribedBy, normalizeAddress, normalizeHexColor, outlookShareUrl, parseAddressOneLine, parseAddressValue, parseBizHours, parseIso, parseTime, passwordMeetsRules, periodGroup, pillTabDescriptionId, pillTabId, pillTabPanelId, pillTabTitleId, pluralize, provideForgerouteToast, reorderItems, requiredIssue, resolveLayoutGap, resolvePreset, serializeBizHours, serializedTextLength, setupIntegrations, splitIntro, terminalTimeoutText, terminalVerdict, todayInTimezone, truncateConversationText, xShareUrl };
60902
62079
 
60903
62080
  //# sourceMappingURL=forgeroute-ui.mjs.map