valtech-components 2.0.963 → 2.0.964

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.
Files changed (33) hide show
  1. package/esm2022/lib/components/molecules/content-card/content-card.component.mjs +86 -0
  2. package/esm2022/lib/components/molecules/content-card/types.mjs +11 -0
  3. package/esm2022/lib/components/molecules/info-card/info-card.component.mjs +126 -0
  4. package/esm2022/lib/components/molecules/info-card/types.mjs +11 -0
  5. package/esm2022/lib/components/molecules/metric-card/metric-card.component.mjs +146 -0
  6. package/esm2022/lib/components/molecules/metric-card/types.mjs +10 -0
  7. package/esm2022/lib/components/molecules/pill/pill.component.mjs +100 -105
  8. package/esm2022/lib/components/molecules/pill/types.mjs +1 -1
  9. package/esm2022/lib/components/organisms/article-strip/article-strip.component.mjs +127 -0
  10. package/esm2022/lib/components/organisms/article-strip/types.mjs +8 -0
  11. package/esm2022/lib/components/organisms/auth-cta/auth-cta.component.mjs +180 -0
  12. package/esm2022/lib/components/organisms/auth-cta/types.mjs +9 -0
  13. package/esm2022/lib/services/requests/request.service.mjs +11 -4
  14. package/esm2022/lib/version.mjs +2 -2
  15. package/esm2022/public-api.mjs +12 -1
  16. package/fesm2022/valtech-components.mjs +811 -124
  17. package/fesm2022/valtech-components.mjs.map +1 -1
  18. package/lib/components/molecules/article-card/article-card.component.d.ts +1 -1
  19. package/lib/components/molecules/content-card/content-card.component.d.ts +26 -0
  20. package/lib/components/molecules/content-card/types.d.ts +30 -0
  21. package/lib/components/molecules/info-card/info-card.component.d.ts +37 -0
  22. package/lib/components/molecules/info-card/types.d.ts +44 -0
  23. package/lib/components/molecules/metric-card/metric-card.component.d.ts +34 -0
  24. package/lib/components/molecules/metric-card/types.d.ts +46 -0
  25. package/lib/components/molecules/pill/pill.component.d.ts +10 -26
  26. package/lib/components/molecules/pill/types.d.ts +76 -35
  27. package/lib/components/organisms/article-strip/article-strip.component.d.ts +38 -0
  28. package/lib/components/organisms/article-strip/types.d.ts +29 -0
  29. package/lib/components/organisms/auth-cta/auth-cta.component.d.ts +44 -0
  30. package/lib/components/organisms/auth-cta/types.d.ts +42 -0
  31. package/lib/version.d.ts +1 -1
  32. package/package.json +1 -1
  33. package/public-api.d.ts +10 -0
@@ -23,7 +23,7 @@ import { IonicModule, ToastController, NavController } from '@ionic/angular';
23
23
  import { isSupported, getMessaging as getMessaging$1 } from 'firebase/messaging';
24
24
  import { getApps, getApp, initializeApp as initializeApp$1 } from 'firebase/app';
25
25
  import * as i2$1 from '@ionic/angular/standalone';
26
- import { AlertController, IonAvatar, IonCard, IonIcon, IonButton, IonSpinner, IonText, IonModal, IonHeader, IonToolbar, IonContent, IonButtons, IonTitle, IonProgressBar, IonSkeletonText, IonFab, IonFabButton, IonFabList, IonLabel, IonCardContent, IonCardHeader, IonCardTitle, IonCardSubtitle, IonCheckbox, IonTextarea, IonDatetime, IonDatetimeButton, IonInput, IonSelect, IonSelectOption, IonPopover, IonList, IonItem, IonRadioGroup, IonRadio, IonRange, IonSearchbar, IonSegment, IonSegmentButton, IonToggle, IonAccordion, IonAccordionGroup, IonTabBar, IonTabButton, IonBadge, IonBreadcrumb, IonBreadcrumbs, IonChip, IonNote, ToastController as ToastController$1, IonCol, IonRow, IonRefresher, IonRefresherContent, IonRippleEffect, IonMenuButton, IonFooter, IonListHeader, IonInfiniteScroll, IonInfiniteScrollContent, IonGrid, MenuController, IonMenu, IonMenuToggle, IonSplitPane } from '@ionic/angular/standalone';
26
+ import { AlertController, IonAvatar, IonCard, IonIcon, IonButton, IonSpinner, IonText, IonModal, IonHeader, IonToolbar, IonContent, IonButtons, IonTitle, IonProgressBar, IonSkeletonText, IonFab, IonFabButton, IonFabList, IonLabel, IonCardContent, IonCardHeader, IonCardTitle, IonCardSubtitle, IonCheckbox, IonTextarea, IonDatetime, IonDatetimeButton, IonInput, IonSelect, IonSelectOption, IonPopover, IonList, IonItem, IonRadioGroup, IonRadio, IonRange, IonSearchbar, IonSegment, IonSegmentButton, IonToggle, IonRippleEffect, IonAccordion, IonAccordionGroup, IonTabBar, IonTabButton, IonBadge, IonBreadcrumb, IonBreadcrumbs, IonChip, IonNote, ToastController as ToastController$1, IonCol, IonRow, IonRefresher, IonRefresherContent, IonMenuButton, IonFooter, IonListHeader, IonInfiniteScroll, IonInfiniteScrollContent, IonGrid, MenuController, IonMenu, IonMenuToggle, IonSplitPane } from '@ionic/angular/standalone';
27
27
  import { addIcons } from 'ionicons';
28
28
  import { addOutline, addCircleOutline, alertOutline, alertCircleOutline, arrowBackOutline, arrowForwardOutline, arrowDownOutline, settings, settingsOutline, checkmarkCircleOutline, ellipsisHorizontalOutline, notifications, notificationsOutline, openOutline, closeOutline, chatbubblesOutline, shareOutline, heart, heartOutline, home, homeOutline, eyeOffOutline, eyeOutline, scanOutline, chevronDownOutline, chevronForwardOutline, checkmarkOutline, clipboardOutline, copyOutline, filterOutline, locationOutline, calendarOutline, businessOutline, logoTwitter, logoInstagram, logoLinkedin, logoYoutube, logoTiktok, logoFacebook, logoGoogle, createOutline, trashOutline, playOutline, peopleOutline, phonePortraitOutline, refreshOutline, documentTextOutline, lockClosedOutline, informationCircleOutline, logoNpm, removeOutline, optionsOutline, personOutline, shieldCheckmarkOutline, keyOutline, desktopOutline, logOutOutline, cloudDownloadOutline, cloudOutline, gitBranchOutline, layersOutline, serverOutline, warningOutline, bulbOutline, lockOpenOutline, diamondOutline, add, close, share, create, trash, star, camera, mic, send, downloadOutline, chevronDown, language, globeOutline, checkmark, list, grid, apps, menu, search, person, helpCircle, informationCircle, documentText, mail, calendar, folder, chevronForward, ellipsisHorizontal, chevronBack, playBack, playForward, ellipse, starOutline, starHalf, heartHalf, checkmarkCircle, timeOutline, flag, trendingUp, trendingDown, remove, analytics, people, cash, cart, eye, chatbubbleOutline, thumbsUpOutline, thumbsUp, happyOutline, happy, sadOutline, sad, chevronUp, pin, pencil, callOutline, logoWhatsapp, paperPlaneOutline, mailOutline, chevronDownCircleOutline, closeCircle, alertCircle, logoApple, logoMicrosoft, linkOutline, unlinkOutline, cloudOfflineOutline, documentOutline, attachOutline, cameraOutline, closeCircleOutline, imageOutline, chevronBackOutline, sendOutline, chatbubbleEllipsesOutline, swapVerticalOutline, chevronUpOutline, searchOutline, cartOutline, chatbubble, compass, compassOutline, gridOutline, listOutline, folderOutline, documents, documentsOutline, statsChart, statsChartOutline, menuOutline } from 'ionicons/icons';
29
29
  import { Browser } from '@capacitor/browser';
@@ -54,7 +54,7 @@ import 'prismjs/components/prism-json';
54
54
  * Current version of valtech-components.
55
55
  * This is automatically updated during the publish process.
56
56
  */
57
- const VERSION = '2.0.963';
57
+ const VERSION = '2.0.964';
58
58
 
59
59
  // Control de estado de refresco (singleton a nivel de módulo)
60
60
  let isRefreshing = false;
@@ -16009,7 +16009,7 @@ i0.ɵɵngDeclareClassMetadata({ minVersion: "12.0.0", version: "18.2.14", ngImpo
16009
16009
  * resolveColor('--my-custom-color'); // returns 'var(--my-custom-color)'
16010
16010
  * resolveColor('#ff0000'); // returns '#ff0000'
16011
16011
  */
16012
- function resolveColor(color) {
16012
+ function resolveColor$1(color) {
16013
16013
  // Si el color empieza con "--", se asume que es una variable CSS válida
16014
16014
  if (color.startsWith('--')) {
16015
16015
  return `var(${color})`;
@@ -16064,7 +16064,7 @@ class ExpandableTextComponent {
16064
16064
  this.expanded = !this.expanded;
16065
16065
  }
16066
16066
  color() {
16067
- return resolveColor(this.props.color || this.defaultColor);
16067
+ return resolveColor$1(this.props.color || this.defaultColor);
16068
16068
  }
16069
16069
  static { this.ɵfac = i0.ɵɵngDeclareFactory({ minVersion: "12.0.0", version: "18.2.14", ngImport: i0, type: ExpandableTextComponent, deps: [], target: i0.ɵɵFactoryTarget.Component }); }
16070
16070
  static { this.ɵcmp = i0.ɵɵngDeclareComponent({ minVersion: "17.0.0", version: "18.2.14", type: ExpandableTextComponent, isStandalone: true, selector: "val-expandable-text", inputs: { props: "props" }, ngImport: i0, template: `
@@ -16987,7 +16987,7 @@ class LayeredCardComponent {
16987
16987
  if (!background) {
16988
16988
  return '';
16989
16989
  }
16990
- return resolveColor(background);
16990
+ return resolveColor$1(background);
16991
16991
  }
16992
16992
  static { this.ɵfac = i0.ɵɵngDeclareFactory({ minVersion: "12.0.0", version: "18.2.14", ngImport: i0, type: LayeredCardComponent, deps: [], target: i0.ɵɵFactoryTarget.Component }); }
16993
16993
  static { this.ɵcmp = i0.ɵɵngDeclareComponent({ minVersion: "17.0.0", version: "18.2.14", type: LayeredCardComponent, isStandalone: true, selector: "layered-card", inputs: { props: "props" }, ngImport: i0, template: `
@@ -19319,102 +19319,95 @@ i0.ɵɵngDeclareClassMetadata({ minVersion: "12.0.0", version: "18.2.14", ngImpo
19319
19319
  type: Input
19320
19320
  }] } });
19321
19321
 
19322
- /**
19323
- * val-pill
19324
- *
19325
- * Has two modes:
19326
- *
19327
- * 1. **Card mode** (legacy) — pass `content` (`ActionHeaderMetadata`). Renders a
19328
- * large fun-card with a title + action. Backwards compatible.
19329
- *
19330
- * 2. **Text-pill / badge mode** — pass `label`. Renders a compact rounded pill
19331
- * with configurable `color`, `weight`, `size`, optional `icon`, and an
19332
- * optional click action (`clickable` → emits `pillClick`).
19333
- *
19334
- * @example Text-pill (badge):
19335
- * <val-pill [props]="{ label: 'v1.2.0', color: 'dark', weight: 'bold' }" />
19336
- *
19337
- * @example Clickable text-pill:
19338
- * <val-pill
19339
- * [props]="{ label: 'Beta', color: 'primary', clickable: true }"
19340
- * (pillClick)="onClick($event)"
19341
- * />
19342
- *
19343
- * @example Card mode (legacy):
19344
- * <val-pill [props]="{ background: '#fff', bordered: true, content: {...} }" />
19345
- *
19346
- * @input preset: string - Name of preset to apply
19347
- * @input props: PillMetadata - Configuration for the pill
19348
- * @output pillClick: PillClickEvent - Emits when a clickable text-pill is activated
19349
- */
19322
+ const IONIC_COLORS$9 = ['primary', 'secondary', 'tertiary', 'success', 'warning', 'danger', 'light', 'medium', 'dark'];
19350
19323
  class PillComponent {
19351
19324
  constructor() {
19352
- this.theme = inject(ThemeService);
19353
19325
  this.presets = inject(PresetService);
19354
- /**
19355
- * Pill configuration object. Values here override preset values.
19356
- */
19326
+ /** Pill configuration. Overrides preset values when both are set. */
19357
19327
  this.props = {};
19358
- /**
19359
- * Emits when a clickable text-pill is activated (click / Enter / Space).
19360
- */
19328
+ /** Emits when a clickable badge pill is activated. */
19361
19329
  this.pillClick = new EventEmitter();
19362
- /**
19363
- * Resolved props after merging preset + explicit props.
19364
- */
19330
+ /** Emits when a notification-pill action button is pressed. */
19331
+ this.pillAction = new EventEmitter();
19365
19332
  this.resolvedProps = {};
19366
19333
  }
19367
19334
  ngOnInit() {
19368
19335
  this.resolveProps();
19369
19336
  }
19370
19337
  ngOnChanges(changes) {
19371
- if (changes['preset'] || changes['props']) {
19338
+ if (changes['preset'] || changes['props'])
19372
19339
  this.resolveProps();
19373
- }
19374
19340
  }
19375
- /**
19376
- * Merge preset configuration with explicit props.
19377
- * Explicit props take precedence over preset values.
19378
- */
19379
19341
  resolveProps() {
19380
19342
  const presetProps = this.preset ? this.presets.get('pill', this.preset) : {};
19381
- this.resolvedProps = {
19382
- ...presetProps,
19383
- ...this.props,
19384
- };
19343
+ this.resolvedProps = { ...presetProps, ...this.props };
19344
+ }
19345
+ get isNotificationPill() {
19346
+ return !!this.resolvedProps.notification && !this.resolvedProps.label;
19385
19347
  }
19386
- /** Text-pill mode is active when a `label` is provided. */
19387
19348
  get isTextPill() {
19388
19349
  return !!this.resolvedProps.label;
19389
19350
  }
19390
- /** Color variant for the text-pill, with a sensible default. */
19391
19351
  get pillColor() {
19392
19352
  return this.resolvedProps.color || 'medium';
19393
19353
  }
19394
- /** Font weight for the text-pill, with a sensible default. */
19395
19354
  get pillWeight() {
19396
19355
  return this.resolvedProps.weight || 'medium';
19397
19356
  }
19398
- /** Size for the text-pill, with a sensible default. */
19399
19357
  get pillSize() {
19400
19358
  return this.resolvedProps.size || 'small';
19401
19359
  }
19402
- /** Handles activation of a clickable text-pill. */
19360
+ getIconColor() {
19361
+ const c = this.resolvedProps.notification?.iconColor || 'warning';
19362
+ return IONIC_COLORS$9.includes(c) ? `var(--ion-color-${c})` : c;
19363
+ }
19403
19364
  onPillClick(event) {
19404
- if (!this.resolvedProps.clickable) {
19365
+ if (!this.resolvedProps.clickable)
19405
19366
  return;
19406
- }
19407
- // For the Space key, prevent the page from scrolling.
19408
19367
  event?.preventDefault();
19409
- this.pillClick.emit({
19410
- token: this.resolvedProps.token,
19411
- label: this.resolvedProps.label,
19412
- });
19368
+ this.pillClick.emit({ token: this.resolvedProps.token, label: this.resolvedProps.label });
19369
+ }
19370
+ onActionClick(actionToken, event) {
19371
+ event.stopPropagation();
19372
+ this.pillAction.emit({ actionToken, pillToken: this.resolvedProps.token });
19413
19373
  }
19414
19374
  static { this.ɵfac = i0.ɵɵngDeclareFactory({ minVersion: "12.0.0", version: "18.2.14", ngImport: i0, type: PillComponent, deps: [], target: i0.ɵɵFactoryTarget.Component }); }
19415
- static { this.ɵcmp = i0.ɵɵngDeclareComponent({ minVersion: "17.0.0", version: "18.2.14", type: PillComponent, isStandalone: true, selector: "val-pill", inputs: { preset: "preset", props: "props" }, outputs: { pillClick: "pillClick" }, usesOnChanges: true, ngImport: i0, template: `
19416
- @if (isTextPill) {
19417
- <!-- Text-pill / badge mode -->
19375
+ static { this.ɵcmp = i0.ɵɵngDeclareComponent({ minVersion: "17.0.0", version: "18.2.14", type: PillComponent, isStandalone: true, selector: "val-pill", inputs: { preset: "preset", props: "props" }, outputs: { pillClick: "pillClick", pillAction: "pillAction" }, usesOnChanges: true, ngImport: i0, template: `
19376
+ @if (isNotificationPill) {
19377
+ <!-- Notification mode -->
19378
+ <div class="notif-pill" [attr.aria-live]="'polite'">
19379
+ @if (resolvedProps.notification?.icon) {
19380
+ <div class="notif-pill__icon-wrap" [style.color]="getIconColor()">
19381
+ <ion-icon [name]="resolvedProps.notification!.icon!" />
19382
+ </div>
19383
+ }
19384
+
19385
+ <div class="notif-pill__content">
19386
+ @if (resolvedProps.notification?.time) {
19387
+ <span class="notif-pill__time">{{ resolvedProps.notification!.time }}</span>
19388
+ }
19389
+ <span class="notif-pill__title">{{ resolvedProps.notification!.title }}</span>
19390
+ @if (resolvedProps.notification?.body) {
19391
+ <span class="notif-pill__body">{{ resolvedProps.notification!.body }}</span>
19392
+ }
19393
+ </div>
19394
+
19395
+ @if (resolvedProps.notification?.actions?.length) {
19396
+ <div class="notif-pill__actions">
19397
+ @for (action of resolvedProps.notification!.actions!; track action.token) {
19398
+ <button
19399
+ class="notif-pill__action-btn"
19400
+ [attr.aria-label]="action.ariaLabel || action.token"
19401
+ (click)="onActionClick(action.token, $event)"
19402
+ >
19403
+ <ion-icon [name]="action.icon" />
19404
+ </button>
19405
+ }
19406
+ </div>
19407
+ }
19408
+ </div>
19409
+ } @else if (isTextPill) {
19410
+ <!-- Badge mode -->
19418
19411
  <span
19419
19412
  class="val-pill"
19420
19413
  [class.val-pill--clickable]="resolvedProps.clickable"
@@ -19427,7 +19420,7 @@ class PillComponent {
19427
19420
  [class.val-pill--w-bold]="pillWeight === 'bold'"
19428
19421
  [style.--val-pill-color]="'var(--ion-color-' + pillColor + ')'"
19429
19422
  [style.--val-pill-color-rgb]="'var(--ion-color-' + pillColor + '-rgb)'"
19430
- [style.--val-pill-contrast]="'var(--ion-color-' + pillColor + '-contrast)'"
19423
+ [style.--val-pill-color-contrast]="'var(--ion-color-' + pillColor + '-contrast)'"
19431
19424
  [attr.role]="resolvedProps.clickable ? 'button' : null"
19432
19425
  [attr.tabindex]="resolvedProps.clickable ? 0 : null"
19433
19426
  [attr.aria-label]="resolvedProps.clickable ? resolvedProps.ariaLabel || resolvedProps.label : null"
@@ -19440,29 +19433,47 @@ class PillComponent {
19440
19433
  }
19441
19434
  <span class="val-pill__label">{{ resolvedProps.label }}</span>
19442
19435
  </span>
19443
- } @else {
19444
- <!-- Card mode (legacy fun-card) -->
19445
- <div
19446
- [id]="resolvedProps.token"
19447
- class="fun-card"
19448
- [class.bordered]="resolvedProps.bordered"
19449
- [class.hoverable]="resolvedProps.hoverable"
19450
- [ngStyle]="{
19451
- background: theme.IsDark ? 'var(--ion-background-color)' : resolvedProps.background,
19452
- }"
19453
- >
19454
- @if (resolvedProps.content) {
19455
- <val-action-header style="width: 100%;" [props]="resolvedProps.content" />
19456
- }
19457
- </div>
19458
19436
  }
19459
- `, isInline: true, styles: ["@charset \"UTF-8\";:root{--val-container-sm: 540px;--val-container-md: 720px;--val-container-lg: 880px;--val-container-xl: 1100px;--val-container-padding: 16px;--ion-color-primary: #7026df;--ion-color-primary-rgb: 112, 38, 223;--ion-color-primary-contrast: #ffffff;--ion-color-primary-contrast-rgb: 255, 255, 255;--ion-color-primary-shade: #6321c4;--ion-color-primary-tint: #7e3ce2;--ion-color-secondary: #e2ccff;--ion-color-secondary-rgb: 226, 204, 255;--ion-color-secondary-contrast: #000000;--ion-color-secondary-contrast-rgb: 0, 0, 0;--ion-color-secondary-shade: #c7b4e0;--ion-color-secondary-tint: #e5d1ff;--ion-color-texti: #354c69;--ion-color-texti-rgb: 53, 76, 105;--ion-color-texti-contrast: #ffffff;--ion-color-texti-contrast-rgb: 255, 255, 255;--ion-color-texti-shade: #2f435c;--ion-color-texti-tint: #495e78;--ion-color-darki: #090f1b;--ion-color-darki-rgb: 9, 15, 27;--ion-color-darki-contrast: #ffffff;--ion-color-darki-contrast-rgb: 255, 255, 255;--ion-color-darki-shade: #080d18;--ion-color-darki-tint: #222732;--ion-color-medium: #9e9e9e;--ion-color-medium-rgb: 158, 158, 158;--ion-color-medium-contrast: #000000;--ion-color-medium-contrast-rgb: 0, 0, 0;--ion-color-medium-shade: #8b8b8b;--ion-color-medium-tint: #a8a8a8;--swiper-pagination-color: var(--ion-color-primary);--swiper-navigation-color: var(--ion-color-primary);--swiper-pagination-bullet-inactive-color: var(--ion-color-medium)}body.dark,html.ion-palette-dark,body[data-theme=dark]{--ion-color-texti: #8fc1ff;--ion-color-texti-rgb: 143, 193, 255;--ion-color-texti-contrast: #000000;--ion-color-texti-contrast-rgb: 0, 0, 0;--ion-color-texti-shade: #7eaae0;--ion-color-texti-tint: #9ac7ff;--ion-color-darki: #ffffff;--ion-color-darki-rgb: 255, 255, 255;--ion-color-darki-contrast: #000000;--ion-color-darki-contrast-rgb: 0, 0, 0;--ion-color-darki-shade: #e0e0e0;--ion-color-darki-tint: #ffffff;--ion-color-primary: #8f49f8;--ion-color-primary-rgb: 143, 73, 248;--ion-color-primary-contrast: #ffffff;--ion-color-primary-contrast-rgb: 255, 255, 255;--ion-color-primary-shade: #7e40da;--ion-color-primary-tint: #9a5bf9}.ion-color-texti{--ion-color-base: var(--ion-color-texti);--ion-color-base-rgb: var(--ion-color-texti-rgb);--ion-color-contrast: var(--ion-color-texti-contrast);--ion-color-contrast-rgb: var(--ion-color-texti-contrast-rgb);--ion-color-shade: var(--ion-color-texti-shade);--ion-color-tint: var(--ion-color-texti-tint)}.ion-color-darki{--ion-color-base: var(--ion-color-darki);--ion-color-base-rgb: var(--ion-color-darki-rgb);--ion-color-contrast: var(--ion-color-darki-contrast);--ion-color-contrast-rgb: var(--ion-color-darki-contrast-rgb);--ion-color-shade: var(--ion-color-darki-shade);--ion-color-tint: var(--ion-color-darki-tint)}.fun-card{z-index:0;position:relative;margin-bottom:8px;cursor:pointer;background:var(--ion-card-background, var(--ion-item-background, var(--ion-background-color, #fff)));display:flex;border-radius:48px;align-items:start;padding:8px 8px 8px 24px;flex-direction:column;box-shadow:0 .25rem .75rem #12195412}.fun-card.hoverable{transition:transform .3s ease,box-shadow .3s ease}.fun-card.hoverable:hover{transform:scale(1.01);box-shadow:.1875rem .625rem .5rem #1219541a}.bordered{border:.0625rem solid var(--ion-color-medium)}.val-pill{display:inline-flex;align-items:center;gap:6px;border-radius:999px;white-space:nowrap;line-height:1;background:rgba(var(--val-pill-color-rgb),.12);color:var(--val-pill-color);border:.0625rem solid rgba(var(--val-pill-color-rgb),.22);transition:background .15s ease,transform .15s ease,box-shadow .15s ease}.val-pill__icon{font-size:1em;flex-shrink:0}.val-pill__label{display:inline-block}.val-pill--solid{background:var(--val-pill-color);color:var(--val-pill-contrast);border-color:var(--val-pill-color)}.val-pill--small{padding:5px 12px;font-size:.75rem}.val-pill--medium{padding:7px 14px;font-size:.875rem}.val-pill--large{padding:9px 18px;font-size:1rem}.val-pill--w-normal{font-weight:400}.val-pill--w-medium{font-weight:600}.val-pill--w-bold{font-weight:700}.val-pill--clickable{cursor:pointer;-webkit-tap-highlight-color:transparent}.val-pill--clickable:hover{background:rgba(var(--val-pill-color-rgb),.2);transform:translateY(-1px)}.val-pill--clickable:active{transform:translateY(0) scale(.98)}.val-pill--clickable:focus-visible{outline:none;box-shadow:0 0 0 3px rgba(var(--val-pill-color-rgb),.3)}.val-pill--clickable.val-pill--solid:hover{filter:brightness(1.08)}:host-context(body.dark) .val-pill:not(.val-pill--solid),:host-context(html.ion-palette-dark) .val-pill:not(.val-pill--solid),:host-context([data-theme=dark]) .val-pill:not(.val-pill--solid){background:rgba(var(--val-pill-color-rgb),.22);border-color:rgba(var(--val-pill-color-rgb),.32)}\n"], dependencies: [{ kind: "ngmodule", type: CommonModule }, { kind: "directive", type: i1$5.NgStyle, selector: "[ngStyle]", inputs: ["ngStyle"] }, { kind: "component", type: ActionHeaderComponent, selector: "val-action-header", inputs: ["props"] }, { kind: "component", type: IonIcon, selector: "ion-icon", inputs: ["color", "flipRtl", "icon", "ios", "lazy", "md", "mode", "name", "sanitize", "size", "src"] }] }); }
19437
+ `, isInline: true, styles: ["@charset \"UTF-8\";:root{--val-container-sm: 540px;--val-container-md: 720px;--val-container-lg: 880px;--val-container-xl: 1100px;--val-container-padding: 16px;--ion-color-primary: #7026df;--ion-color-primary-rgb: 112, 38, 223;--ion-color-primary-contrast: #ffffff;--ion-color-primary-contrast-rgb: 255, 255, 255;--ion-color-primary-shade: #6321c4;--ion-color-primary-tint: #7e3ce2;--ion-color-secondary: #e2ccff;--ion-color-secondary-rgb: 226, 204, 255;--ion-color-secondary-contrast: #000000;--ion-color-secondary-contrast-rgb: 0, 0, 0;--ion-color-secondary-shade: #c7b4e0;--ion-color-secondary-tint: #e5d1ff;--ion-color-texti: #354c69;--ion-color-texti-rgb: 53, 76, 105;--ion-color-texti-contrast: #ffffff;--ion-color-texti-contrast-rgb: 255, 255, 255;--ion-color-texti-shade: #2f435c;--ion-color-texti-tint: #495e78;--ion-color-darki: #090f1b;--ion-color-darki-rgb: 9, 15, 27;--ion-color-darki-contrast: #ffffff;--ion-color-darki-contrast-rgb: 255, 255, 255;--ion-color-darki-shade: #080d18;--ion-color-darki-tint: #222732;--ion-color-medium: #9e9e9e;--ion-color-medium-rgb: 158, 158, 158;--ion-color-medium-contrast: #000000;--ion-color-medium-contrast-rgb: 0, 0, 0;--ion-color-medium-shade: #8b8b8b;--ion-color-medium-tint: #a8a8a8;--swiper-pagination-color: var(--ion-color-primary);--swiper-navigation-color: var(--ion-color-primary);--swiper-pagination-bullet-inactive-color: var(--ion-color-medium)}body.dark,html.ion-palette-dark,body[data-theme=dark]{--ion-color-texti: #8fc1ff;--ion-color-texti-rgb: 143, 193, 255;--ion-color-texti-contrast: #000000;--ion-color-texti-contrast-rgb: 0, 0, 0;--ion-color-texti-shade: #7eaae0;--ion-color-texti-tint: #9ac7ff;--ion-color-darki: #ffffff;--ion-color-darki-rgb: 255, 255, 255;--ion-color-darki-contrast: #000000;--ion-color-darki-contrast-rgb: 0, 0, 0;--ion-color-darki-shade: #e0e0e0;--ion-color-darki-tint: #ffffff;--ion-color-primary: #8f49f8;--ion-color-primary-rgb: 143, 73, 248;--ion-color-primary-contrast: #ffffff;--ion-color-primary-contrast-rgb: 255, 255, 255;--ion-color-primary-shade: #7e40da;--ion-color-primary-tint: #9a5bf9}.ion-color-texti{--ion-color-base: var(--ion-color-texti);--ion-color-base-rgb: var(--ion-color-texti-rgb);--ion-color-contrast: var(--ion-color-texti-contrast);--ion-color-contrast-rgb: var(--ion-color-texti-contrast-rgb);--ion-color-shade: var(--ion-color-texti-shade);--ion-color-tint: var(--ion-color-texti-tint)}.ion-color-darki{--ion-color-base: var(--ion-color-darki);--ion-color-base-rgb: var(--ion-color-darki-rgb);--ion-color-contrast: var(--ion-color-darki-contrast);--ion-color-contrast-rgb: var(--ion-color-darki-contrast-rgb);--ion-color-shade: var(--ion-color-darki-shade);--ion-color-tint: var(--ion-color-darki-tint)}.val-pill{display:inline-flex;align-items:center;gap:6px;border-radius:999px;white-space:nowrap;line-height:1;background:rgba(var(--val-pill-color-rgb),.12);color:var(--val-pill-color);border:.0625rem solid rgba(var(--val-pill-color-rgb),.22);transition:background .15s ease,transform .15s ease,box-shadow .15s ease}.val-pill__icon{font-size:1em;flex-shrink:0}.val-pill__label{display:inline-block}.val-pill--solid{background:var(--val-pill-color);color:var(--val-pill-color-contrast);border-color:var(--val-pill-color)}.val-pill--small{padding:5px 12px;font-size:.75rem}.val-pill--medium{padding:7px 14px;font-size:.875rem}.val-pill--large{padding:9px 18px;font-size:1rem}.val-pill--w-normal{font-weight:400}.val-pill--w-medium{font-weight:600}.val-pill--w-bold{font-weight:700}.val-pill--clickable{cursor:pointer;-webkit-tap-highlight-color:transparent}.val-pill--clickable:hover{background:rgba(var(--val-pill-color-rgb),.2);transform:translateY(-1px)}.val-pill--clickable:active{transform:translateY(0) scale(.98)}.val-pill--clickable:focus-visible{outline:none;box-shadow:0 0 0 3px rgba(var(--val-pill-color-rgb),.3)}.val-pill--clickable.val-pill--solid:hover{filter:brightness(1.08)}:host-context(body.dark) .val-pill:not(.val-pill--solid),:host-context(html.ion-palette-dark) .val-pill:not(.val-pill--solid),:host-context([data-theme=dark]) .val-pill:not(.val-pill--solid){background:rgba(var(--val-pill-color-rgb),.22);border-color:rgba(var(--val-pill-color-rgb),.32)}.notif-pill{display:inline-flex;align-items:center;gap:12px;padding:10px 14px;border-radius:999px;background:var(--ion-color-dark);color:var(--ion-color-dark-contrast);max-width:100%;box-sizing:border-box;box-shadow:.1875rem .625rem .5rem #1219541a}.notif-pill__icon-wrap{display:flex;align-items:center;justify-content:center;flex-shrink:0;width:32px;height:32px;border-radius:50%;background:#ffffff1a;font-size:1rem}.notif-pill__content{display:flex;align-items:baseline;gap:8px;flex:1;min-width:0;overflow:hidden}.notif-pill__time{font-size:.72rem;font-weight:600;opacity:.55;flex-shrink:0;letter-spacing:.02em}.notif-pill__title{font-size:.875rem;font-weight:600;white-space:nowrap;overflow:hidden;text-overflow:ellipsis}.notif-pill__body{font-size:.75rem;opacity:.7;white-space:nowrap;overflow:hidden;text-overflow:ellipsis;flex-shrink:1}.notif-pill__actions{display:flex;align-items:center;gap:6px;flex-shrink:0;margin-left:4px}.notif-pill__action-btn{display:flex;align-items:center;justify-content:center;width:30px;height:30px;border-radius:50%;border:none;background:#ffffff1f;color:var(--ion-color-dark-contrast);cursor:pointer;font-size:.9rem;transition:background .15s ease,transform .1s ease;-webkit-tap-highlight-color:transparent}.notif-pill__action-btn:hover{background:#ffffff38}.notif-pill__action-btn:active{transform:scale(.9)}.notif-pill__action-btn:focus-visible{outline:none;box-shadow:0 0 0 2px #ffffff80}\n"], dependencies: [{ kind: "ngmodule", type: CommonModule }, { kind: "component", type: IonIcon, selector: "ion-icon", inputs: ["color", "flipRtl", "icon", "ios", "lazy", "md", "mode", "name", "sanitize", "size", "src"] }] }); }
19460
19438
  }
19461
19439
  i0.ɵɵngDeclareClassMetadata({ minVersion: "12.0.0", version: "18.2.14", ngImport: i0, type: PillComponent, decorators: [{
19462
19440
  type: Component,
19463
- args: [{ selector: 'val-pill', standalone: true, imports: [CommonModule, ActionHeaderComponent, IonIcon], template: `
19464
- @if (isTextPill) {
19465
- <!-- Text-pill / badge mode -->
19441
+ args: [{ selector: 'val-pill', standalone: true, imports: [CommonModule, IonIcon, IonRippleEffect], template: `
19442
+ @if (isNotificationPill) {
19443
+ <!-- Notification mode -->
19444
+ <div class="notif-pill" [attr.aria-live]="'polite'">
19445
+ @if (resolvedProps.notification?.icon) {
19446
+ <div class="notif-pill__icon-wrap" [style.color]="getIconColor()">
19447
+ <ion-icon [name]="resolvedProps.notification!.icon!" />
19448
+ </div>
19449
+ }
19450
+
19451
+ <div class="notif-pill__content">
19452
+ @if (resolvedProps.notification?.time) {
19453
+ <span class="notif-pill__time">{{ resolvedProps.notification!.time }}</span>
19454
+ }
19455
+ <span class="notif-pill__title">{{ resolvedProps.notification!.title }}</span>
19456
+ @if (resolvedProps.notification?.body) {
19457
+ <span class="notif-pill__body">{{ resolvedProps.notification!.body }}</span>
19458
+ }
19459
+ </div>
19460
+
19461
+ @if (resolvedProps.notification?.actions?.length) {
19462
+ <div class="notif-pill__actions">
19463
+ @for (action of resolvedProps.notification!.actions!; track action.token) {
19464
+ <button
19465
+ class="notif-pill__action-btn"
19466
+ [attr.aria-label]="action.ariaLabel || action.token"
19467
+ (click)="onActionClick(action.token, $event)"
19468
+ >
19469
+ <ion-icon [name]="action.icon" />
19470
+ </button>
19471
+ }
19472
+ </div>
19473
+ }
19474
+ </div>
19475
+ } @else if (isTextPill) {
19476
+ <!-- Badge mode -->
19466
19477
  <span
19467
19478
  class="val-pill"
19468
19479
  [class.val-pill--clickable]="resolvedProps.clickable"
@@ -19475,7 +19486,7 @@ i0.ɵɵngDeclareClassMetadata({ minVersion: "12.0.0", version: "18.2.14", ngImpo
19475
19486
  [class.val-pill--w-bold]="pillWeight === 'bold'"
19476
19487
  [style.--val-pill-color]="'var(--ion-color-' + pillColor + ')'"
19477
19488
  [style.--val-pill-color-rgb]="'var(--ion-color-' + pillColor + '-rgb)'"
19478
- [style.--val-pill-contrast]="'var(--ion-color-' + pillColor + '-contrast)'"
19489
+ [style.--val-pill-color-contrast]="'var(--ion-color-' + pillColor + '-contrast)'"
19479
19490
  [attr.role]="resolvedProps.clickable ? 'button' : null"
19480
19491
  [attr.tabindex]="resolvedProps.clickable ? 0 : null"
19481
19492
  [attr.aria-label]="resolvedProps.clickable ? resolvedProps.ariaLabel || resolvedProps.label : null"
@@ -19488,29 +19499,16 @@ i0.ɵɵngDeclareClassMetadata({ minVersion: "12.0.0", version: "18.2.14", ngImpo
19488
19499
  }
19489
19500
  <span class="val-pill__label">{{ resolvedProps.label }}</span>
19490
19501
  </span>
19491
- } @else {
19492
- <!-- Card mode (legacy fun-card) -->
19493
- <div
19494
- [id]="resolvedProps.token"
19495
- class="fun-card"
19496
- [class.bordered]="resolvedProps.bordered"
19497
- [class.hoverable]="resolvedProps.hoverable"
19498
- [ngStyle]="{
19499
- background: theme.IsDark ? 'var(--ion-background-color)' : resolvedProps.background,
19500
- }"
19501
- >
19502
- @if (resolvedProps.content) {
19503
- <val-action-header style="width: 100%;" [props]="resolvedProps.content" />
19504
- }
19505
- </div>
19506
19502
  }
19507
- `, styles: ["@charset \"UTF-8\";:root{--val-container-sm: 540px;--val-container-md: 720px;--val-container-lg: 880px;--val-container-xl: 1100px;--val-container-padding: 16px;--ion-color-primary: #7026df;--ion-color-primary-rgb: 112, 38, 223;--ion-color-primary-contrast: #ffffff;--ion-color-primary-contrast-rgb: 255, 255, 255;--ion-color-primary-shade: #6321c4;--ion-color-primary-tint: #7e3ce2;--ion-color-secondary: #e2ccff;--ion-color-secondary-rgb: 226, 204, 255;--ion-color-secondary-contrast: #000000;--ion-color-secondary-contrast-rgb: 0, 0, 0;--ion-color-secondary-shade: #c7b4e0;--ion-color-secondary-tint: #e5d1ff;--ion-color-texti: #354c69;--ion-color-texti-rgb: 53, 76, 105;--ion-color-texti-contrast: #ffffff;--ion-color-texti-contrast-rgb: 255, 255, 255;--ion-color-texti-shade: #2f435c;--ion-color-texti-tint: #495e78;--ion-color-darki: #090f1b;--ion-color-darki-rgb: 9, 15, 27;--ion-color-darki-contrast: #ffffff;--ion-color-darki-contrast-rgb: 255, 255, 255;--ion-color-darki-shade: #080d18;--ion-color-darki-tint: #222732;--ion-color-medium: #9e9e9e;--ion-color-medium-rgb: 158, 158, 158;--ion-color-medium-contrast: #000000;--ion-color-medium-contrast-rgb: 0, 0, 0;--ion-color-medium-shade: #8b8b8b;--ion-color-medium-tint: #a8a8a8;--swiper-pagination-color: var(--ion-color-primary);--swiper-navigation-color: var(--ion-color-primary);--swiper-pagination-bullet-inactive-color: var(--ion-color-medium)}body.dark,html.ion-palette-dark,body[data-theme=dark]{--ion-color-texti: #8fc1ff;--ion-color-texti-rgb: 143, 193, 255;--ion-color-texti-contrast: #000000;--ion-color-texti-contrast-rgb: 0, 0, 0;--ion-color-texti-shade: #7eaae0;--ion-color-texti-tint: #9ac7ff;--ion-color-darki: #ffffff;--ion-color-darki-rgb: 255, 255, 255;--ion-color-darki-contrast: #000000;--ion-color-darki-contrast-rgb: 0, 0, 0;--ion-color-darki-shade: #e0e0e0;--ion-color-darki-tint: #ffffff;--ion-color-primary: #8f49f8;--ion-color-primary-rgb: 143, 73, 248;--ion-color-primary-contrast: #ffffff;--ion-color-primary-contrast-rgb: 255, 255, 255;--ion-color-primary-shade: #7e40da;--ion-color-primary-tint: #9a5bf9}.ion-color-texti{--ion-color-base: var(--ion-color-texti);--ion-color-base-rgb: var(--ion-color-texti-rgb);--ion-color-contrast: var(--ion-color-texti-contrast);--ion-color-contrast-rgb: var(--ion-color-texti-contrast-rgb);--ion-color-shade: var(--ion-color-texti-shade);--ion-color-tint: var(--ion-color-texti-tint)}.ion-color-darki{--ion-color-base: var(--ion-color-darki);--ion-color-base-rgb: var(--ion-color-darki-rgb);--ion-color-contrast: var(--ion-color-darki-contrast);--ion-color-contrast-rgb: var(--ion-color-darki-contrast-rgb);--ion-color-shade: var(--ion-color-darki-shade);--ion-color-tint: var(--ion-color-darki-tint)}.fun-card{z-index:0;position:relative;margin-bottom:8px;cursor:pointer;background:var(--ion-card-background, var(--ion-item-background, var(--ion-background-color, #fff)));display:flex;border-radius:48px;align-items:start;padding:8px 8px 8px 24px;flex-direction:column;box-shadow:0 .25rem .75rem #12195412}.fun-card.hoverable{transition:transform .3s ease,box-shadow .3s ease}.fun-card.hoverable:hover{transform:scale(1.01);box-shadow:.1875rem .625rem .5rem #1219541a}.bordered{border:.0625rem solid var(--ion-color-medium)}.val-pill{display:inline-flex;align-items:center;gap:6px;border-radius:999px;white-space:nowrap;line-height:1;background:rgba(var(--val-pill-color-rgb),.12);color:var(--val-pill-color);border:.0625rem solid rgba(var(--val-pill-color-rgb),.22);transition:background .15s ease,transform .15s ease,box-shadow .15s ease}.val-pill__icon{font-size:1em;flex-shrink:0}.val-pill__label{display:inline-block}.val-pill--solid{background:var(--val-pill-color);color:var(--val-pill-contrast);border-color:var(--val-pill-color)}.val-pill--small{padding:5px 12px;font-size:.75rem}.val-pill--medium{padding:7px 14px;font-size:.875rem}.val-pill--large{padding:9px 18px;font-size:1rem}.val-pill--w-normal{font-weight:400}.val-pill--w-medium{font-weight:600}.val-pill--w-bold{font-weight:700}.val-pill--clickable{cursor:pointer;-webkit-tap-highlight-color:transparent}.val-pill--clickable:hover{background:rgba(var(--val-pill-color-rgb),.2);transform:translateY(-1px)}.val-pill--clickable:active{transform:translateY(0) scale(.98)}.val-pill--clickable:focus-visible{outline:none;box-shadow:0 0 0 3px rgba(var(--val-pill-color-rgb),.3)}.val-pill--clickable.val-pill--solid:hover{filter:brightness(1.08)}:host-context(body.dark) .val-pill:not(.val-pill--solid),:host-context(html.ion-palette-dark) .val-pill:not(.val-pill--solid),:host-context([data-theme=dark]) .val-pill:not(.val-pill--solid){background:rgba(var(--val-pill-color-rgb),.22);border-color:rgba(var(--val-pill-color-rgb),.32)}\n"] }]
19503
+ `, styles: ["@charset \"UTF-8\";:root{--val-container-sm: 540px;--val-container-md: 720px;--val-container-lg: 880px;--val-container-xl: 1100px;--val-container-padding: 16px;--ion-color-primary: #7026df;--ion-color-primary-rgb: 112, 38, 223;--ion-color-primary-contrast: #ffffff;--ion-color-primary-contrast-rgb: 255, 255, 255;--ion-color-primary-shade: #6321c4;--ion-color-primary-tint: #7e3ce2;--ion-color-secondary: #e2ccff;--ion-color-secondary-rgb: 226, 204, 255;--ion-color-secondary-contrast: #000000;--ion-color-secondary-contrast-rgb: 0, 0, 0;--ion-color-secondary-shade: #c7b4e0;--ion-color-secondary-tint: #e5d1ff;--ion-color-texti: #354c69;--ion-color-texti-rgb: 53, 76, 105;--ion-color-texti-contrast: #ffffff;--ion-color-texti-contrast-rgb: 255, 255, 255;--ion-color-texti-shade: #2f435c;--ion-color-texti-tint: #495e78;--ion-color-darki: #090f1b;--ion-color-darki-rgb: 9, 15, 27;--ion-color-darki-contrast: #ffffff;--ion-color-darki-contrast-rgb: 255, 255, 255;--ion-color-darki-shade: #080d18;--ion-color-darki-tint: #222732;--ion-color-medium: #9e9e9e;--ion-color-medium-rgb: 158, 158, 158;--ion-color-medium-contrast: #000000;--ion-color-medium-contrast-rgb: 0, 0, 0;--ion-color-medium-shade: #8b8b8b;--ion-color-medium-tint: #a8a8a8;--swiper-pagination-color: var(--ion-color-primary);--swiper-navigation-color: var(--ion-color-primary);--swiper-pagination-bullet-inactive-color: var(--ion-color-medium)}body.dark,html.ion-palette-dark,body[data-theme=dark]{--ion-color-texti: #8fc1ff;--ion-color-texti-rgb: 143, 193, 255;--ion-color-texti-contrast: #000000;--ion-color-texti-contrast-rgb: 0, 0, 0;--ion-color-texti-shade: #7eaae0;--ion-color-texti-tint: #9ac7ff;--ion-color-darki: #ffffff;--ion-color-darki-rgb: 255, 255, 255;--ion-color-darki-contrast: #000000;--ion-color-darki-contrast-rgb: 0, 0, 0;--ion-color-darki-shade: #e0e0e0;--ion-color-darki-tint: #ffffff;--ion-color-primary: #8f49f8;--ion-color-primary-rgb: 143, 73, 248;--ion-color-primary-contrast: #ffffff;--ion-color-primary-contrast-rgb: 255, 255, 255;--ion-color-primary-shade: #7e40da;--ion-color-primary-tint: #9a5bf9}.ion-color-texti{--ion-color-base: var(--ion-color-texti);--ion-color-base-rgb: var(--ion-color-texti-rgb);--ion-color-contrast: var(--ion-color-texti-contrast);--ion-color-contrast-rgb: var(--ion-color-texti-contrast-rgb);--ion-color-shade: var(--ion-color-texti-shade);--ion-color-tint: var(--ion-color-texti-tint)}.ion-color-darki{--ion-color-base: var(--ion-color-darki);--ion-color-base-rgb: var(--ion-color-darki-rgb);--ion-color-contrast: var(--ion-color-darki-contrast);--ion-color-contrast-rgb: var(--ion-color-darki-contrast-rgb);--ion-color-shade: var(--ion-color-darki-shade);--ion-color-tint: var(--ion-color-darki-tint)}.val-pill{display:inline-flex;align-items:center;gap:6px;border-radius:999px;white-space:nowrap;line-height:1;background:rgba(var(--val-pill-color-rgb),.12);color:var(--val-pill-color);border:.0625rem solid rgba(var(--val-pill-color-rgb),.22);transition:background .15s ease,transform .15s ease,box-shadow .15s ease}.val-pill__icon{font-size:1em;flex-shrink:0}.val-pill__label{display:inline-block}.val-pill--solid{background:var(--val-pill-color);color:var(--val-pill-color-contrast);border-color:var(--val-pill-color)}.val-pill--small{padding:5px 12px;font-size:.75rem}.val-pill--medium{padding:7px 14px;font-size:.875rem}.val-pill--large{padding:9px 18px;font-size:1rem}.val-pill--w-normal{font-weight:400}.val-pill--w-medium{font-weight:600}.val-pill--w-bold{font-weight:700}.val-pill--clickable{cursor:pointer;-webkit-tap-highlight-color:transparent}.val-pill--clickable:hover{background:rgba(var(--val-pill-color-rgb),.2);transform:translateY(-1px)}.val-pill--clickable:active{transform:translateY(0) scale(.98)}.val-pill--clickable:focus-visible{outline:none;box-shadow:0 0 0 3px rgba(var(--val-pill-color-rgb),.3)}.val-pill--clickable.val-pill--solid:hover{filter:brightness(1.08)}:host-context(body.dark) .val-pill:not(.val-pill--solid),:host-context(html.ion-palette-dark) .val-pill:not(.val-pill--solid),:host-context([data-theme=dark]) .val-pill:not(.val-pill--solid){background:rgba(var(--val-pill-color-rgb),.22);border-color:rgba(var(--val-pill-color-rgb),.32)}.notif-pill{display:inline-flex;align-items:center;gap:12px;padding:10px 14px;border-radius:999px;background:var(--ion-color-dark);color:var(--ion-color-dark-contrast);max-width:100%;box-sizing:border-box;box-shadow:.1875rem .625rem .5rem #1219541a}.notif-pill__icon-wrap{display:flex;align-items:center;justify-content:center;flex-shrink:0;width:32px;height:32px;border-radius:50%;background:#ffffff1a;font-size:1rem}.notif-pill__content{display:flex;align-items:baseline;gap:8px;flex:1;min-width:0;overflow:hidden}.notif-pill__time{font-size:.72rem;font-weight:600;opacity:.55;flex-shrink:0;letter-spacing:.02em}.notif-pill__title{font-size:.875rem;font-weight:600;white-space:nowrap;overflow:hidden;text-overflow:ellipsis}.notif-pill__body{font-size:.75rem;opacity:.7;white-space:nowrap;overflow:hidden;text-overflow:ellipsis;flex-shrink:1}.notif-pill__actions{display:flex;align-items:center;gap:6px;flex-shrink:0;margin-left:4px}.notif-pill__action-btn{display:flex;align-items:center;justify-content:center;width:30px;height:30px;border-radius:50%;border:none;background:#ffffff1f;color:var(--ion-color-dark-contrast);cursor:pointer;font-size:.9rem;transition:background .15s ease,transform .1s ease;-webkit-tap-highlight-color:transparent}.notif-pill__action-btn:hover{background:#ffffff38}.notif-pill__action-btn:active{transform:scale(.9)}.notif-pill__action-btn:focus-visible{outline:none;box-shadow:0 0 0 2px #ffffff80}\n"] }]
19508
19504
  }], propDecorators: { preset: [{
19509
19505
  type: Input
19510
19506
  }], props: [{
19511
19507
  type: Input
19512
19508
  }], pillClick: [{
19513
19509
  type: Output
19510
+ }], pillAction: [{
19511
+ type: Output
19514
19512
  }] } });
19515
19513
 
19516
19514
  class CommandDisplayComponent {
@@ -27046,7 +27044,7 @@ const ACTION_CARD_DEFAULTS = {
27046
27044
  };
27047
27045
 
27048
27046
  addIcons({ chevronForwardOutline });
27049
- const IONIC_COLORS$5 = ['primary', 'secondary', 'tertiary', 'success', 'warning', 'danger', 'light', 'medium', 'dark'];
27047
+ const IONIC_COLORS$8 = ['primary', 'secondary', 'tertiary', 'success', 'warning', 'danger', 'light', 'medium', 'dark'];
27050
27048
  /**
27051
27049
  * val-action-card
27052
27050
  *
@@ -27126,7 +27124,7 @@ class ActionCardComponent {
27126
27124
  resolveColor(color) {
27127
27125
  if (!color)
27128
27126
  return null;
27129
- if (IONIC_COLORS$5.includes(color)) {
27127
+ if (IONIC_COLORS$8.includes(color)) {
27130
27128
  return `var(--ion-color-${color})`;
27131
27129
  }
27132
27130
  return color;
@@ -27319,7 +27317,7 @@ const MEDIA_OBJECT_DEFAULTS = {
27319
27317
  circle: false,
27320
27318
  };
27321
27319
 
27322
- const IONIC_COLORS$4 = ['primary', 'secondary', 'tertiary', 'success', 'warning', 'danger', 'light', 'medium', 'dark'];
27320
+ const IONIC_COLORS$7 = ['primary', 'secondary', 'tertiary', 'success', 'warning', 'danger', 'light', 'medium', 'dark'];
27323
27321
  /**
27324
27322
  * val-media-object
27325
27323
  *
@@ -27359,7 +27357,7 @@ class MediaObjectComponent {
27359
27357
  const color = this.config().color;
27360
27358
  if (!color)
27361
27359
  return 'var(--ion-color-primary)';
27362
- return IONIC_COLORS$4.includes(color) ? `var(--ion-color-${color})` : color;
27360
+ return IONIC_COLORS$7.includes(color) ? `var(--ion-color-${color})` : color;
27363
27361
  }
27364
27362
  handleLinkClick(event) {
27365
27363
  const link = this.config().link;
@@ -27463,7 +27461,7 @@ const STATS_BAR_DEFAULTS = {
27463
27461
  stackOnMobile: true,
27464
27462
  };
27465
27463
 
27466
- const IONIC_COLORS$3 = ['primary', 'secondary', 'tertiary', 'success', 'warning', 'danger', 'light', 'medium', 'dark'];
27464
+ const IONIC_COLORS$6 = ['primary', 'secondary', 'tertiary', 'success', 'warning', 'danger', 'light', 'medium', 'dark'];
27467
27465
  /**
27468
27466
  * val-stats-bar
27469
27467
  *
@@ -27500,7 +27498,7 @@ class StatsBarComponent {
27500
27498
  const color = stat.color;
27501
27499
  if (!color)
27502
27500
  return null;
27503
- return IONIC_COLORS$3.includes(color) ? `var(--ion-color-${color})` : color;
27501
+ return IONIC_COLORS$6.includes(color) ? `var(--ion-color-${color})` : color;
27504
27502
  }
27505
27503
  static { this.ɵfac = i0.ɵɵngDeclareFactory({ minVersion: "12.0.0", version: "18.2.14", ngImport: i0, type: StatsBarComponent, deps: [], target: i0.ɵɵFactoryTarget.Component }); }
27506
27504
  static { this.ɵcmp = i0.ɵɵngDeclareComponent({ minVersion: "17.0.0", version: "18.2.14", type: StatsBarComponent, isStandalone: true, selector: "val-stats-bar", inputs: { props: { classPropertyName: "props", publicName: "props", isSignal: true, isRequired: false, transformFunction: null } }, ngImport: i0, template: `
@@ -27568,7 +27566,7 @@ const ARTICLE_CARD_DEFAULTS = {
27568
27566
  excerptLines: 3,
27569
27567
  };
27570
27568
 
27571
- const IONIC_COLORS$2 = ['primary', 'secondary', 'tertiary', 'success', 'warning', 'danger', 'light', 'medium', 'dark'];
27569
+ const IONIC_COLORS$5 = ['primary', 'secondary', 'tertiary', 'success', 'warning', 'danger', 'light', 'medium', 'dark'];
27572
27570
  /**
27573
27571
  * val-article-card
27574
27572
  *
@@ -27611,7 +27609,7 @@ class ArticleCardComponent {
27611
27609
  const color = this.config().topicColor;
27612
27610
  if (!color)
27613
27611
  return 'var(--ion-color-primary)';
27614
- return IONIC_COLORS$2.includes(color) ? `var(--ion-color-${color})` : color;
27612
+ return IONIC_COLORS$5.includes(color) ? `var(--ion-color-${color})` : color;
27615
27613
  }
27616
27614
  handleClick(event) {
27617
27615
  const cfg = this.config();
@@ -27726,7 +27724,7 @@ const CTA_CARD_DEFAULTS = {
27726
27724
  shadowed: false,
27727
27725
  };
27728
27726
 
27729
- const IONIC_COLORS$1 = ['primary', 'secondary', 'tertiary', 'success', 'warning', 'danger', 'light', 'medium', 'dark'];
27727
+ const IONIC_COLORS$4 = ['primary', 'secondary', 'tertiary', 'success', 'warning', 'danger', 'light', 'medium', 'dark'];
27730
27728
  /**
27731
27729
  * val-cta-card
27732
27730
  *
@@ -27770,7 +27768,7 @@ class CtaCardComponent {
27770
27768
  resolveColor(color) {
27771
27769
  if (!color)
27772
27770
  return null;
27773
- return IONIC_COLORS$1.includes(color) ? `var(--ion-color-${color})` : color;
27771
+ return IONIC_COLORS$4.includes(color) ? `var(--ion-color-${color})` : color;
27774
27772
  }
27775
27773
  getBackground() {
27776
27774
  return this.resolveColor(this.config().backgroundColor) || 'var(--ion-color-light, #f4f5f8)';
@@ -32913,7 +32911,7 @@ const FUN_MODAL_DEFAULTS = {
32913
32911
  imageRadius: 16,
32914
32912
  };
32915
32913
 
32916
- const IONIC_COLORS = ['primary', 'secondary', 'tertiary', 'success', 'warning', 'danger', 'light', 'medium', 'dark'];
32914
+ const IONIC_COLORS$3 = ['primary', 'secondary', 'tertiary', 'success', 'warning', 'danger', 'light', 'medium', 'dark'];
32917
32915
  /**
32918
32916
  * `val-fun-modal` — modal moderno tipo promo/onboarding: imagen o ilustración
32919
32917
  * arriba, título, cuerpo y botones de acción, con redondeo personalizable.
@@ -32963,7 +32961,7 @@ class FunModalComponent {
32963
32961
  const color = this.config().backgroundColor;
32964
32962
  if (!color)
32965
32963
  return null;
32966
- return IONIC_COLORS.includes(color) ? `var(--ion-color-${color})` : color;
32964
+ return IONIC_COLORS$3.includes(color) ? `var(--ion-color-${color})` : color;
32967
32965
  }
32968
32966
  close() {
32969
32967
  this._isOpen = false;
@@ -34712,7 +34710,7 @@ class ItemListComponent {
34712
34710
  * Devuelve el color de borde de la lista.
34713
34711
  */
34714
34712
  color() {
34715
- return resolveColor(this.props.color || this.defaultColor);
34713
+ return resolveColor$1(this.props.color || this.defaultColor);
34716
34714
  }
34717
34715
  static { this.ɵfac = i0.ɵɵngDeclareFactory({ minVersion: "12.0.0", version: "18.2.14", ngImport: i0, type: ItemListComponent, deps: [{ token: IconService }], target: i0.ɵɵFactoryTarget.Component }); }
34718
34716
  static { this.ɵcmp = i0.ɵɵngDeclareComponent({ minVersion: "17.0.0", version: "18.2.14", type: ItemListComponent, isStandalone: true, selector: "val-item-list", inputs: { props: "props" }, outputs: { onClick: "onClick", onActionClick: "onActionClick" }, ngImport: i0, template: `
@@ -42378,7 +42376,7 @@ class PageContentComponent {
42378
42376
  if (!bg) {
42379
42377
  return 'var(--ion-background-color)';
42380
42378
  }
42381
- return resolveColor(bg);
42379
+ return resolveColor$1(bg);
42382
42380
  }
42383
42381
  /**
42384
42382
  * Handles header action clicks.
@@ -42784,7 +42782,7 @@ class PageWrapperComponent {
42784
42782
  if (!bg) {
42785
42783
  return 'var(--ion-background-color)';
42786
42784
  }
42787
- return resolveColor(bg);
42785
+ return resolveColor$1(bg);
42788
42786
  });
42789
42787
  }
42790
42788
  /**
@@ -51608,17 +51606,23 @@ class RequestService {
51608
51606
  return this.http.get(`${this.baseUrl}/my${qs}`);
51609
51607
  }
51610
51608
  getRequest(id) {
51611
- return this.http.get(`${this.baseUrl}/${id}`);
51609
+ return this.http
51610
+ .get(`${this.baseUrl}/${id}`)
51611
+ .pipe(map$1(r => r.request));
51612
51612
  }
51613
51613
  updateRequest(id, payload) {
51614
- return this.http.put(`${this.baseUrl}/${id}`, payload);
51614
+ return this.http
51615
+ .put(`${this.baseUrl}/${id}`, payload)
51616
+ .pipe(map$1(r => r.request));
51615
51617
  }
51616
51618
  transition(id, payload) {
51617
51619
  return this.http.post(`${this.baseUrl}/${id}/transition`, payload);
51618
51620
  }
51619
51621
  // ── Comments ──
51620
51622
  addComment(requestId, payload) {
51621
- return this.http.post(`${this.baseUrl}/${requestId}/comments`, payload);
51623
+ return this.http
51624
+ .post(`${this.baseUrl}/${requestId}/comments`, payload)
51625
+ .pipe(map$1(r => r.comment));
51622
51626
  }
51623
51627
  listComments(requestId) {
51624
51628
  return this.http.get(`${this.baseUrl}/${requestId}/comments`);
@@ -51821,6 +51825,689 @@ i0.ɵɵngDeclareClassMetadata({ minVersion: "12.0.0", version: "18.2.14", ngImpo
51821
51825
  args: [{ providedIn: 'root' }]
51822
51826
  }] });
51823
51827
 
51828
+ /**
51829
+ * Default values for ArticleStripMetadata.
51830
+ */
51831
+ const ARTICLE_STRIP_DEFAULTS = {
51832
+ cardWidth: '280px',
51833
+ gap: '16px',
51834
+ };
51835
+
51836
+ /**
51837
+ * val-article-strip
51838
+ *
51839
+ * Horizontal scroll row of article cards with a section header and an optional
51840
+ * "see all" link/action. Reuses val-horizontal-scroll + val-article-card.
51841
+ *
51842
+ * @example
51843
+ * ```html
51844
+ * <val-article-strip
51845
+ * [props]="{
51846
+ * title: 'Latest Articles',
51847
+ * seeAllLabel: 'View all',
51848
+ * seeAllRoute: '/blog',
51849
+ * articles: [...]
51850
+ * }"
51851
+ * (onArticleClick)="openArticle($event)"
51852
+ * />
51853
+ * ```
51854
+ */
51855
+ class ArticleStripComponent {
51856
+ constructor() {
51857
+ this.navigation = inject(NavigationService);
51858
+ /** Component configuration */
51859
+ this.props = input({ articles: [] });
51860
+ /** Emitted when the "see all" link/button is clicked */
51861
+ this.onSeeAll = new EventEmitter();
51862
+ /** Re-emits the onClick event from each article card */
51863
+ this.onArticleClick = new EventEmitter();
51864
+ /** Merged configuration with defaults */
51865
+ this.config = computed(() => ({
51866
+ ...ARTICLE_STRIP_DEFAULTS,
51867
+ articles: [],
51868
+ ...this.props(),
51869
+ }));
51870
+ this.hasSeeAll = computed(() => !!(this.config().seeAllLabel &&
51871
+ (this.config().seeAllRoute || this.config().seeAllHref || this.config().seeAllToken)));
51872
+ }
51873
+ handleSeeAll(event) {
51874
+ const cfg = this.config();
51875
+ if (cfg.seeAllHref) {
51876
+ event.preventDefault();
51877
+ this.navigation.openInNewTab(cfg.seeAllHref);
51878
+ }
51879
+ this.onSeeAll.emit(cfg.seeAllToken);
51880
+ }
51881
+ static { this.ɵfac = i0.ɵɵngDeclareFactory({ minVersion: "12.0.0", version: "18.2.14", ngImport: i0, type: ArticleStripComponent, deps: [], target: i0.ɵɵFactoryTarget.Component }); }
51882
+ static { this.ɵcmp = i0.ɵɵngDeclareComponent({ minVersion: "17.0.0", version: "18.2.14", type: ArticleStripComponent, isStandalone: true, selector: "val-article-strip", inputs: { props: { classPropertyName: "props", publicName: "props", isSignal: true, isRequired: false, transformFunction: null } }, outputs: { onSeeAll: "onSeeAll", onArticleClick: "onArticleClick" }, ngImport: i0, template: `
51883
+ @if (config().title || hasSeeAll()) {
51884
+ <div class="article-strip__header">
51885
+ @if (config().title) {
51886
+ <h3 class="article-strip__title">{{ config().title }}</h3>
51887
+ }
51888
+
51889
+ @if (hasSeeAll()) {
51890
+ <a
51891
+ class="article-strip__see-all"
51892
+ [routerLink]="config().seeAllRoute ?? null"
51893
+ [attr.href]="config().seeAllHref ?? null"
51894
+ (click)="handleSeeAll($event)"
51895
+ >
51896
+ {{ config().seeAllLabel }}
51897
+ </a>
51898
+ }
51899
+ </div>
51900
+ }
51901
+
51902
+ <val-horizontal-scroll
51903
+ [items]="config().articles"
51904
+ [itemTemplate]="cardTpl"
51905
+ [props]="{ gap: config().gap }"
51906
+ ></val-horizontal-scroll>
51907
+
51908
+ <ng-template #cardTpl let-article>
51909
+ <div [style.width]="config().cardWidth" [style.flex-shrink]="0">
51910
+ <val-article-card [props]="article" (onClick)="onArticleClick.emit($event)"></val-article-card>
51911
+ </div>
51912
+ </ng-template>
51913
+ `, isInline: true, styles: [":host{display:block}.article-strip__header{display:flex;align-items:center;justify-content:space-between;gap:1rem;padding:0 0 .75rem}.article-strip__title{margin:0;font-size:1.1rem;font-weight:700;color:var(--ion-text-color);line-height:1.3}.article-strip__see-all{flex-shrink:0;font-size:.875rem;font-weight:600;color:var(--ion-color-primary);text-decoration:none;transition:opacity .15s ease;cursor:pointer}.article-strip__see-all:hover{opacity:.75;text-decoration:underline}:host-context(body.dark) .article-strip__title,:host-context(html.ion-palette-dark) .article-strip__title,:host-context([data-theme=dark]) .article-strip__title{color:var(--ion-text-color)}\n"], dependencies: [{ kind: "ngmodule", type: CommonModule }, { kind: "directive", type: RouterLink, selector: "[routerLink]", inputs: ["target", "queryParams", "fragment", "queryParamsHandling", "state", "info", "relativeTo", "preserveFragment", "skipLocationChange", "replaceUrl", "routerLink"] }, { kind: "component", type: HorizontalScrollComponent, selector: "val-horizontal-scroll", inputs: ["items", "itemTemplate", "props"] }, { kind: "component", type: ArticleCardComponent, selector: "val-article-card", inputs: ["props"], outputs: ["onClick"] }] }); }
51914
+ }
51915
+ i0.ɵɵngDeclareClassMetadata({ minVersion: "12.0.0", version: "18.2.14", ngImport: i0, type: ArticleStripComponent, decorators: [{
51916
+ type: Component,
51917
+ args: [{ selector: 'val-article-strip', standalone: true, imports: [CommonModule, RouterLink, HorizontalScrollComponent, ArticleCardComponent], template: `
51918
+ @if (config().title || hasSeeAll()) {
51919
+ <div class="article-strip__header">
51920
+ @if (config().title) {
51921
+ <h3 class="article-strip__title">{{ config().title }}</h3>
51922
+ }
51923
+
51924
+ @if (hasSeeAll()) {
51925
+ <a
51926
+ class="article-strip__see-all"
51927
+ [routerLink]="config().seeAllRoute ?? null"
51928
+ [attr.href]="config().seeAllHref ?? null"
51929
+ (click)="handleSeeAll($event)"
51930
+ >
51931
+ {{ config().seeAllLabel }}
51932
+ </a>
51933
+ }
51934
+ </div>
51935
+ }
51936
+
51937
+ <val-horizontal-scroll
51938
+ [items]="config().articles"
51939
+ [itemTemplate]="cardTpl"
51940
+ [props]="{ gap: config().gap }"
51941
+ ></val-horizontal-scroll>
51942
+
51943
+ <ng-template #cardTpl let-article>
51944
+ <div [style.width]="config().cardWidth" [style.flex-shrink]="0">
51945
+ <val-article-card [props]="article" (onClick)="onArticleClick.emit($event)"></val-article-card>
51946
+ </div>
51947
+ </ng-template>
51948
+ `, styles: [":host{display:block}.article-strip__header{display:flex;align-items:center;justify-content:space-between;gap:1rem;padding:0 0 .75rem}.article-strip__title{margin:0;font-size:1.1rem;font-weight:700;color:var(--ion-text-color);line-height:1.3}.article-strip__see-all{flex-shrink:0;font-size:.875rem;font-weight:600;color:var(--ion-color-primary);text-decoration:none;transition:opacity .15s ease;cursor:pointer}.article-strip__see-all:hover{opacity:.75;text-decoration:underline}:host-context(body.dark) .article-strip__title,:host-context(html.ion-palette-dark) .article-strip__title,:host-context([data-theme=dark]) .article-strip__title{color:var(--ion-text-color)}\n"] }]
51949
+ }], propDecorators: { onSeeAll: [{
51950
+ type: Output
51951
+ }], onArticleClick: [{
51952
+ type: Output
51953
+ }] } });
51954
+
51955
+ /**
51956
+ * Default values for InfoCardMetadata.
51957
+ */
51958
+ const INFO_CARD_DEFAULTS = {
51959
+ iconColor: 'primary',
51960
+ bordered: true,
51961
+ shadowed: false,
51962
+ padding: '1.5rem',
51963
+ borderRadius: '16px',
51964
+ };
51965
+
51966
+ const IONIC_COLORS$2 = ['primary', 'secondary', 'tertiary', 'success', 'warning', 'danger', 'light', 'medium', 'dark'];
51967
+ /**
51968
+ * val-info-card
51969
+ *
51970
+ * Card with icon + overtitle + title + subtitle on the left side, and a list
51971
+ * of key-value pairs (label: value) on the right side. Inspired by npm's
51972
+ * "Provenance" / metadata panel style.
51973
+ *
51974
+ * Two-column layout on desktop, stacked single-column on mobile.
51975
+ *
51976
+ * Presentational — pass already-resolved strings.
51977
+ *
51978
+ * @example
51979
+ * ```html
51980
+ * <val-info-card
51981
+ * [props]="{
51982
+ * icon: 'cube-outline',
51983
+ * title: 'valtech-components',
51984
+ * subtitle: 'v2.0.962',
51985
+ * keyValues: [
51986
+ * { label: 'License', value: 'MIT' },
51987
+ * { label: 'Downloads', value: '1.2M' }
51988
+ * ]
51989
+ * }"
51990
+ * />
51991
+ * ```
51992
+ */
51993
+ class InfoCardComponent {
51994
+ constructor() {
51995
+ /** Component configuration */
51996
+ this.props = input({});
51997
+ /** Merged configuration with defaults */
51998
+ this.config = computed(() => ({
51999
+ ...INFO_CARD_DEFAULTS,
52000
+ ...this.props(),
52001
+ }));
52002
+ }
52003
+ getIconColor() {
52004
+ const color = this.config().iconColor;
52005
+ if (!color)
52006
+ return `var(--ion-color-primary)`;
52007
+ return IONIC_COLORS$2.includes(color) ? `var(--ion-color-${color})` : color;
52008
+ }
52009
+ static { this.ɵfac = i0.ɵɵngDeclareFactory({ minVersion: "12.0.0", version: "18.2.14", ngImport: i0, type: InfoCardComponent, deps: [], target: i0.ɵɵFactoryTarget.Component }); }
52010
+ static { this.ɵcmp = i0.ɵɵngDeclareComponent({ minVersion: "17.0.0", version: "18.2.14", type: InfoCardComponent, isStandalone: true, selector: "val-info-card", inputs: { props: { classPropertyName: "props", publicName: "props", isSignal: true, isRequired: false, transformFunction: null } }, ngImport: i0, template: `
52011
+ <div
52012
+ class="info-card"
52013
+ [class.info-card--bordered]="config().bordered"
52014
+ [class.info-card--shadowed]="config().shadowed"
52015
+ [style.padding]="config().padding"
52016
+ [style.border-radius]="config().borderRadius"
52017
+ >
52018
+ <div class="info-card__left">
52019
+ @if (config().icon) {
52020
+ <ion-icon class="info-card__icon" [name]="config().icon" [style.color]="getIconColor()"></ion-icon>
52021
+ }
52022
+
52023
+ @if (config().overtitle) {
52024
+ <span class="info-card__overtitle">{{ config().overtitle }}</span>
52025
+ }
52026
+
52027
+ <h3 class="info-card__title">{{ config().title }}</h3>
52028
+
52029
+ @if (config().subtitle) {
52030
+ <p class="info-card__subtitle">{{ config().subtitle }}</p>
52031
+ }
52032
+ </div>
52033
+
52034
+ @if (config().keyValues?.length) {
52035
+ <div class="info-card__right">
52036
+ @for (kv of config().keyValues; track $index) {
52037
+ <div class="info-card__kv">
52038
+ <span class="info-card__kv-label">{{ kv.label }}</span>
52039
+ <span class="info-card__kv-value">{{ kv.value }}</span>
52040
+ </div>
52041
+ }
52042
+ </div>
52043
+ }
52044
+ </div>
52045
+ `, isInline: true, styles: [":host{display:block}.info-card{display:flex;flex-direction:row;gap:2rem;background:var(--ion-card-background, var(--ion-background-color))}.info-card--bordered{border:1px solid var(--ion-color-light-shade, rgba(0, 0, 0, .1))}.info-card--shadowed{box-shadow:0 2px 8px #00000014}.info-card__left{display:flex;flex-direction:column;gap:.35rem;flex:1 1 0;min-width:0}.info-card__icon{font-size:2rem;margin-bottom:.25rem}.info-card__overtitle{font-size:.75rem;font-weight:600;text-transform:uppercase;letter-spacing:.08em;color:var(--ion-color-medium)}.info-card__title{margin:0;font-size:1.25rem;font-weight:700;color:var(--ion-text-color);line-height:1.3}.info-card__subtitle{margin:0;font-size:.875rem;color:var(--ion-color-medium-shade)}.info-card__right{display:flex;flex-direction:column;gap:.6rem;flex:0 0 auto;min-width:160px;max-width:260px}.info-card__kv{display:flex;flex-direction:column;gap:.1rem}.info-card__kv-label{font-size:.75rem;color:var(--ion-color-medium)}.info-card__kv-value{font-size:.9rem;font-weight:600;color:var(--ion-text-color);word-break:break-word}@media (max-width: 600px){.info-card{flex-direction:column;gap:1.25rem}.info-card__right{max-width:100%;flex-direction:row;flex-wrap:wrap;gap:.75rem 1.5rem}.info-card__kv{flex:0 0 auto}}:host-context(body.dark) .info-card--bordered,:host-context(html.ion-palette-dark) .info-card--bordered,:host-context([data-theme=dark]) .info-card--bordered{border-color:#ffffff1f}:host-context(body.dark) .info-card--shadowed,:host-context(html.ion-palette-dark) .info-card--shadowed,:host-context([data-theme=dark]) .info-card--shadowed{box-shadow:0 2px 8px #0000004d}\n"], dependencies: [{ kind: "ngmodule", type: CommonModule }, { kind: "component", type: IonIcon, selector: "ion-icon", inputs: ["color", "flipRtl", "icon", "ios", "lazy", "md", "mode", "name", "sanitize", "size", "src"] }] }); }
52046
+ }
52047
+ i0.ɵɵngDeclareClassMetadata({ minVersion: "12.0.0", version: "18.2.14", ngImport: i0, type: InfoCardComponent, decorators: [{
52048
+ type: Component,
52049
+ args: [{ selector: 'val-info-card', standalone: true, imports: [CommonModule, IonIcon], template: `
52050
+ <div
52051
+ class="info-card"
52052
+ [class.info-card--bordered]="config().bordered"
52053
+ [class.info-card--shadowed]="config().shadowed"
52054
+ [style.padding]="config().padding"
52055
+ [style.border-radius]="config().borderRadius"
52056
+ >
52057
+ <div class="info-card__left">
52058
+ @if (config().icon) {
52059
+ <ion-icon class="info-card__icon" [name]="config().icon" [style.color]="getIconColor()"></ion-icon>
52060
+ }
52061
+
52062
+ @if (config().overtitle) {
52063
+ <span class="info-card__overtitle">{{ config().overtitle }}</span>
52064
+ }
52065
+
52066
+ <h3 class="info-card__title">{{ config().title }}</h3>
52067
+
52068
+ @if (config().subtitle) {
52069
+ <p class="info-card__subtitle">{{ config().subtitle }}</p>
52070
+ }
52071
+ </div>
52072
+
52073
+ @if (config().keyValues?.length) {
52074
+ <div class="info-card__right">
52075
+ @for (kv of config().keyValues; track $index) {
52076
+ <div class="info-card__kv">
52077
+ <span class="info-card__kv-label">{{ kv.label }}</span>
52078
+ <span class="info-card__kv-value">{{ kv.value }}</span>
52079
+ </div>
52080
+ }
52081
+ </div>
52082
+ }
52083
+ </div>
52084
+ `, styles: [":host{display:block}.info-card{display:flex;flex-direction:row;gap:2rem;background:var(--ion-card-background, var(--ion-background-color))}.info-card--bordered{border:1px solid var(--ion-color-light-shade, rgba(0, 0, 0, .1))}.info-card--shadowed{box-shadow:0 2px 8px #00000014}.info-card__left{display:flex;flex-direction:column;gap:.35rem;flex:1 1 0;min-width:0}.info-card__icon{font-size:2rem;margin-bottom:.25rem}.info-card__overtitle{font-size:.75rem;font-weight:600;text-transform:uppercase;letter-spacing:.08em;color:var(--ion-color-medium)}.info-card__title{margin:0;font-size:1.25rem;font-weight:700;color:var(--ion-text-color);line-height:1.3}.info-card__subtitle{margin:0;font-size:.875rem;color:var(--ion-color-medium-shade)}.info-card__right{display:flex;flex-direction:column;gap:.6rem;flex:0 0 auto;min-width:160px;max-width:260px}.info-card__kv{display:flex;flex-direction:column;gap:.1rem}.info-card__kv-label{font-size:.75rem;color:var(--ion-color-medium)}.info-card__kv-value{font-size:.9rem;font-weight:600;color:var(--ion-text-color);word-break:break-word}@media (max-width: 600px){.info-card{flex-direction:column;gap:1.25rem}.info-card__right{max-width:100%;flex-direction:row;flex-wrap:wrap;gap:.75rem 1.5rem}.info-card__kv{flex:0 0 auto}}:host-context(body.dark) .info-card--bordered,:host-context(html.ion-palette-dark) .info-card--bordered,:host-context([data-theme=dark]) .info-card--bordered{border-color:#ffffff1f}:host-context(body.dark) .info-card--shadowed,:host-context(html.ion-palette-dark) .info-card--shadowed,:host-context([data-theme=dark]) .info-card--shadowed{box-shadow:0 2px 8px #0000004d}\n"] }]
52085
+ }] });
52086
+
52087
+ /**
52088
+ * Default values for MetricCardMetadata.
52089
+ */
52090
+ const METRIC_CARD_DEFAULTS = {
52091
+ bordered: true,
52092
+ shadowed: false,
52093
+ padding: '1.25rem 1.5rem',
52094
+ borderRadius: '16px',
52095
+ };
52096
+
52097
+ /**
52098
+ * val-metric-card
52099
+ *
52100
+ * Card with title + optional info link + description + horizontal stats row
52101
+ * (val-stats-bar) + a discrete icon action button in the top-right corner.
52102
+ *
52103
+ * Presentational — pass already-resolved strings.
52104
+ *
52105
+ * @example
52106
+ * ```html
52107
+ * <val-metric-card
52108
+ * [props]="{
52109
+ * title: 'Email Activity',
52110
+ * description: 'Last 30 days',
52111
+ * stats: { stats: [{ label: 'Sent', value: 1240 }, { label: 'Opens', value: 680 }] },
52112
+ * action: { icon: 'refresh-outline', token: 'refresh' }
52113
+ * }"
52114
+ * (onAction)="handleAction($event)"
52115
+ * />
52116
+ * ```
52117
+ */
52118
+ class MetricCardComponent {
52119
+ constructor() {
52120
+ /** Component configuration */
52121
+ this.props = input({});
52122
+ /** Emitted with the token of the clicked action */
52123
+ this.onAction = new EventEmitter();
52124
+ /** Merged configuration with defaults */
52125
+ this.config = computed(() => ({
52126
+ ...METRIC_CARD_DEFAULTS,
52127
+ ...this.props(),
52128
+ }));
52129
+ }
52130
+ static { this.ɵfac = i0.ɵɵngDeclareFactory({ minVersion: "12.0.0", version: "18.2.14", ngImport: i0, type: MetricCardComponent, deps: [], target: i0.ɵɵFactoryTarget.Component }); }
52131
+ static { this.ɵcmp = i0.ɵɵngDeclareComponent({ minVersion: "17.0.0", version: "18.2.14", type: MetricCardComponent, isStandalone: true, selector: "val-metric-card", inputs: { props: { classPropertyName: "props", publicName: "props", isSignal: true, isRequired: false, transformFunction: null } }, outputs: { onAction: "onAction" }, ngImport: i0, template: `
52132
+ <div
52133
+ class="metric-card"
52134
+ [class.metric-card--bordered]="config().bordered"
52135
+ [class.metric-card--shadowed]="config().shadowed"
52136
+ [style.padding]="config().padding"
52137
+ [style.border-radius]="config().borderRadius"
52138
+ >
52139
+ <div class="metric-card__header">
52140
+ <div class="metric-card__header-left">
52141
+ <h3 class="metric-card__title">{{ config().title }}</h3>
52142
+
52143
+ @if (config().infoLabel) {
52144
+ <a
52145
+ class="metric-card__info-link"
52146
+ [routerLink]="config().infoRoute ?? null"
52147
+ [attr.href]="config().infoHref ?? null"
52148
+ [attr.target]="config().infoHref ? '_blank' : null"
52149
+ [attr.rel]="config().infoHref ? 'noopener noreferrer' : null"
52150
+ >
52151
+ {{ config().infoLabel }}
52152
+ </a>
52153
+ }
52154
+ </div>
52155
+
52156
+ @if (config().action; as action) {
52157
+ <ion-button
52158
+ class="metric-card__action"
52159
+ fill="clear"
52160
+ size="small"
52161
+ [disabled]="action.disabled ?? false"
52162
+ (click)="onAction.emit(action.token)"
52163
+ >
52164
+ <ion-icon [name]="action.icon" slot="icon-only"></ion-icon>
52165
+ </ion-button>
52166
+ }
52167
+ </div>
52168
+
52169
+ @if (config().description) {
52170
+ <p class="metric-card__description">{{ config().description }}</p>
52171
+ }
52172
+
52173
+ @if (config().stats; as stats) {
52174
+ <div class="metric-card__stats">
52175
+ <val-stats-bar [props]="stats"></val-stats-bar>
52176
+ </div>
52177
+ }
52178
+ </div>
52179
+ `, isInline: true, styles: [":host{display:block}.metric-card{background:var(--ion-card-background, var(--ion-background-color))}.metric-card--bordered{border:1px solid var(--ion-color-light-shade, rgba(0, 0, 0, .1))}.metric-card--shadowed{box-shadow:0 2px 8px #00000014}.metric-card__header{display:flex;align-items:flex-start;justify-content:space-between;gap:.5rem;margin-bottom:.25rem}.metric-card__header-left{display:flex;flex-direction:column;gap:.2rem;flex:1 1 0;min-width:0}.metric-card__title{margin:0;font-size:1rem;font-weight:700;color:var(--ion-text-color);line-height:1.3;white-space:nowrap;overflow:hidden;text-overflow:ellipsis}.metric-card__info-link{font-size:.8rem;font-weight:500;color:var(--ion-color-primary);text-decoration:none;transition:opacity .15s ease;width:fit-content}.metric-card__info-link:hover{opacity:.75;text-decoration:underline}.metric-card__action{flex-shrink:0;margin:-6px -8px 0 0}.metric-card__description{margin:0 0 .75rem;font-size:.875rem;color:var(--ion-color-medium-shade);line-height:1.5}.metric-card__stats{margin-top:.5rem}:host-context(body.dark) .metric-card--bordered,:host-context(html.ion-palette-dark) .metric-card--bordered,:host-context([data-theme=dark]) .metric-card--bordered{border-color:#ffffff1f}:host-context(body.dark) .metric-card--shadowed,:host-context(html.ion-palette-dark) .metric-card--shadowed,:host-context([data-theme=dark]) .metric-card--shadowed{box-shadow:0 2px 8px #0000004d}\n"], dependencies: [{ kind: "ngmodule", type: CommonModule }, { kind: "directive", type: RouterLink, selector: "[routerLink]", inputs: ["target", "queryParams", "fragment", "queryParamsHandling", "state", "info", "relativeTo", "preserveFragment", "skipLocationChange", "replaceUrl", "routerLink"] }, { kind: "component", type: IonButton, selector: "ion-button", inputs: ["buttonType", "color", "disabled", "download", "expand", "fill", "form", "href", "mode", "rel", "routerAnimation", "routerDirection", "shape", "size", "strong", "target", "type"] }, { kind: "component", type: IonIcon, selector: "ion-icon", inputs: ["color", "flipRtl", "icon", "ios", "lazy", "md", "mode", "name", "sanitize", "size", "src"] }, { kind: "component", type: StatsBarComponent, selector: "val-stats-bar", inputs: ["props"] }] }); }
52180
+ }
52181
+ i0.ɵɵngDeclareClassMetadata({ minVersion: "12.0.0", version: "18.2.14", ngImport: i0, type: MetricCardComponent, decorators: [{
52182
+ type: Component,
52183
+ args: [{ selector: 'val-metric-card', standalone: true, imports: [CommonModule, RouterLink, IonButton, IonIcon, StatsBarComponent], template: `
52184
+ <div
52185
+ class="metric-card"
52186
+ [class.metric-card--bordered]="config().bordered"
52187
+ [class.metric-card--shadowed]="config().shadowed"
52188
+ [style.padding]="config().padding"
52189
+ [style.border-radius]="config().borderRadius"
52190
+ >
52191
+ <div class="metric-card__header">
52192
+ <div class="metric-card__header-left">
52193
+ <h3 class="metric-card__title">{{ config().title }}</h3>
52194
+
52195
+ @if (config().infoLabel) {
52196
+ <a
52197
+ class="metric-card__info-link"
52198
+ [routerLink]="config().infoRoute ?? null"
52199
+ [attr.href]="config().infoHref ?? null"
52200
+ [attr.target]="config().infoHref ? '_blank' : null"
52201
+ [attr.rel]="config().infoHref ? 'noopener noreferrer' : null"
52202
+ >
52203
+ {{ config().infoLabel }}
52204
+ </a>
52205
+ }
52206
+ </div>
52207
+
52208
+ @if (config().action; as action) {
52209
+ <ion-button
52210
+ class="metric-card__action"
52211
+ fill="clear"
52212
+ size="small"
52213
+ [disabled]="action.disabled ?? false"
52214
+ (click)="onAction.emit(action.token)"
52215
+ >
52216
+ <ion-icon [name]="action.icon" slot="icon-only"></ion-icon>
52217
+ </ion-button>
52218
+ }
52219
+ </div>
52220
+
52221
+ @if (config().description) {
52222
+ <p class="metric-card__description">{{ config().description }}</p>
52223
+ }
52224
+
52225
+ @if (config().stats; as stats) {
52226
+ <div class="metric-card__stats">
52227
+ <val-stats-bar [props]="stats"></val-stats-bar>
52228
+ </div>
52229
+ }
52230
+ </div>
52231
+ `, styles: [":host{display:block}.metric-card{background:var(--ion-card-background, var(--ion-background-color))}.metric-card--bordered{border:1px solid var(--ion-color-light-shade, rgba(0, 0, 0, .1))}.metric-card--shadowed{box-shadow:0 2px 8px #00000014}.metric-card__header{display:flex;align-items:flex-start;justify-content:space-between;gap:.5rem;margin-bottom:.25rem}.metric-card__header-left{display:flex;flex-direction:column;gap:.2rem;flex:1 1 0;min-width:0}.metric-card__title{margin:0;font-size:1rem;font-weight:700;color:var(--ion-text-color);line-height:1.3;white-space:nowrap;overflow:hidden;text-overflow:ellipsis}.metric-card__info-link{font-size:.8rem;font-weight:500;color:var(--ion-color-primary);text-decoration:none;transition:opacity .15s ease;width:fit-content}.metric-card__info-link:hover{opacity:.75;text-decoration:underline}.metric-card__action{flex-shrink:0;margin:-6px -8px 0 0}.metric-card__description{margin:0 0 .75rem;font-size:.875rem;color:var(--ion-color-medium-shade);line-height:1.5}.metric-card__stats{margin-top:.5rem}:host-context(body.dark) .metric-card--bordered,:host-context(html.ion-palette-dark) .metric-card--bordered,:host-context([data-theme=dark]) .metric-card--bordered{border-color:#ffffff1f}:host-context(body.dark) .metric-card--shadowed,:host-context(html.ion-palette-dark) .metric-card--shadowed,:host-context([data-theme=dark]) .metric-card--shadowed{box-shadow:0 2px 8px #0000004d}\n"] }]
52232
+ }], propDecorators: { onAction: [{
52233
+ type: Output
52234
+ }] } });
52235
+
52236
+ /**
52237
+ * Default values for ContentCardMetadata.
52238
+ */
52239
+ const CONTENT_CARD_DEFAULTS = {
52240
+ padding: '1.5rem',
52241
+ borderRadius: '20px',
52242
+ bordered: false,
52243
+ shadowed: true,
52244
+ align: 'start',
52245
+ };
52246
+
52247
+ const IONIC_COLORS$1 = ['primary', 'secondary', 'tertiary', 'success', 'warning', 'danger', 'light', 'medium', 'dark'];
52248
+ function resolveColor(value) {
52249
+ if (!value)
52250
+ return undefined;
52251
+ return IONIC_COLORS$1.includes(value) ? `var(--ion-color-${value})` : value;
52252
+ }
52253
+ /**
52254
+ * val-content-card
52255
+ *
52256
+ * Generic container card with configurable padding, border radius, background
52257
+ * color and shadow. Accepts arbitrary content via ng-content. Use it to wrap
52258
+ * val-article, stats, or any other content that needs a card shell.
52259
+ *
52260
+ * @example
52261
+ * ```html
52262
+ * <val-content-card [props]="{ title: 'Summary', shadowed: true }">
52263
+ * <p>Any inner content here.</p>
52264
+ * </val-content-card>
52265
+ * ```
52266
+ */
52267
+ class ContentCardComponent {
52268
+ constructor() {
52269
+ /** Component configuration */
52270
+ this.props = input({});
52271
+ /** Merged configuration with defaults */
52272
+ this.config = computed(() => ({
52273
+ ...CONTENT_CARD_DEFAULTS,
52274
+ ...this.props(),
52275
+ }));
52276
+ this.resolvedBg = computed(() => resolveColor(this.config().backgroundColor));
52277
+ this.resolvedColor = computed(() => resolveColor(this.config().color));
52278
+ }
52279
+ static { this.ɵfac = i0.ɵɵngDeclareFactory({ minVersion: "12.0.0", version: "18.2.14", ngImport: i0, type: ContentCardComponent, deps: [], target: i0.ɵɵFactoryTarget.Component }); }
52280
+ static { this.ɵcmp = i0.ɵɵngDeclareComponent({ minVersion: "17.0.0", version: "18.2.14", type: ContentCardComponent, isStandalone: true, selector: "val-content-card", inputs: { props: { classPropertyName: "props", publicName: "props", isSignal: true, isRequired: false, transformFunction: null } }, ngImport: i0, template: `
52281
+ <div
52282
+ class="content-card"
52283
+ [class.content-card--bordered]="config().bordered"
52284
+ [class.content-card--shadowed]="config().shadowed"
52285
+ [class.content-card--center]="config().align === 'center'"
52286
+ [style.padding]="config().padding"
52287
+ [style.border-radius]="config().borderRadius"
52288
+ [style.background-color]="resolvedBg()"
52289
+ [style.color]="resolvedColor()"
52290
+ >
52291
+ @if (config().title) {
52292
+ <h3 class="content-card__title">{{ config().title }}</h3>
52293
+ }
52294
+
52295
+ @if (config().description) {
52296
+ <p class="content-card__description">{{ config().description }}</p>
52297
+ }
52298
+
52299
+ <ng-content></ng-content>
52300
+ </div>
52301
+ `, isInline: true, styles: [":host{display:block}.content-card{background:var(--ion-card-background, var(--ion-background-color))}.content-card--bordered{border:1px solid var(--ion-color-light-shade, rgba(0, 0, 0, .1))}.content-card--shadowed{box-shadow:0 4px 16px #00000014}.content-card--center{text-align:center}.content-card__title{margin:0 0 .5rem;font-size:1.1rem;font-weight:700;color:inherit;line-height:1.3}.content-card__description{margin:0 0 1rem;font-size:.875rem;color:var(--ion-color-medium-shade);line-height:1.5}:host-context(body.dark) .content-card--bordered,:host-context(html.ion-palette-dark) .content-card--bordered,:host-context([data-theme=dark]) .content-card--bordered{border-color:#ffffff1f}:host-context(body.dark) .content-card--shadowed,:host-context(html.ion-palette-dark) .content-card--shadowed,:host-context([data-theme=dark]) .content-card--shadowed{box-shadow:0 4px 16px #0000004d}\n"], dependencies: [{ kind: "ngmodule", type: CommonModule }] }); }
52302
+ }
52303
+ i0.ɵɵngDeclareClassMetadata({ minVersion: "12.0.0", version: "18.2.14", ngImport: i0, type: ContentCardComponent, decorators: [{
52304
+ type: Component,
52305
+ args: [{ selector: 'val-content-card', standalone: true, imports: [CommonModule], template: `
52306
+ <div
52307
+ class="content-card"
52308
+ [class.content-card--bordered]="config().bordered"
52309
+ [class.content-card--shadowed]="config().shadowed"
52310
+ [class.content-card--center]="config().align === 'center'"
52311
+ [style.padding]="config().padding"
52312
+ [style.border-radius]="config().borderRadius"
52313
+ [style.background-color]="resolvedBg()"
52314
+ [style.color]="resolvedColor()"
52315
+ >
52316
+ @if (config().title) {
52317
+ <h3 class="content-card__title">{{ config().title }}</h3>
52318
+ }
52319
+
52320
+ @if (config().description) {
52321
+ <p class="content-card__description">{{ config().description }}</p>
52322
+ }
52323
+
52324
+ <ng-content></ng-content>
52325
+ </div>
52326
+ `, styles: [":host{display:block}.content-card{background:var(--ion-card-background, var(--ion-background-color))}.content-card--bordered{border:1px solid var(--ion-color-light-shade, rgba(0, 0, 0, .1))}.content-card--shadowed{box-shadow:0 4px 16px #00000014}.content-card--center{text-align:center}.content-card__title{margin:0 0 .5rem;font-size:1.1rem;font-weight:700;color:inherit;line-height:1.3}.content-card__description{margin:0 0 1rem;font-size:.875rem;color:var(--ion-color-medium-shade);line-height:1.5}:host-context(body.dark) .content-card--bordered,:host-context(html.ion-palette-dark) .content-card--bordered,:host-context([data-theme=dark]) .content-card--bordered{border-color:#ffffff1f}:host-context(body.dark) .content-card--shadowed,:host-context(html.ion-palette-dark) .content-card--shadowed,:host-context([data-theme=dark]) .content-card--shadowed{box-shadow:0 4px 16px #0000004d}\n"] }]
52327
+ }] });
52328
+
52329
+ /**
52330
+ * Default values for AuthCtaMetadata.
52331
+ */
52332
+ const AUTH_CTA_DEFAULTS = {
52333
+ align: 'center',
52334
+ borderRadius: '0',
52335
+ padding: '3rem 1.5rem',
52336
+ };
52337
+
52338
+ const IONIC_COLORS = ['primary', 'secondary', 'tertiary', 'success', 'warning', 'danger', 'light', 'medium', 'dark'];
52339
+ const AUTH_CTA_I18N = {
52340
+ es: { login: 'Iniciar sesión', register: 'Registrarse' },
52341
+ en: { login: 'Log in', register: 'Sign up' },
52342
+ };
52343
+ /**
52344
+ * val-auth-cta
52345
+ *
52346
+ * Full-width CTA section inviting unauthenticated users to sign up or log in.
52347
+ * Desktop: text on the left, optional image on the right.
52348
+ * Mobile: stacked, image below text.
52349
+ *
52350
+ * Auto-registers its own i18n defaults (AuthCta namespace) so there are never
52351
+ * missing keys, even if the consumer does not register them.
52352
+ *
52353
+ * @example
52354
+ * ```html
52355
+ * <val-auth-cta
52356
+ * [props]="{
52357
+ * title: 'Join Valtech today',
52358
+ * subtitle: 'The platform built for teams that ship.',
52359
+ * loginRoute: '/login',
52360
+ * registerRoute: '/register'
52361
+ * }"
52362
+ * (onLogin)="openLogin()"
52363
+ * (onRegister)="openRegister()"
52364
+ * />
52365
+ * ```
52366
+ */
52367
+ class AuthCtaComponent {
52368
+ constructor() {
52369
+ this.i18n = inject(I18nService);
52370
+ /** Component configuration */
52371
+ this.props = input({});
52372
+ /** Emitted when the login button is clicked */
52373
+ this.onLogin = new EventEmitter();
52374
+ /** Emitted when the register button is clicked */
52375
+ this.onRegister = new EventEmitter();
52376
+ /** Merged configuration with defaults */
52377
+ this.config = computed(() => ({
52378
+ ...AUTH_CTA_DEFAULTS,
52379
+ ...this.props(),
52380
+ }));
52381
+ this.loginLabel = computed(() => this.config().loginLabel ?? this.i18n.t('AuthCta.login'));
52382
+ this.registerLabel = computed(() => this.config().registerLabel ?? this.i18n.t('AuthCta.register'));
52383
+ this.resolvedBg = computed(() => {
52384
+ const bg = this.config().backgroundColor;
52385
+ if (!bg)
52386
+ return undefined;
52387
+ return IONIC_COLORS.includes(bg) ? `var(--ion-color-${bg})` : bg;
52388
+ });
52389
+ if (!this.i18n.hasNamespace('AuthCta')) {
52390
+ this.i18n.registerContent('AuthCta', AUTH_CTA_I18N);
52391
+ }
52392
+ }
52393
+ static { this.ɵfac = i0.ɵɵngDeclareFactory({ minVersion: "12.0.0", version: "18.2.14", ngImport: i0, type: AuthCtaComponent, deps: [], target: i0.ɵɵFactoryTarget.Component }); }
52394
+ static { this.ɵcmp = i0.ɵɵngDeclareComponent({ minVersion: "17.0.0", version: "18.2.14", type: AuthCtaComponent, isStandalone: true, selector: "val-auth-cta", inputs: { props: { classPropertyName: "props", publicName: "props", isSignal: true, isRequired: false, transformFunction: null } }, outputs: { onLogin: "onLogin", onRegister: "onRegister" }, ngImport: i0, template: `
52395
+ <div
52396
+ class="auth-cta"
52397
+ [class.auth-cta--center]="config().align === 'center'"
52398
+ [class.auth-cta--has-image]="!!config().image"
52399
+ [style.padding]="config().padding"
52400
+ [style.border-radius]="config().borderRadius"
52401
+ [style.background-color]="resolvedBg()"
52402
+ >
52403
+ <div class="auth-cta__text">
52404
+ @if (config().eyebrow) {
52405
+ <span class="auth-cta__eyebrow">{{ config().eyebrow }}</span>
52406
+ }
52407
+
52408
+ <h2 class="auth-cta__title">{{ config().title }}</h2>
52409
+
52410
+ @if (config().subtitle) {
52411
+ <p class="auth-cta__subtitle">{{ config().subtitle }}</p>
52412
+ }
52413
+
52414
+ <div class="auth-cta__actions">
52415
+ <ion-button
52416
+ class="auth-cta__btn-register"
52417
+ fill="solid"
52418
+ color="dark"
52419
+ shape="round"
52420
+ [routerLink]="config().registerRoute ?? null"
52421
+ [attr.href]="config().registerHref ?? null"
52422
+ (click)="onRegister.emit()"
52423
+ >
52424
+ {{ registerLabel() }}
52425
+ </ion-button>
52426
+
52427
+ <ion-button
52428
+ class="auth-cta__btn-login"
52429
+ fill="outline"
52430
+ color="dark"
52431
+ shape="round"
52432
+ [routerLink]="config().loginRoute ?? null"
52433
+ [attr.href]="config().loginHref ?? null"
52434
+ (click)="onLogin.emit()"
52435
+ >
52436
+ {{ loginLabel() }}
52437
+ </ion-button>
52438
+ </div>
52439
+ </div>
52440
+
52441
+ @if (config().image) {
52442
+ <div class="auth-cta__image-wrap">
52443
+ <img class="auth-cta__image" [src]="config().image" [alt]="config().imageAlt ?? ''" loading="lazy" />
52444
+ </div>
52445
+ }
52446
+ </div>
52447
+ `, isInline: true, styles: [":host{display:block}.auth-cta{display:flex;flex-direction:row;align-items:center;gap:3rem;background:var(--ion-background-color)}.auth-cta--center{text-align:center}.auth-cta--center .auth-cta__actions{justify-content:center}.auth-cta--has-image{text-align:start}.auth-cta--has-image .auth-cta__actions{justify-content:flex-start}.auth-cta__text{flex:1 1 0;min-width:0;display:flex;flex-direction:column;gap:1rem}.auth-cta__eyebrow{font-size:.8rem;font-weight:700;text-transform:uppercase;letter-spacing:.1em;color:var(--ion-color-primary)}.auth-cta__title{margin:0;font-size:2rem;font-weight:800;line-height:1.2;color:var(--ion-text-color)}.auth-cta__subtitle{margin:0;font-size:1.05rem;line-height:1.6;color:var(--ion-color-medium-shade)}.auth-cta__actions{display:flex;flex-wrap:wrap;gap:.75rem;align-items:center;margin-top:.5rem}.auth-cta__image-wrap{flex:0 0 auto;max-width:420px;width:40%}.auth-cta__image{display:block;width:100%;height:auto;border-radius:12px;object-fit:cover}@media (max-width: 768px){.auth-cta{flex-direction:column;gap:2rem;text-align:center}.auth-cta--has-image{text-align:center}.auth-cta--has-image .auth-cta__actions{justify-content:center}.auth-cta__image-wrap{max-width:100%;width:100%}.auth-cta__actions{justify-content:center}}:host-context(body.dark) .auth-cta__title,:host-context(html.ion-palette-dark) .auth-cta__title,:host-context([data-theme=dark]) .auth-cta__title{color:var(--ion-text-color)}:host-context(body.dark) .auth-cta__subtitle,:host-context(html.ion-palette-dark) .auth-cta__subtitle,:host-context([data-theme=dark]) .auth-cta__subtitle{color:var(--ion-color-medium)}\n"], dependencies: [{ kind: "ngmodule", type: CommonModule }, { kind: "directive", type: RouterLink, selector: "[routerLink]", inputs: ["target", "queryParams", "fragment", "queryParamsHandling", "state", "info", "relativeTo", "preserveFragment", "skipLocationChange", "replaceUrl", "routerLink"] }, { kind: "component", type: IonButton, selector: "ion-button", inputs: ["buttonType", "color", "disabled", "download", "expand", "fill", "form", "href", "mode", "rel", "routerAnimation", "routerDirection", "shape", "size", "strong", "target", "type"] }] }); }
52448
+ }
52449
+ i0.ɵɵngDeclareClassMetadata({ minVersion: "12.0.0", version: "18.2.14", ngImport: i0, type: AuthCtaComponent, decorators: [{
52450
+ type: Component,
52451
+ args: [{ selector: 'val-auth-cta', standalone: true, imports: [CommonModule, RouterLink, IonButton], template: `
52452
+ <div
52453
+ class="auth-cta"
52454
+ [class.auth-cta--center]="config().align === 'center'"
52455
+ [class.auth-cta--has-image]="!!config().image"
52456
+ [style.padding]="config().padding"
52457
+ [style.border-radius]="config().borderRadius"
52458
+ [style.background-color]="resolvedBg()"
52459
+ >
52460
+ <div class="auth-cta__text">
52461
+ @if (config().eyebrow) {
52462
+ <span class="auth-cta__eyebrow">{{ config().eyebrow }}</span>
52463
+ }
52464
+
52465
+ <h2 class="auth-cta__title">{{ config().title }}</h2>
52466
+
52467
+ @if (config().subtitle) {
52468
+ <p class="auth-cta__subtitle">{{ config().subtitle }}</p>
52469
+ }
52470
+
52471
+ <div class="auth-cta__actions">
52472
+ <ion-button
52473
+ class="auth-cta__btn-register"
52474
+ fill="solid"
52475
+ color="dark"
52476
+ shape="round"
52477
+ [routerLink]="config().registerRoute ?? null"
52478
+ [attr.href]="config().registerHref ?? null"
52479
+ (click)="onRegister.emit()"
52480
+ >
52481
+ {{ registerLabel() }}
52482
+ </ion-button>
52483
+
52484
+ <ion-button
52485
+ class="auth-cta__btn-login"
52486
+ fill="outline"
52487
+ color="dark"
52488
+ shape="round"
52489
+ [routerLink]="config().loginRoute ?? null"
52490
+ [attr.href]="config().loginHref ?? null"
52491
+ (click)="onLogin.emit()"
52492
+ >
52493
+ {{ loginLabel() }}
52494
+ </ion-button>
52495
+ </div>
52496
+ </div>
52497
+
52498
+ @if (config().image) {
52499
+ <div class="auth-cta__image-wrap">
52500
+ <img class="auth-cta__image" [src]="config().image" [alt]="config().imageAlt ?? ''" loading="lazy" />
52501
+ </div>
52502
+ }
52503
+ </div>
52504
+ `, styles: [":host{display:block}.auth-cta{display:flex;flex-direction:row;align-items:center;gap:3rem;background:var(--ion-background-color)}.auth-cta--center{text-align:center}.auth-cta--center .auth-cta__actions{justify-content:center}.auth-cta--has-image{text-align:start}.auth-cta--has-image .auth-cta__actions{justify-content:flex-start}.auth-cta__text{flex:1 1 0;min-width:0;display:flex;flex-direction:column;gap:1rem}.auth-cta__eyebrow{font-size:.8rem;font-weight:700;text-transform:uppercase;letter-spacing:.1em;color:var(--ion-color-primary)}.auth-cta__title{margin:0;font-size:2rem;font-weight:800;line-height:1.2;color:var(--ion-text-color)}.auth-cta__subtitle{margin:0;font-size:1.05rem;line-height:1.6;color:var(--ion-color-medium-shade)}.auth-cta__actions{display:flex;flex-wrap:wrap;gap:.75rem;align-items:center;margin-top:.5rem}.auth-cta__image-wrap{flex:0 0 auto;max-width:420px;width:40%}.auth-cta__image{display:block;width:100%;height:auto;border-radius:12px;object-fit:cover}@media (max-width: 768px){.auth-cta{flex-direction:column;gap:2rem;text-align:center}.auth-cta--has-image{text-align:center}.auth-cta--has-image .auth-cta__actions{justify-content:center}.auth-cta__image-wrap{max-width:100%;width:100%}.auth-cta__actions{justify-content:center}}:host-context(body.dark) .auth-cta__title,:host-context(html.ion-palette-dark) .auth-cta__title,:host-context([data-theme=dark]) .auth-cta__title{color:var(--ion-text-color)}:host-context(body.dark) .auth-cta__subtitle,:host-context(html.ion-palette-dark) .auth-cta__subtitle,:host-context([data-theme=dark]) .auth-cta__subtitle{color:var(--ion-color-medium)}\n"] }]
52505
+ }], ctorParameters: () => [], propDecorators: { onLogin: [{
52506
+ type: Output
52507
+ }], onRegister: [{
52508
+ type: Output
52509
+ }] } });
52510
+
51824
52511
  /*
51825
52512
  * Public API Surface of valtech-components
51826
52513
  */
@@ -51830,5 +52517,5 @@ i0.ɵɵngDeclareClassMetadata({ minVersion: "12.0.0", version: "18.2.14", ngImpo
51830
52517
  * Generated bundle index. Do not edit.
51831
52518
  */
51832
52519
 
51833
- export { ACTION_CARD_DEFAULTS, AD_SIZE_MAP, API_TABLE_COLUMN_LABELS, ARTICLE_CARD_DEFAULTS, ARTICLE_SPACING, AVATAR_UPLOAD_DEFAULTS, AccordionComponent, ActionCardComponent, ActionHeaderComponent, ActionType, AdSlotComponent, AdsLoaderService, AdsService, AlertBoxComponent, AnalyticsErrorHandler, AnalyticsRouterTracker, AnalyticsService, AnimatedTerminalComponent, AppConfigService, AppVersionService, ArticleBuilder, ArticleCardComponent, ArticleComponent, AttachmentUploaderComponent, AuthBackgroundComponent, AuthService, AuthStateService, AuthStorageService, AuthSyncService, AvatarComponent, AvatarUploadComponent, BOTTOM_NAV_DEFAULTS, BannerComponent, BaseDefault, BlogPostBuilder, BottomNavComponent, BoxComponent, BreadcrumbComponent, ButtonComponent, ButtonGroupComponent, CALLOUT_LABELS, CHEV_KEYS, CIRCLE_KEYS, COMMON_COUNTRY_CODES, COMMON_CURRENCIES, CORNER_KEYS, CTA_CARD_DEFAULTS, CURRENCY_INFO, CardComponent, CardSection, CardType, CardsCarouselComponent, ChangeEmailModalComponent, ChangePasswordModalComponent, CheckInputComponent, CheckboxRadioInputComponent, ChipGroupComponent, ClearDefault, ClearDefaultBlock, ClearDefaultFull, ClearDefaultRound, ClearDefaultRoundBlock, ClearDefaultRoundFull, CodeDisplayComponent, CommandDisplayComponent, CommentComponent, CommentInputComponent, CommentSectionComponent, CompanyFooterComponent, ComponentStates, ConfirmationDialogService, ContainerComponent, ContentLoaderComponent, ContentReactionComponent, ContentService, ContentTransformer, CookieBannerComponent, CountdownComponent, CtaCardComponent, CurrencyInputComponent, DEFAULT_ADS_CONFIG, DEFAULT_APP_CONFIG_SERVICE_CONFIG, DEFAULT_APP_VERSION_SERVICE_CONFIG, DEFAULT_AUTH_CONFIG, DEFAULT_BACK_HEADER, DEFAULT_CANCEL_BUTTON, DEFAULT_CHECK_INTERVAL_MS, DEFAULT_CONFIRM_BUTTON, DEFAULT_COUNTDOWN_LABELS, DEFAULT_COUNTDOWN_LABELS_EN, DEFAULT_DEBUG_CONSOLE_CONFIG, DEFAULT_DONATION_CONFIG, DEFAULT_EMPTY_STATE, DEFAULT_EMULATOR_CONFIG, DEFAULT_FEEDBACK_CONFIG, DEFAULT_FEEDBACK_TYPE_OPTIONS, DEFAULT_HOME_HEADER, DEFAULT_INFINITE_LIST_METADATA, DEFAULT_MODAL_CANCEL_BUTTON, DEFAULT_MODAL_CONFIRM_BUTTON, DEFAULT_PAGE_SIZE_OPTIONS, DEFAULT_PLATFORMS, DEFAULT_REFRESHER_METADATA, DEFAULT_SKELETON_CONFIG, DEFAULT_SPLASH_SCREEN_CONFIG, DataTableComponent, DateInputComponent, DateRangeInputComponent, DebugConsoleComponent, DetailSkeletonComponent, DeviceService, DisplayComponent, DividerComponent, DocsApiTableComponent, DocsBreadcrumbComponent, DocsBuilder, DocsCalloutComponent, DocsCodeExampleComponent, DocsLayoutComponent, DocsNavLinksComponent, DocsNavigationService, DocsPageComponent, DocsSearchComponent, DocsSectionComponent, DocsShellComponent, DocsSidebarComponent, DocsTocComponent, DonationService, DownloadService, EmailInputComponent, EmptyStateComponent, ExpandableTextComponent, FEATURES_LIST_DEFAULTS, FUN_MODAL_DEFAULTS, FabComponent, FaqComponent, FeaturesListComponent, FeedbackFormComponent, FeedbackService, FileInputComponent, FirebaseService, FirestoreCollectionFactory, FirestoreService, FooterComponent, FooterLinksComponent, FormComponent, FormFooterComponent, FormSkeletonComponent, FunHeaderComponent, FunModalComponent, GlassComponent, GlowCardComponent, GlowComponent, GridSkeletonComponent, HANDOFF_ROUTE_PARAM, HANDOFF_TOKEN_PARAM, HandoffService, HasPermissionDirective, HeaderComponent, HintComponent, HorizontalScrollComponent, HourInputComponent, HrefComponent, I18nService, IMAGE_DEFAULTS, INITIAL_AUTH_STATE, INITIAL_MFA_STATE, INVITATION_CARD_DEFAULTS, Icon, IconComponent, IconService, ImageComponent, ImageCropComponent, ImageService, InAppBrowserService, InfiniteListComponent, InfoComponent, InputI18nHelper, InputType, InvitationCardComponent, ItemListComponent, LANG_STORAGE_KEY$1 as LANG_STORAGE_KEY, LEGAL_CONTENT_CONFIG, LOGIN_DEFAULTS, LandingSplitComponent, LandingStepsComponent, LanguageSelectorComponent, LayeredCardComponent, LegalContentService, LegalLinkService, LinkComponent, LinkProcessorService, LinkedProvidersComponent, LinksAccordionComponent, LinksCakeComponent, ListSkeletonComponent, LoadingDirective, LocalStorageService, LocaleService, LoginComponent, MEDIA_OBJECT_DEFAULTS, MEMBER_CARD_DEFAULTS, MODAL_SIZES, MOTIF_KEYS, MOTION, MaintenancePageComponent, MarkdownArticleParserService, MediaObjectComponent, MemberCardComponent, MenuComponent, MessagingService, MetaService, MfaModalComponent, ModalService, ModalShellComponent, MultiSelectSearchComponent, NUM_KEYS, NavigationService, NetworkBannerComponent, NetworkStatusService, NewsBuilder, NoContentComponent, NotesBoxComponent, NotificationActionService, NotificationsService, NumberFromToComponent, NumberInputComponent, NumberStepperComponent, OAUTH_PROVIDERS_INFO, OAuthCallbackComponent, OAuthService, OrgService, OrgSwitchService, OutlineDefault, OutlineDefaultBlock, OutlineDefaultFull, OutlineDefaultRound, OutlineDefaultRoundBlock, OutlineDefaultRoundFull, PATTERN_MOTIFS, PATTERN_PALETTES, PATTERN_STYLE_CONFIGS, PLATFORM_CONFIGS, PageContentComponent, PageLinksComponent, PageRefreshService, PageTemplateComponent, PageWavesComponent, PageWrapperComponent, PaginationComponent, PaginationService, PasswordInputComponent, PatternComponent, PhoneInputComponent, PillComponent, PinInputComponent, PlainCodeBoxComponent, PopoverSelectorComponent, PreferencesService, PresetService, PriceTagComponent, PrimarySolidBlockButton, PrimarySolidBlockHrefButton, PrimarySolidBlockIconButton, PrimarySolidBlockIconHrefButton, PrimarySolidDefaultRoundButton, PrimarySolidDefaultRoundHrefButton, PrimarySolidDefaultRoundIconButton, PrimarySolidDefaultRoundIconHrefButton, PrimarySolidFullButton, PrimarySolidFullHrefButton, PrimarySolidFullIconButton, PrimarySolidFullIconHrefButton, PrimarySolidLargeRoundButton, PrimarySolidLargeRoundHrefButton, PrimarySolidLargeRoundIconButton, PrimarySolidLargeRoundIconHrefButton, PrimarySolidSmallRoundButton, PrimarySolidSmallRoundHrefButton, PrimarySolidSmallRoundIconButton, PrimarySolidSmallRoundIconHrefButton, ProcessLinksPipe, ProfileSkeletonComponent, ProgressBarComponent, ProgressRingComponent, ProgressStatusComponent, PrompterComponent, QR_PRESETS, QrCodeComponent, QrGeneratorService, QueryBuilder, QuoteBoxComponent, REQUEST_STATUSES, RadioInputComponent, RangeInputComponent, RatingComponent, RefresherComponent, RequestFirestoreService, RequestFormBuilderService, RequestService, RightsFooterComponent, RotatingTextComponent, SEARCH_HEADER_DEFAULTS, SHAPE_KEYS, SHARE_PROFILE_MODAL_DEFAULTS, SKELETON_LAYOUT_DEFAULT_ROWS, SKELETON_PRESETS, SOLID_KEYS, STATS_BAR_DEFAULTS, STROKE_KEYS, SearchHeaderComponent, SearchSelectorComponent, SearchbarComponent, SecondarySolidBlockButton, SecondarySolidBlockHrefButton, SecondarySolidBlockIconButton, SecondarySolidBlockIconHrefButton, SecondarySolidDefaultRoundButton, SecondarySolidDefaultRoundHrefButton, SecondarySolidDefaultRoundIconButton, SecondarySolidDefaultRoundIconHrefButton, SecondarySolidFullButton, SecondarySolidFullHrefButton, SecondarySolidFullIconButton, SecondarySolidFullIconHrefButton, SecondarySolidLargeRoundButton, SecondarySolidLargeRoundHrefButton, SecondarySolidLargeRoundIconButton, SecondarySolidLargeRoundIconHrefButton, SecondarySolidSmallRoundButton, SecondarySolidSmallRoundHrefButton, SecondarySolidSmallRoundIconButton, SecondarySolidSmallRoundIconHrefButton, SegmentControlComponent, SelectSearchComponent, SessionService, ShareButtonsComponent, ShareProfileModalComponent, SimpleComponent, SkeletonComponent, SkeletonLayoutComponent, SkeletonService, SolidBlockButton, SolidDefault, SolidDefaultBlock, SolidDefaultButton, SolidDefaultFull, SolidDefaultRound, SolidDefaultRoundBlock, SolidDefaultRoundButton, SolidDefaultRoundFull, SolidFullButton, SolidLargeButton, SolidLargeRoundButton, SolidSmallButton, SolidSmallRoundButton, SplashScreenService, StatsBarComponent, StatsCardComponent, StepperComponent, StorageService, SwipeCarouselComponent, TRI_KEYS, TabbedContentComponent, TableSkeletonComponent, TabsComponent, Terminal404Component, TestimonialCardComponent, TestimonialCarouselComponent, TextComponent, TextInputComponent, TextareaInputComponent, ThemeOption, ThemeService, TimelineComponent, TitleBlockComponent, TitleComponent, ToastService, ToggleInputComponent, TokenService, ToolbarActionType, ToolbarComponent, TranslatePipe, TypedCollection, UPDATE_BANNER_DEFAULT_CONTENT, UPDATE_BANNER_I18N_NAMESPACE, UpdateBannerComponent, UserAvatarComponent, UsernameInputComponent, VALTECH_ADS_CONFIG, VALTECH_APP_CONFIG, VALTECH_APP_VERSION, VALTECH_AUTH_CONFIG, VALTECH_COMPANY_LINKS, VALTECH_CONTENT_CONFIG, VALTECH_DEBUG_CONSOLE, VALTECH_DEFAULT_CONTENT, VALTECH_DONATION_CONFIG, VALTECH_FEEDBACK_CONFIG, VALTECH_FIREBASE_CONFIG, VALTECH_FOOTER_I18N, VALTECH_FOOTER_LOGO, VALTECH_LANGUAGE_SELECTOR, VALTECH_LEGAL_CONFIG, VALTECH_NETWORK_ERROR_KEY, VALTECH_SITE_PATHS, VALTECH_SOCIAL_LINKS, VALTECH_SPLASH_SCREEN, VALTECH_WEB_BASE_URLS, VERSION, ValtechErrorService, WizardComponent, WizardFooterComponent, applyDefaultValueToControl, authGuard, authInterceptor, authPasswordValidator, blogPost, buildFooterLinks, buildPath, collections, connectPageRefresh, createErrorStateProps, createFirebaseConfig, createGlowCardProps, createInitialPaginationState, createNumberFromToField, createRefreshableStream, createTitleProps, docs, errorLoggingInterceptor, extractPathParams, generatePatternTiles, generateRandomTile, getAppInfo, getAppVersion, getCollectionPath, getDocumentId, getTimeOfDayKey, goToTop, guestGuard, hasEmulators, interpretError, isAtEnd, isCollectionPath, isDocumentPath, isEmulatorMode, isValidPath, joinPath, maxLength, mulberry32, news, parseMarkdownArticle, permissionGuard, permissionGuardFromRoute, provideLegalContent, provideSplashScreen, provideValtechAds, provideValtechAppConfig, provideValtechAppVersion, provideValtechAuth, provideValtechAuthInterceptor, provideValtechContent, provideValtechDebugConsole, provideValtechDonations, provideValtechErrorHandling, provideValtechFeedback, provideValtechFirebase, provideValtechI18n, provideValtechLegal, provideValtechPresets, provideValtechSite, provideValtechSkeleton, query, renderPatternSvgInner, replaceSpecialChars, resolveColor, resolveInputDefaultValue, resolveWebBaseUrl, roleGuard, storagePaths, superAdminGuard, toArticle };
52520
+ export { ACTION_CARD_DEFAULTS, AD_SIZE_MAP, API_TABLE_COLUMN_LABELS, ARTICLE_CARD_DEFAULTS, ARTICLE_SPACING, ARTICLE_STRIP_DEFAULTS, AUTH_CTA_DEFAULTS, AVATAR_UPLOAD_DEFAULTS, AccordionComponent, ActionCardComponent, ActionHeaderComponent, ActionType, AdSlotComponent, AdsLoaderService, AdsService, AlertBoxComponent, AnalyticsErrorHandler, AnalyticsRouterTracker, AnalyticsService, AnimatedTerminalComponent, AppConfigService, AppVersionService, ArticleBuilder, ArticleCardComponent, ArticleComponent, ArticleStripComponent, AttachmentUploaderComponent, AuthBackgroundComponent, AuthCtaComponent, AuthService, AuthStateService, AuthStorageService, AuthSyncService, AvatarComponent, AvatarUploadComponent, BOTTOM_NAV_DEFAULTS, BannerComponent, BaseDefault, BlogPostBuilder, BottomNavComponent, BoxComponent, BreadcrumbComponent, ButtonComponent, ButtonGroupComponent, CALLOUT_LABELS, CHEV_KEYS, CIRCLE_KEYS, COMMON_COUNTRY_CODES, COMMON_CURRENCIES, CONTENT_CARD_DEFAULTS, CORNER_KEYS, CTA_CARD_DEFAULTS, CURRENCY_INFO, CardComponent, CardSection, CardType, CardsCarouselComponent, ChangeEmailModalComponent, ChangePasswordModalComponent, CheckInputComponent, CheckboxRadioInputComponent, ChipGroupComponent, ClearDefault, ClearDefaultBlock, ClearDefaultFull, ClearDefaultRound, ClearDefaultRoundBlock, ClearDefaultRoundFull, CodeDisplayComponent, CommandDisplayComponent, CommentComponent, CommentInputComponent, CommentSectionComponent, CompanyFooterComponent, ComponentStates, ConfirmationDialogService, ContainerComponent, ContentCardComponent, ContentLoaderComponent, ContentReactionComponent, ContentService, ContentTransformer, CookieBannerComponent, CountdownComponent, CtaCardComponent, CurrencyInputComponent, DEFAULT_ADS_CONFIG, DEFAULT_APP_CONFIG_SERVICE_CONFIG, DEFAULT_APP_VERSION_SERVICE_CONFIG, DEFAULT_AUTH_CONFIG, DEFAULT_BACK_HEADER, DEFAULT_CANCEL_BUTTON, DEFAULT_CHECK_INTERVAL_MS, DEFAULT_CONFIRM_BUTTON, DEFAULT_COUNTDOWN_LABELS, DEFAULT_COUNTDOWN_LABELS_EN, DEFAULT_DEBUG_CONSOLE_CONFIG, DEFAULT_DONATION_CONFIG, DEFAULT_EMPTY_STATE, DEFAULT_EMULATOR_CONFIG, DEFAULT_FEEDBACK_CONFIG, DEFAULT_FEEDBACK_TYPE_OPTIONS, DEFAULT_HOME_HEADER, DEFAULT_INFINITE_LIST_METADATA, DEFAULT_MODAL_CANCEL_BUTTON, DEFAULT_MODAL_CONFIRM_BUTTON, DEFAULT_PAGE_SIZE_OPTIONS, DEFAULT_PLATFORMS, DEFAULT_REFRESHER_METADATA, DEFAULT_SKELETON_CONFIG, DEFAULT_SPLASH_SCREEN_CONFIG, DataTableComponent, DateInputComponent, DateRangeInputComponent, DebugConsoleComponent, DetailSkeletonComponent, DeviceService, DisplayComponent, DividerComponent, DocsApiTableComponent, DocsBreadcrumbComponent, DocsBuilder, DocsCalloutComponent, DocsCodeExampleComponent, DocsLayoutComponent, DocsNavLinksComponent, DocsNavigationService, DocsPageComponent, DocsSearchComponent, DocsSectionComponent, DocsShellComponent, DocsSidebarComponent, DocsTocComponent, DonationService, DownloadService, EmailInputComponent, EmptyStateComponent, ExpandableTextComponent, FEATURES_LIST_DEFAULTS, FUN_MODAL_DEFAULTS, FabComponent, FaqComponent, FeaturesListComponent, FeedbackFormComponent, FeedbackService, FileInputComponent, FirebaseService, FirestoreCollectionFactory, FirestoreService, FooterComponent, FooterLinksComponent, FormComponent, FormFooterComponent, FormSkeletonComponent, FunHeaderComponent, FunModalComponent, GlassComponent, GlowCardComponent, GlowComponent, GridSkeletonComponent, HANDOFF_ROUTE_PARAM, HANDOFF_TOKEN_PARAM, HandoffService, HasPermissionDirective, HeaderComponent, HintComponent, HorizontalScrollComponent, HourInputComponent, HrefComponent, I18nService, IMAGE_DEFAULTS, INFO_CARD_DEFAULTS, INITIAL_AUTH_STATE, INITIAL_MFA_STATE, INVITATION_CARD_DEFAULTS, Icon, IconComponent, IconService, ImageComponent, ImageCropComponent, ImageService, InAppBrowserService, InfiniteListComponent, InfoCardComponent, InfoComponent, InputI18nHelper, InputType, InvitationCardComponent, ItemListComponent, LANG_STORAGE_KEY$1 as LANG_STORAGE_KEY, LEGAL_CONTENT_CONFIG, LOGIN_DEFAULTS, LandingSplitComponent, LandingStepsComponent, LanguageSelectorComponent, LayeredCardComponent, LegalContentService, LegalLinkService, LinkComponent, LinkProcessorService, LinkedProvidersComponent, LinksAccordionComponent, LinksCakeComponent, ListSkeletonComponent, LoadingDirective, LocalStorageService, LocaleService, LoginComponent, MEDIA_OBJECT_DEFAULTS, MEMBER_CARD_DEFAULTS, METRIC_CARD_DEFAULTS, MODAL_SIZES, MOTIF_KEYS, MOTION, MaintenancePageComponent, MarkdownArticleParserService, MediaObjectComponent, MemberCardComponent, MenuComponent, MessagingService, MetaService, MetricCardComponent, MfaModalComponent, ModalService, ModalShellComponent, MultiSelectSearchComponent, NUM_KEYS, NavigationService, NetworkBannerComponent, NetworkStatusService, NewsBuilder, NoContentComponent, NotesBoxComponent, NotificationActionService, NotificationsService, NumberFromToComponent, NumberInputComponent, NumberStepperComponent, OAUTH_PROVIDERS_INFO, OAuthCallbackComponent, OAuthService, OrgService, OrgSwitchService, OutlineDefault, OutlineDefaultBlock, OutlineDefaultFull, OutlineDefaultRound, OutlineDefaultRoundBlock, OutlineDefaultRoundFull, PATTERN_MOTIFS, PATTERN_PALETTES, PATTERN_STYLE_CONFIGS, PLATFORM_CONFIGS, PageContentComponent, PageLinksComponent, PageRefreshService, PageTemplateComponent, PageWavesComponent, PageWrapperComponent, PaginationComponent, PaginationService, PasswordInputComponent, PatternComponent, PhoneInputComponent, PillComponent, PinInputComponent, PlainCodeBoxComponent, PopoverSelectorComponent, PreferencesService, PresetService, PriceTagComponent, PrimarySolidBlockButton, PrimarySolidBlockHrefButton, PrimarySolidBlockIconButton, PrimarySolidBlockIconHrefButton, PrimarySolidDefaultRoundButton, PrimarySolidDefaultRoundHrefButton, PrimarySolidDefaultRoundIconButton, PrimarySolidDefaultRoundIconHrefButton, PrimarySolidFullButton, PrimarySolidFullHrefButton, PrimarySolidFullIconButton, PrimarySolidFullIconHrefButton, PrimarySolidLargeRoundButton, PrimarySolidLargeRoundHrefButton, PrimarySolidLargeRoundIconButton, PrimarySolidLargeRoundIconHrefButton, PrimarySolidSmallRoundButton, PrimarySolidSmallRoundHrefButton, PrimarySolidSmallRoundIconButton, PrimarySolidSmallRoundIconHrefButton, ProcessLinksPipe, ProfileSkeletonComponent, ProgressBarComponent, ProgressRingComponent, ProgressStatusComponent, PrompterComponent, QR_PRESETS, QrCodeComponent, QrGeneratorService, QueryBuilder, QuoteBoxComponent, REQUEST_STATUSES, RadioInputComponent, RangeInputComponent, RatingComponent, RefresherComponent, RequestFirestoreService, RequestFormBuilderService, RequestService, RightsFooterComponent, RotatingTextComponent, SEARCH_HEADER_DEFAULTS, SHAPE_KEYS, SHARE_PROFILE_MODAL_DEFAULTS, SKELETON_LAYOUT_DEFAULT_ROWS, SKELETON_PRESETS, SOLID_KEYS, STATS_BAR_DEFAULTS, STROKE_KEYS, SearchHeaderComponent, SearchSelectorComponent, SearchbarComponent, SecondarySolidBlockButton, SecondarySolidBlockHrefButton, SecondarySolidBlockIconButton, SecondarySolidBlockIconHrefButton, SecondarySolidDefaultRoundButton, SecondarySolidDefaultRoundHrefButton, SecondarySolidDefaultRoundIconButton, SecondarySolidDefaultRoundIconHrefButton, SecondarySolidFullButton, SecondarySolidFullHrefButton, SecondarySolidFullIconButton, SecondarySolidFullIconHrefButton, SecondarySolidLargeRoundButton, SecondarySolidLargeRoundHrefButton, SecondarySolidLargeRoundIconButton, SecondarySolidLargeRoundIconHrefButton, SecondarySolidSmallRoundButton, SecondarySolidSmallRoundHrefButton, SecondarySolidSmallRoundIconButton, SecondarySolidSmallRoundIconHrefButton, SegmentControlComponent, SelectSearchComponent, SessionService, ShareButtonsComponent, ShareProfileModalComponent, SimpleComponent, SkeletonComponent, SkeletonLayoutComponent, SkeletonService, SolidBlockButton, SolidDefault, SolidDefaultBlock, SolidDefaultButton, SolidDefaultFull, SolidDefaultRound, SolidDefaultRoundBlock, SolidDefaultRoundButton, SolidDefaultRoundFull, SolidFullButton, SolidLargeButton, SolidLargeRoundButton, SolidSmallButton, SolidSmallRoundButton, SplashScreenService, StatsBarComponent, StatsCardComponent, StepperComponent, StorageService, SwipeCarouselComponent, TRI_KEYS, TabbedContentComponent, TableSkeletonComponent, TabsComponent, Terminal404Component, TestimonialCardComponent, TestimonialCarouselComponent, TextComponent, TextInputComponent, TextareaInputComponent, ThemeOption, ThemeService, TimelineComponent, TitleBlockComponent, TitleComponent, ToastService, ToggleInputComponent, TokenService, ToolbarActionType, ToolbarComponent, TranslatePipe, TypedCollection, UPDATE_BANNER_DEFAULT_CONTENT, UPDATE_BANNER_I18N_NAMESPACE, UpdateBannerComponent, UserAvatarComponent, UsernameInputComponent, VALTECH_ADS_CONFIG, VALTECH_APP_CONFIG, VALTECH_APP_VERSION, VALTECH_AUTH_CONFIG, VALTECH_COMPANY_LINKS, VALTECH_CONTENT_CONFIG, VALTECH_DEBUG_CONSOLE, VALTECH_DEFAULT_CONTENT, VALTECH_DONATION_CONFIG, VALTECH_FEEDBACK_CONFIG, VALTECH_FIREBASE_CONFIG, VALTECH_FOOTER_I18N, VALTECH_FOOTER_LOGO, VALTECH_LANGUAGE_SELECTOR, VALTECH_LEGAL_CONFIG, VALTECH_NETWORK_ERROR_KEY, VALTECH_SITE_PATHS, VALTECH_SOCIAL_LINKS, VALTECH_SPLASH_SCREEN, VALTECH_WEB_BASE_URLS, VERSION, ValtechErrorService, WizardComponent, WizardFooterComponent, applyDefaultValueToControl, authGuard, authInterceptor, authPasswordValidator, blogPost, buildFooterLinks, buildPath, collections, connectPageRefresh, createErrorStateProps, createFirebaseConfig, createGlowCardProps, createInitialPaginationState, createNumberFromToField, createRefreshableStream, createTitleProps, docs, errorLoggingInterceptor, extractPathParams, generatePatternTiles, generateRandomTile, getAppInfo, getAppVersion, getCollectionPath, getDocumentId, getTimeOfDayKey, goToTop, guestGuard, hasEmulators, interpretError, isAtEnd, isCollectionPath, isDocumentPath, isEmulatorMode, isValidPath, joinPath, maxLength, mulberry32, news, parseMarkdownArticle, permissionGuard, permissionGuardFromRoute, provideLegalContent, provideSplashScreen, provideValtechAds, provideValtechAppConfig, provideValtechAppVersion, provideValtechAuth, provideValtechAuthInterceptor, provideValtechContent, provideValtechDebugConsole, provideValtechDonations, provideValtechErrorHandling, provideValtechFeedback, provideValtechFirebase, provideValtechI18n, provideValtechLegal, provideValtechPresets, provideValtechSite, provideValtechSkeleton, query, renderPatternSvgInner, replaceSpecialChars, resolveColor$1 as resolveColor, resolveInputDefaultValue, resolveWebBaseUrl, roleGuard, storagePaths, superAdminGuard, toArticle };
51834
52521
  //# sourceMappingURL=valtech-components.mjs.map