@camp2gether/c2g-ui 0.0.7

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 (56) hide show
  1. package/README.md +95 -0
  2. package/charts/index.d.ts +199 -0
  3. package/fesm2022/camp2gether-c2g-ui-beach-animation-ipi3OoKW.mjs +54156 -0
  4. package/fesm2022/camp2gether-c2g-ui-beach-animation-ipi3OoKW.mjs.map +1 -0
  5. package/fesm2022/camp2gether-c2g-ui-camping-animation-DY6XWXyF.mjs +35807 -0
  6. package/fesm2022/camp2gether-c2g-ui-camping-animation-DY6XWXyF.mjs.map +1 -0
  7. package/fesm2022/camp2gether-c2g-ui-car-animation-DnDp7WfG.mjs +45189 -0
  8. package/fesm2022/camp2gether-c2g-ui-car-animation-DnDp7WfG.mjs.map +1 -0
  9. package/fesm2022/camp2gether-c2g-ui-car-driving-landscape-animation-CawNeMKD.mjs +43833 -0
  10. package/fesm2022/camp2gether-c2g-ui-car-driving-landscape-animation-CawNeMKD.mjs.map +1 -0
  11. package/fesm2022/camp2gether-c2g-ui-cat-love-animation-ewC7fZyY.mjs +30789 -0
  12. package/fesm2022/camp2gether-c2g-ui-cat-love-animation-ewC7fZyY.mjs.map +1 -0
  13. package/fesm2022/camp2gether-c2g-ui-charts.mjs +404 -0
  14. package/fesm2022/camp2gether-c2g-ui-charts.mjs.map +1 -0
  15. package/fesm2022/camp2gether-c2g-ui-checklist-animation-DqUkcLqI.mjs +19868 -0
  16. package/fesm2022/camp2gether-c2g-ui-checklist-animation-DqUkcLqI.mjs.map +1 -0
  17. package/fesm2022/camp2gether-c2g-ui-coffee-time-animation-DQilaE0A.mjs +6816 -0
  18. package/fesm2022/camp2gether-c2g-ui-coffee-time-animation-DQilaE0A.mjs.map +1 -0
  19. package/fesm2022/camp2gether-c2g-ui-error-404-pdjg-EHb.mjs +49742 -0
  20. package/fesm2022/camp2gether-c2g-ui-error-404-pdjg-EHb.mjs.map +1 -0
  21. package/fesm2022/camp2gether-c2g-ui-fishing-animation-DwE3IF-V.mjs +38941 -0
  22. package/fesm2022/camp2gether-c2g-ui-fishing-animation-DwE3IF-V.mjs.map +1 -0
  23. package/fesm2022/camp2gether-c2g-ui-layout.mjs +768 -0
  24. package/fesm2022/camp2gether-c2g-ui-layout.mjs.map +1 -0
  25. package/fesm2022/camp2gether-c2g-ui-maps.mjs +223 -0
  26. package/fesm2022/camp2gether-c2g-ui-maps.mjs.map +1 -0
  27. package/fesm2022/camp2gether-c2g-ui-mountain-search-animation-TebM1gS4.mjs +69245 -0
  28. package/fesm2022/camp2gether-c2g-ui-mountain-search-animation-TebM1gS4.mjs.map +1 -0
  29. package/fesm2022/camp2gether-c2g-ui-planning-animation-D8QSsZk6.mjs +28330 -0
  30. package/fesm2022/camp2gether-c2g-ui-planning-animation-D8QSsZk6.mjs.map +1 -0
  31. package/fesm2022/camp2gether-c2g-ui-presets.mjs +2855 -0
  32. package/fesm2022/camp2gether-c2g-ui-presets.mjs.map +1 -0
  33. package/fesm2022/camp2gether-c2g-ui-share-animation-qgqs-k59.mjs +59129 -0
  34. package/fesm2022/camp2gether-c2g-ui-share-animation-qgqs-k59.mjs.map +1 -0
  35. package/fesm2022/camp2gether-c2g-ui-summer-camp-animation-DPzirVNH.mjs +89317 -0
  36. package/fesm2022/camp2gether-c2g-ui-summer-camp-animation-DPzirVNH.mjs.map +1 -0
  37. package/fesm2022/camp2gether-c2g-ui-theme.mjs +479 -0
  38. package/fesm2022/camp2gether-c2g-ui-theme.mjs.map +1 -0
  39. package/fesm2022/camp2gether-c2g-ui-thinking-animation--X3er_pf.mjs +27929 -0
  40. package/fesm2022/camp2gether-c2g-ui-thinking-animation--X3er_pf.mjs.map +1 -0
  41. package/fesm2022/camp2gether-c2g-ui-walking-avocado-animation-CQMU2C9-.mjs +4064 -0
  42. package/fesm2022/camp2gether-c2g-ui-walking-avocado-animation-CQMU2C9-.mjs.map +1 -0
  43. package/fesm2022/camp2gether-c2g-ui-walking-orange-animation-CTJniCsF.mjs +3113 -0
  44. package/fesm2022/camp2gether-c2g-ui-walking-orange-animation-CTJniCsF.mjs.map +1 -0
  45. package/fesm2022/camp2gether-c2g-ui-weather-partly-cloudy-animation-Cnw3W4cS.mjs +1731 -0
  46. package/fesm2022/camp2gether-c2g-ui-weather-partly-cloudy-animation-Cnw3W4cS.mjs.map +1 -0
  47. package/fesm2022/camp2gether-c2g-ui.mjs +2099 -0
  48. package/fesm2022/camp2gether-c2g-ui.mjs.map +1 -0
  49. package/index.d.ts +578 -0
  50. package/layout/index.d.ts +443 -0
  51. package/maps/index.d.ts +62 -0
  52. package/package.json +51 -0
  53. package/presets/index.d.ts +1437 -0
  54. package/src/lib/styles/design-tokens.css +153 -0
  55. package/src/lib/styles/themes.scss +346 -0
  56. package/theme/index.d.ts +63 -0
@@ -0,0 +1,768 @@
1
+ import * as i0 from '@angular/core';
2
+ import { input, ChangeDetectionStrategy, Component, computed, output, signal, forwardRef, model, effect } from '@angular/core';
3
+ import * as i1 from '@ngx-translate/core';
4
+ import { TranslateModule } from '@ngx-translate/core';
5
+ import * as i1$1 from '@angular/material/icon';
6
+ import { MatIconModule, MatIcon } from '@angular/material/icon';
7
+ import { ButtonComponent, LottieLoaderComponent } from '@humbeldore/c2g-ui';
8
+ import * as i1$2 from '@angular/material/button';
9
+ import { MatButtonModule } from '@angular/material/button';
10
+ import * as i3 from '@angular/material/tooltip';
11
+ import { MatTooltipModule } from '@angular/material/tooltip';
12
+ import * as i1$3 from '@angular/common';
13
+ import { CommonModule, NgClass, NgTemplateOutlet } from '@angular/common';
14
+ import { MatCard } from '@angular/material/card';
15
+ import { NG_VALUE_ACCESSOR } from '@angular/forms';
16
+ import * as i1$4 from '@angular/cdk/scrolling';
17
+ import { ScrollingModule } from '@angular/cdk/scrolling';
18
+
19
+ class ContentPanelComponent {
20
+ eyebrow = input('', ...(ngDevMode ? [{ debugName: "eyebrow" }] : []));
21
+ title = input('', ...(ngDevMode ? [{ debugName: "title" }] : []));
22
+ static ɵfac = i0.ɵɵngDeclareFactory({ minVersion: "12.0.0", version: "20.3.19", ngImport: i0, type: ContentPanelComponent, deps: [], target: i0.ɵɵFactoryTarget.Component });
23
+ static ɵcmp = i0.ɵɵngDeclareComponent({ minVersion: "17.0.0", version: "20.3.19", type: ContentPanelComponent, isStandalone: true, selector: "app-content-panel", inputs: { eyebrow: { classPropertyName: "eyebrow", publicName: "eyebrow", isSignal: true, isRequired: false, transformFunction: null }, title: { classPropertyName: "title", publicName: "title", isSignal: true, isRequired: false, transformFunction: null } }, ngImport: i0, template: "<article class=\"content-panel\">\n @if (eyebrow() || title()) {\n <header class=\"content-panel__header\">\n <div class=\"content-panel__header-text\">\n @if (eyebrow()) {\n <span class=\"content-panel__eyebrow\">{{ eyebrow() | translate }}</span>\n }\n @if (title()) {\n <h2 class=\"content-panel__title\">{{ title() | translate }}</h2>\n }\n </div>\n <div class=\"content-panel__actions\">\n <ng-content select=\"[panel-actions]\" />\n </div>\n </header>\n }\n <ng-content />\n</article>\n", styles: [".content-panel{background:var(--c2g-glass-bg, rgba(255, 255, 255, .95));border:1px solid var(--c2g-color-border-soft, rgba(17, 24, 39, .08));border-radius:var(--c2g-radius-xl, 1.125rem);box-shadow:var(--c2g-shadow-sm, 0 1px 2px rgba(15, 23, 42, .08));overflow:hidden}.content-panel__header{display:flex;align-items:flex-end;gap:var(--c2g-space-4, 1rem);padding:var(--c2g-space-6, 1.5rem) var(--c2g-space-6, 1.5rem) 0;flex-wrap:wrap}.content-panel__header-text{flex:1;min-width:0}.content-panel__eyebrow{display:block;font-size:var(--c2g-font-size-xs, .75rem);font-weight:var(--c2g-font-weight-bold, 700);letter-spacing:var(--c2g-letter-spacing-wide, .1em);text-transform:uppercase;color:var(--c2g-primary, #f97316);margin-bottom:var(--c2g-space-1, .25rem)}.content-panel__title{font-size:var(--c2g-font-size-lg, 1.25rem);font-weight:var(--c2g-font-weight-extrabold, 800);color:var(--c2g-text-primary, #1f2937);margin:0;letter-spacing:var(--c2g-letter-spacing-tight, -.02em)}.content-panel__actions{display:flex;align-items:center;gap:var(--c2g-space-2, .5rem);flex-wrap:wrap}\n"], dependencies: [{ kind: "ngmodule", type: TranslateModule }, { kind: "pipe", type: i1.TranslatePipe, name: "translate" }], changeDetection: i0.ChangeDetectionStrategy.OnPush });
24
+ }
25
+ i0.ɵɵngDeclareClassMetadata({ minVersion: "12.0.0", version: "20.3.19", ngImport: i0, type: ContentPanelComponent, decorators: [{
26
+ type: Component,
27
+ args: [{ selector: 'app-content-panel', standalone: true, changeDetection: ChangeDetectionStrategy.OnPush, imports: [TranslateModule], template: "<article class=\"content-panel\">\n @if (eyebrow() || title()) {\n <header class=\"content-panel__header\">\n <div class=\"content-panel__header-text\">\n @if (eyebrow()) {\n <span class=\"content-panel__eyebrow\">{{ eyebrow() | translate }}</span>\n }\n @if (title()) {\n <h2 class=\"content-panel__title\">{{ title() | translate }}</h2>\n }\n </div>\n <div class=\"content-panel__actions\">\n <ng-content select=\"[panel-actions]\" />\n </div>\n </header>\n }\n <ng-content />\n</article>\n", styles: [".content-panel{background:var(--c2g-glass-bg, rgba(255, 255, 255, .95));border:1px solid var(--c2g-color-border-soft, rgba(17, 24, 39, .08));border-radius:var(--c2g-radius-xl, 1.125rem);box-shadow:var(--c2g-shadow-sm, 0 1px 2px rgba(15, 23, 42, .08));overflow:hidden}.content-panel__header{display:flex;align-items:flex-end;gap:var(--c2g-space-4, 1rem);padding:var(--c2g-space-6, 1.5rem) var(--c2g-space-6, 1.5rem) 0;flex-wrap:wrap}.content-panel__header-text{flex:1;min-width:0}.content-panel__eyebrow{display:block;font-size:var(--c2g-font-size-xs, .75rem);font-weight:var(--c2g-font-weight-bold, 700);letter-spacing:var(--c2g-letter-spacing-wide, .1em);text-transform:uppercase;color:var(--c2g-primary, #f97316);margin-bottom:var(--c2g-space-1, .25rem)}.content-panel__title{font-size:var(--c2g-font-size-lg, 1.25rem);font-weight:var(--c2g-font-weight-extrabold, 800);color:var(--c2g-text-primary, #1f2937);margin:0;letter-spacing:var(--c2g-letter-spacing-tight, -.02em)}.content-panel__actions{display:flex;align-items:center;gap:var(--c2g-space-2, .5rem);flex-wrap:wrap}\n"] }]
28
+ }], propDecorators: { eyebrow: [{ type: i0.Input, args: [{ isSignal: true, alias: "eyebrow", required: false }] }], title: [{ type: i0.Input, args: [{ isSignal: true, alias: "title", required: false }] }] } });
29
+
30
+ class CoverageKpiComponent {
31
+ label = input.required(...(ngDevMode ? [{ debugName: "label" }] : []));
32
+ coveragePercent = input(0, ...(ngDevMode ? [{ debugName: "coveragePercent" }] : []));
33
+ ringCircumference = 125.66;
34
+ ringOffset = computed(() => this.ringCircumference * (1 - this.coveragePercent() / 100), ...(ngDevMode ? [{ debugName: "ringOffset" }] : []));
35
+ static ɵfac = i0.ɵɵngDeclareFactory({ minVersion: "12.0.0", version: "20.3.19", ngImport: i0, type: CoverageKpiComponent, deps: [], target: i0.ɵɵFactoryTarget.Component });
36
+ static ɵcmp = i0.ɵɵngDeclareComponent({ minVersion: "17.1.0", version: "20.3.19", type: CoverageKpiComponent, isStandalone: true, selector: "app-coverage-kpi", inputs: { label: { classPropertyName: "label", publicName: "label", isSignal: true, isRequired: true, transformFunction: null }, coveragePercent: { classPropertyName: "coveragePercent", publicName: "coveragePercent", isSignal: true, isRequired: false, transformFunction: null } }, ngImport: i0, template: "<div class=\"coverage-kpi\" role=\"listitem\">\n <div class=\"coverage-kpi__content\">\n <div class=\"coverage-kpi__ring\" aria-hidden=\"true\">\n <svg viewBox=\"0 0 48 48\">\n <circle class=\"coverage-kpi__ring-bg\" cx=\"24\" cy=\"24\" r=\"20\" />\n <circle\n class=\"coverage-kpi__ring-fill\"\n cx=\"24\"\n cy=\"24\"\n r=\"20\"\n [style.stroke-dasharray]=\"ringCircumference\"\n [style.stroke-dashoffset]=\"ringOffset()\"\n />\n </svg>\n <span class=\"coverage-kpi__percent\">{{ coveragePercent() }}%</span>\n </div>\n\n <span class=\"coverage-kpi__label\">{{ label() }}</span>\n </div>\n</div>", styles: [":host{display:block;width:100%;height:100%}.coverage-kpi{box-sizing:border-box;background:#63b3ed26;border:1px solid rgba(255,255,255,.15);border-radius:14px;padding:16px;display:flex;flex-direction:column;justify-content:space-between;gap:12px;height:100%;position:relative;overflow:hidden}.coverage-kpi__content{display:flex;flex-direction:column;justify-content:center;align-items:center;gap:10px;height:100%}.coverage-kpi__label{font-size:12px;opacity:.8;text-transform:uppercase;letter-spacing:.06em;line-height:1.25;text-align:center}.coverage-kpi__ring{position:relative;width:56px;height:56px;display:flex;align-items:center;justify-content:center}.coverage-kpi__ring svg{width:100%;height:100%;transform:rotate(-90deg)}.coverage-kpi__ring-bg{fill:none;stroke:#ffffff26;stroke-width:4}.coverage-kpi__ring-fill{fill:none;stroke:var(--c2g-color-secondary);stroke-width:4;stroke-linecap:round;transition:stroke-dashoffset .6s ease}.coverage-kpi__percent{position:absolute;inset:0;display:flex;align-items:center;justify-content:center;font-size:12px;font-weight:800}@media(max-width:1024px){.coverage-kpi{padding:14px}.coverage-kpi__content{gap:8px}.coverage-kpi__ring{width:54px;height:54px}.coverage-kpi__label,.coverage-kpi__percent{font-size:11px}}@media(max-width:640px){.coverage-kpi{padding:12px 14px}.coverage-kpi__content{gap:6px}.coverage-kpi__ring{width:48px;height:48px}.coverage-kpi__label,.coverage-kpi__percent{font-size:10px}.coverage-kpi__ring-bg,.coverage-kpi__ring-fill{stroke-width:3}}\n"], changeDetection: i0.ChangeDetectionStrategy.OnPush });
37
+ }
38
+ i0.ɵɵngDeclareClassMetadata({ minVersion: "12.0.0", version: "20.3.19", ngImport: i0, type: CoverageKpiComponent, decorators: [{
39
+ type: Component,
40
+ args: [{ selector: 'app-coverage-kpi', standalone: true, changeDetection: ChangeDetectionStrategy.OnPush, imports: [], template: "<div class=\"coverage-kpi\" role=\"listitem\">\n <div class=\"coverage-kpi__content\">\n <div class=\"coverage-kpi__ring\" aria-hidden=\"true\">\n <svg viewBox=\"0 0 48 48\">\n <circle class=\"coverage-kpi__ring-bg\" cx=\"24\" cy=\"24\" r=\"20\" />\n <circle\n class=\"coverage-kpi__ring-fill\"\n cx=\"24\"\n cy=\"24\"\n r=\"20\"\n [style.stroke-dasharray]=\"ringCircumference\"\n [style.stroke-dashoffset]=\"ringOffset()\"\n />\n </svg>\n <span class=\"coverage-kpi__percent\">{{ coveragePercent() }}%</span>\n </div>\n\n <span class=\"coverage-kpi__label\">{{ label() }}</span>\n </div>\n</div>", styles: [":host{display:block;width:100%;height:100%}.coverage-kpi{box-sizing:border-box;background:#63b3ed26;border:1px solid rgba(255,255,255,.15);border-radius:14px;padding:16px;display:flex;flex-direction:column;justify-content:space-between;gap:12px;height:100%;position:relative;overflow:hidden}.coverage-kpi__content{display:flex;flex-direction:column;justify-content:center;align-items:center;gap:10px;height:100%}.coverage-kpi__label{font-size:12px;opacity:.8;text-transform:uppercase;letter-spacing:.06em;line-height:1.25;text-align:center}.coverage-kpi__ring{position:relative;width:56px;height:56px;display:flex;align-items:center;justify-content:center}.coverage-kpi__ring svg{width:100%;height:100%;transform:rotate(-90deg)}.coverage-kpi__ring-bg{fill:none;stroke:#ffffff26;stroke-width:4}.coverage-kpi__ring-fill{fill:none;stroke:var(--c2g-color-secondary);stroke-width:4;stroke-linecap:round;transition:stroke-dashoffset .6s ease}.coverage-kpi__percent{position:absolute;inset:0;display:flex;align-items:center;justify-content:center;font-size:12px;font-weight:800}@media(max-width:1024px){.coverage-kpi{padding:14px}.coverage-kpi__content{gap:8px}.coverage-kpi__ring{width:54px;height:54px}.coverage-kpi__label,.coverage-kpi__percent{font-size:11px}}@media(max-width:640px){.coverage-kpi{padding:12px 14px}.coverage-kpi__content{gap:6px}.coverage-kpi__ring{width:48px;height:48px}.coverage-kpi__label,.coverage-kpi__percent{font-size:10px}.coverage-kpi__ring-bg,.coverage-kpi__ring-fill{stroke-width:3}}\n"] }]
41
+ }], propDecorators: { label: [{ type: i0.Input, args: [{ isSignal: true, alias: "label", required: true }] }], coveragePercent: [{ type: i0.Input, args: [{ isSignal: true, alias: "coveragePercent", required: false }] }] } });
42
+
43
+ class HeroComponent {
44
+ eyebrow = input(...(ngDevMode ? [undefined, { debugName: "eyebrow" }] : []));
45
+ title = input(...(ngDevMode ? [undefined, { debugName: "title" }] : []));
46
+ lead = input(...(ngDevMode ? [undefined, { debugName: "lead" }] : []));
47
+ static ɵfac = i0.ɵɵngDeclareFactory({ minVersion: "12.0.0", version: "20.3.19", ngImport: i0, type: HeroComponent, deps: [], target: i0.ɵɵFactoryTarget.Component });
48
+ static ɵcmp = i0.ɵɵngDeclareComponent({ minVersion: "17.0.0", version: "20.3.19", type: HeroComponent, isStandalone: true, selector: "app-hero", inputs: { eyebrow: { classPropertyName: "eyebrow", publicName: "eyebrow", isSignal: true, isRequired: false, transformFunction: null }, title: { classPropertyName: "title", publicName: "title", isSignal: true, isRequired: false, transformFunction: null }, lead: { classPropertyName: "lead", publicName: "lead", isSignal: true, isRequired: false, transformFunction: null } }, ngImport: i0, template: "<section class=\"hero\">\n @if (eyebrow()) {\n <div class=\"hero__eyebrow\">\n <mat-icon class=\"hero__icon\">backpack</mat-icon>\n <span>{{ eyebrow() }}</span>\n </div>\n }\n\n <h1 class=\"hero__title\">{{ title() }}</h1>\n <p class=\"hero__lead\">{{ lead() }}</p>\n\n <ng-content></ng-content>\n</section>\n", styles: [".hero{background:linear-gradient(135deg,var(--c2g-dark-bg, #16213e) 0%,#0f3460 100%);border-radius:20px;padding:32px;margin-bottom:24px;color:#fff}.hero__eyebrow{display:flex;align-items:center;gap:8px;font-size:12px;font-weight:600;letter-spacing:.1em;text-transform:uppercase;opacity:.7;margin-bottom:8px}.hero__icon{font-size:18px;width:18px;height:18px;flex-shrink:0}.hero__title{font-size:28px;font-weight:700;margin:0 0 24px;line-height:1.2}.hero__lead{font-size:14px;line-height:1.6;color:#ffffffa6;margin:0 0 24px;max-width:560px}@media(max-width:1024px){.hero{padding:28px 22px}.hero__title{font-size:24px}.hero__lead{font-size:13px;margin-bottom:18px}}@media(max-width:640px){.hero{padding:24px 16px}.hero__title{font-size:22px}.hero__lead{font-size:13px;margin-bottom:14px}}\n"], dependencies: [{ kind: "ngmodule", type: MatIconModule }, { kind: "component", type: i1$1.MatIcon, selector: "mat-icon", inputs: ["color", "inline", "svgIcon", "fontSet", "fontIcon"], exportAs: ["matIcon"] }, { kind: "ngmodule", type: TranslateModule }], changeDetection: i0.ChangeDetectionStrategy.OnPush });
49
+ }
50
+ i0.ɵɵngDeclareClassMetadata({ minVersion: "12.0.0", version: "20.3.19", ngImport: i0, type: HeroComponent, decorators: [{
51
+ type: Component,
52
+ args: [{ selector: 'app-hero', standalone: true, changeDetection: ChangeDetectionStrategy.OnPush, imports: [MatIconModule, TranslateModule], template: "<section class=\"hero\">\n @if (eyebrow()) {\n <div class=\"hero__eyebrow\">\n <mat-icon class=\"hero__icon\">backpack</mat-icon>\n <span>{{ eyebrow() }}</span>\n </div>\n }\n\n <h1 class=\"hero__title\">{{ title() }}</h1>\n <p class=\"hero__lead\">{{ lead() }}</p>\n\n <ng-content></ng-content>\n</section>\n", styles: [".hero{background:linear-gradient(135deg,var(--c2g-dark-bg, #16213e) 0%,#0f3460 100%);border-radius:20px;padding:32px;margin-bottom:24px;color:#fff}.hero__eyebrow{display:flex;align-items:center;gap:8px;font-size:12px;font-weight:600;letter-spacing:.1em;text-transform:uppercase;opacity:.7;margin-bottom:8px}.hero__icon{font-size:18px;width:18px;height:18px;flex-shrink:0}.hero__title{font-size:28px;font-weight:700;margin:0 0 24px;line-height:1.2}.hero__lead{font-size:14px;line-height:1.6;color:#ffffffa6;margin:0 0 24px;max-width:560px}@media(max-width:1024px){.hero{padding:28px 22px}.hero__title{font-size:24px}.hero__lead{font-size:13px;margin-bottom:18px}}@media(max-width:640px){.hero{padding:24px 16px}.hero__title{font-size:22px}.hero__lead{font-size:13px;margin-bottom:14px}}\n"] }]
53
+ }], propDecorators: { eyebrow: [{ type: i0.Input, args: [{ isSignal: true, alias: "eyebrow", required: false }] }], title: [{ type: i0.Input, args: [{ isSignal: true, alias: "title", required: false }] }], lead: [{ type: i0.Input, args: [{ isSignal: true, alias: "lead", required: false }] }] } });
54
+
55
+ class KpiCardComponent {
56
+ value = input.required(...(ngDevMode ? [{ debugName: "value" }] : []));
57
+ label = input.required(...(ngDevMode ? [{ debugName: "label" }] : []));
58
+ icon = input.required(...(ngDevMode ? [{ debugName: "icon" }] : []));
59
+ tone = input.required(...(ngDevMode ? [{ debugName: "tone" }] : []));
60
+ static ɵfac = i0.ɵɵngDeclareFactory({ minVersion: "12.0.0", version: "20.3.19", ngImport: i0, type: KpiCardComponent, deps: [], target: i0.ɵɵFactoryTarget.Component });
61
+ static ɵcmp = i0.ɵɵngDeclareComponent({ minVersion: "17.1.0", version: "20.3.19", type: KpiCardComponent, isStandalone: true, selector: "app-kpi-card", inputs: { value: { classPropertyName: "value", publicName: "value", isSignal: true, isRequired: true, transformFunction: null }, label: { classPropertyName: "label", publicName: "label", isSignal: true, isRequired: true, transformFunction: null }, icon: { classPropertyName: "icon", publicName: "icon", isSignal: true, isRequired: true, transformFunction: null }, tone: { classPropertyName: "tone", publicName: "tone", isSignal: true, isRequired: true, transformFunction: null } }, ngImport: i0, template: "<div class=\"kpi-card\" [class]=\"'kpi-card kpi-card--' + tone()\" role=\"listitem\">\n <div class=\"kpi-card__content\">\n <span class=\"kpi-card__value\">{{ value() }}</span>\n <span class=\"kpi-card__label\">{{ label() }}</span>\n </div>\n <mat-icon class=\"kpi-card__icon\">{{ icon() }}</mat-icon>\n</div>", styles: [":host{display:block;width:100%;height:100%}.kpi-card{box-sizing:border-box;background:#ffffff1a;border:1px solid rgba(255,255,255,.15);border-radius:14px;padding:16px;display:flex;flex-direction:column;justify-content:space-between;gap:12px;height:100%;position:relative;overflow:hidden}.kpi-card__content{display:flex;flex-direction:column;gap:6px;padding-right:20px}.kpi-card--owned{background:#48bb7826}.kpi-card--missing{background:#f5656526}.kpi-card--total{background:#ed893626}.kpi-card__value{font-size:28px;font-weight:700;line-height:1.05}.kpi-card__label{font-size:12px;opacity:.8;text-transform:uppercase;letter-spacing:.06em;line-height:1.25}.kpi-card__icon{position:absolute;top:12px;right:12px;font-size:18px;width:18px;height:18px;color:#ffffff40}.kpi-card--owned .kpi-card__icon{color:#3f9d76b3}.kpi-card--missing .kpi-card__icon{color:#dd4c4c99}.kpi-card--total .kpi-card__icon{color:#ff6b3599}@media(max-width:1024px){.kpi-card{padding:14px}.kpi-card__content{gap:4px;padding-right:18px}.kpi-card__value{font-size:25px}.kpi-card__label{font-size:11px}}@media(max-width:640px){.kpi-card{padding:12px 14px}.kpi-card__content{gap:4px;padding-right:18px}.kpi-card__value{font-size:22px}.kpi-card__label{font-size:10px}.kpi-card__icon{font-size:16px;width:16px;height:16px}}\n"], dependencies: [{ kind: "ngmodule", type: MatIconModule }, { kind: "component", type: i1$1.MatIcon, selector: "mat-icon", inputs: ["color", "inline", "svgIcon", "fontSet", "fontIcon"], exportAs: ["matIcon"] }], changeDetection: i0.ChangeDetectionStrategy.OnPush });
62
+ }
63
+ i0.ɵɵngDeclareClassMetadata({ minVersion: "12.0.0", version: "20.3.19", ngImport: i0, type: KpiCardComponent, decorators: [{
64
+ type: Component,
65
+ args: [{ selector: 'app-kpi-card', standalone: true, changeDetection: ChangeDetectionStrategy.OnPush, imports: [MatIconModule], template: "<div class=\"kpi-card\" [class]=\"'kpi-card kpi-card--' + tone()\" role=\"listitem\">\n <div class=\"kpi-card__content\">\n <span class=\"kpi-card__value\">{{ value() }}</span>\n <span class=\"kpi-card__label\">{{ label() }}</span>\n </div>\n <mat-icon class=\"kpi-card__icon\">{{ icon() }}</mat-icon>\n</div>", styles: [":host{display:block;width:100%;height:100%}.kpi-card{box-sizing:border-box;background:#ffffff1a;border:1px solid rgba(255,255,255,.15);border-radius:14px;padding:16px;display:flex;flex-direction:column;justify-content:space-between;gap:12px;height:100%;position:relative;overflow:hidden}.kpi-card__content{display:flex;flex-direction:column;gap:6px;padding-right:20px}.kpi-card--owned{background:#48bb7826}.kpi-card--missing{background:#f5656526}.kpi-card--total{background:#ed893626}.kpi-card__value{font-size:28px;font-weight:700;line-height:1.05}.kpi-card__label{font-size:12px;opacity:.8;text-transform:uppercase;letter-spacing:.06em;line-height:1.25}.kpi-card__icon{position:absolute;top:12px;right:12px;font-size:18px;width:18px;height:18px;color:#ffffff40}.kpi-card--owned .kpi-card__icon{color:#3f9d76b3}.kpi-card--missing .kpi-card__icon{color:#dd4c4c99}.kpi-card--total .kpi-card__icon{color:#ff6b3599}@media(max-width:1024px){.kpi-card{padding:14px}.kpi-card__content{gap:4px;padding-right:18px}.kpi-card__value{font-size:25px}.kpi-card__label{font-size:11px}}@media(max-width:640px){.kpi-card{padding:12px 14px}.kpi-card__content{gap:4px;padding-right:18px}.kpi-card__value{font-size:22px}.kpi-card__label{font-size:10px}.kpi-card__icon{font-size:16px;width:16px;height:16px}}\n"] }]
66
+ }], propDecorators: { value: [{ type: i0.Input, args: [{ isSignal: true, alias: "value", required: true }] }], label: [{ type: i0.Input, args: [{ isSignal: true, alias: "label", required: true }] }], icon: [{ type: i0.Input, args: [{ isSignal: true, alias: "icon", required: true }] }], tone: [{ type: i0.Input, args: [{ isSignal: true, alias: "tone", required: true }] }] } });
67
+
68
+ class DangerZoneItemComponent {
69
+ item = input.required(...(ngDevMode ? [{ debugName: "item" }] : []));
70
+ triggered = output();
71
+ titleKey() {
72
+ return this.item().titleKey ?? this.item().title ?? '';
73
+ }
74
+ descriptionKey() {
75
+ return this.item().descriptionKey ?? this.item().description ?? null;
76
+ }
77
+ actionLabelKey() {
78
+ return this.item().action.labelKey ?? this.item().action.label ?? '';
79
+ }
80
+ actionAriaLabelKey() {
81
+ return this.item().action.ariaLabelKey ?? this.item().action.labelKey ?? this.item().action.ariaLabel ?? this.item().action.label ?? '';
82
+ }
83
+ onTriggered() {
84
+ this.triggered.emit(this.item());
85
+ }
86
+ static ɵfac = i0.ɵɵngDeclareFactory({ minVersion: "12.0.0", version: "20.3.19", ngImport: i0, type: DangerZoneItemComponent, deps: [], target: i0.ɵɵFactoryTarget.Component });
87
+ static ɵcmp = i0.ɵɵngDeclareComponent({ minVersion: "17.0.0", version: "20.3.19", type: DangerZoneItemComponent, isStandalone: true, selector: "c2g-danger-zone-item", inputs: { item: { classPropertyName: "item", publicName: "item", isSignal: true, isRequired: true, transformFunction: null } }, outputs: { triggered: "triggered" }, ngImport: i0, template: "<div class=\"c2g-danger-zone-item\">\n <div class=\"c2g-danger-zone-item__info\">\n <span class=\"c2g-danger-zone-item__label\">{{ titleKey() | translate }}</span>\n @if (descriptionKey(); as descriptionKey) {\n <span class=\"c2g-danger-zone-item__hint\">{{ descriptionKey | translate }}</span>\n }\n </div>\n\n <c2g-button\n [variant]=\"item().action.variant ?? 'secondary'\"\n [icon]=\"item().action.icon ?? ''\"\n [ariaLabel]=\"actionAriaLabelKey() | translate\"\n [disabled]=\"item().action.disabled ?? false\"\n (clicked)=\"onTriggered()\"\n >\n {{ actionLabelKey() | translate }}\n </c2g-button>\n</div>\n", styles: [".c2g-danger-zone-item{display:flex;align-items:flex-start;gap:1rem;justify-content:space-between;padding:.875rem 1.25rem}.c2g-danger-zone-item__info{display:flex;flex-direction:column;gap:4px;flex:1;min-width:0}.c2g-danger-zone-item__label{font-size:.9rem;color:var(--c2g-text-primary, #1a1a1a);font-weight:500}.c2g-danger-zone-item__hint{font-size:.8rem;color:var(--c2g-text-muted, #666);line-height:1.4}@media(max-width:639px){.c2g-danger-zone-item{flex-direction:column;align-items:stretch}}\n"], dependencies: [{ kind: "component", type: ButtonComponent, selector: "c2g-button", inputs: ["variant", "size", "disabled", "loading", "icon", "iconPosition", "iconOnly", "ariaLabel", "loadingAriaLabel", "type"], outputs: ["clicked"] }, { kind: "ngmodule", type: TranslateModule }, { kind: "pipe", type: i1.TranslatePipe, name: "translate" }], changeDetection: i0.ChangeDetectionStrategy.OnPush });
88
+ }
89
+ i0.ɵɵngDeclareClassMetadata({ minVersion: "12.0.0", version: "20.3.19", ngImport: i0, type: DangerZoneItemComponent, decorators: [{
90
+ type: Component,
91
+ args: [{ selector: 'c2g-danger-zone-item', standalone: true, changeDetection: ChangeDetectionStrategy.OnPush, imports: [ButtonComponent, TranslateModule], template: "<div class=\"c2g-danger-zone-item\">\n <div class=\"c2g-danger-zone-item__info\">\n <span class=\"c2g-danger-zone-item__label\">{{ titleKey() | translate }}</span>\n @if (descriptionKey(); as descriptionKey) {\n <span class=\"c2g-danger-zone-item__hint\">{{ descriptionKey | translate }}</span>\n }\n </div>\n\n <c2g-button\n [variant]=\"item().action.variant ?? 'secondary'\"\n [icon]=\"item().action.icon ?? ''\"\n [ariaLabel]=\"actionAriaLabelKey() | translate\"\n [disabled]=\"item().action.disabled ?? false\"\n (clicked)=\"onTriggered()\"\n >\n {{ actionLabelKey() | translate }}\n </c2g-button>\n</div>\n", styles: [".c2g-danger-zone-item{display:flex;align-items:flex-start;gap:1rem;justify-content:space-between;padding:.875rem 1.25rem}.c2g-danger-zone-item__info{display:flex;flex-direction:column;gap:4px;flex:1;min-width:0}.c2g-danger-zone-item__label{font-size:.9rem;color:var(--c2g-text-primary, #1a1a1a);font-weight:500}.c2g-danger-zone-item__hint{font-size:.8rem;color:var(--c2g-text-muted, #666);line-height:1.4}@media(max-width:639px){.c2g-danger-zone-item{flex-direction:column;align-items:stretch}}\n"] }]
92
+ }], propDecorators: { item: [{ type: i0.Input, args: [{ isSignal: true, alias: "item", required: true }] }], triggered: [{ type: i0.Output, args: ["triggered"] }] } });
93
+
94
+ class DangerZoneComponent {
95
+ headingKey = input('c2g.danger_zone.default.heading', ...(ngDevMode ? [{ debugName: "headingKey" }] : []));
96
+ items = input.required(...(ngDevMode ? [{ debugName: "items" }] : []));
97
+ /**
98
+ * Emits the clicked item id so consumers can map actions in their container.
99
+ *
100
+ * Prefer the per-item callback (`item.onTrigger`) when you want action logic to
101
+ * live directly on each item config.
102
+ *
103
+ * Output binding:
104
+ * ```html
105
+ * <c2g-danger-zone [items]="dangerItems" (itemTriggered)="onDangerAction($event)" />
106
+ * ```
107
+ *
108
+ * Example mapping:
109
+ * ```ts
110
+ * onDangerAction(id: string) {
111
+ * if (id === 'delete-project') {
112
+ * this.openDeleteDialog();
113
+ * }
114
+ * }
115
+ * ```
116
+ */
117
+ itemTriggered = output();
118
+ resolvedHeadingKey = computed(() => this.headingKey(), ...(ngDevMode ? [{ debugName: "resolvedHeadingKey" }] : []));
119
+ onItemTriggered(item) {
120
+ item.onTrigger?.(item);
121
+ this.itemTriggered.emit(item.id);
122
+ }
123
+ static ɵfac = i0.ɵɵngDeclareFactory({ minVersion: "12.0.0", version: "20.3.19", ngImport: i0, type: DangerZoneComponent, deps: [], target: i0.ɵɵFactoryTarget.Component });
124
+ static ɵcmp = i0.ɵɵngDeclareComponent({ minVersion: "17.0.0", version: "20.3.19", type: DangerZoneComponent, isStandalone: true, selector: "c2g-danger-zone", inputs: { headingKey: { classPropertyName: "headingKey", publicName: "headingKey", isSignal: true, isRequired: false, transformFunction: null }, items: { classPropertyName: "items", publicName: "items", isSignal: true, isRequired: true, transformFunction: null } }, outputs: { itemTriggered: "itemTriggered" }, ngImport: i0, template: "<section class=\"c2g-danger-zone\" aria-labelledby=\"c2g-danger-zone-heading\">\n <h2 id=\"c2g-danger-zone-heading\" class=\"c2g-danger-zone__heading\">\n {{ resolvedHeadingKey() | translate }}\n </h2>\n\n <div class=\"c2g-danger-zone__content\">\n @for (item of items(); track item.id; let last = $last) {\n <c2g-danger-zone-item [item]=\"item\" (triggered)=\"onItemTriggered($event)\" />\n\n @if (!last) {\n <div class=\"c2g-danger-zone__divider\" aria-hidden=\"true\"></div>\n }\n }\n </div>\n</section>", styles: [".c2g-danger-zone{background:var(--c2g-card-background, #fff);border-radius:12px;border:1px solid var(--c2g-outline-variant, #d8d8d8);border-top:3px solid var(--mat-sys-error, #d32f2f);overflow:hidden}.c2g-danger-zone__heading{margin:0;padding:1rem 1.25rem .75rem;font-size:.875rem;font-weight:700;color:var(--mat-sys-error, #d32f2f);letter-spacing:.02em;text-transform:uppercase;background:var(--c2g-bg-primary, #f8f8f8);border-bottom:1px solid var(--c2g-outline-variant, #d8d8d8)}.c2g-danger-zone__content{padding:.25rem 0}.c2g-danger-zone__divider{height:1px;margin:0 1.25rem;background:var(--c2g-outline-variant, #d8d8d8)}\n"], dependencies: [{ kind: "component", type: DangerZoneItemComponent, selector: "c2g-danger-zone-item", inputs: ["item"], outputs: ["triggered"] }, { kind: "ngmodule", type: TranslateModule }, { kind: "pipe", type: i1.TranslatePipe, name: "translate" }], changeDetection: i0.ChangeDetectionStrategy.OnPush });
125
+ }
126
+ i0.ɵɵngDeclareClassMetadata({ minVersion: "12.0.0", version: "20.3.19", ngImport: i0, type: DangerZoneComponent, decorators: [{
127
+ type: Component,
128
+ args: [{ selector: 'c2g-danger-zone', standalone: true, changeDetection: ChangeDetectionStrategy.OnPush, imports: [DangerZoneItemComponent, TranslateModule], template: "<section class=\"c2g-danger-zone\" aria-labelledby=\"c2g-danger-zone-heading\">\n <h2 id=\"c2g-danger-zone-heading\" class=\"c2g-danger-zone__heading\">\n {{ resolvedHeadingKey() | translate }}\n </h2>\n\n <div class=\"c2g-danger-zone__content\">\n @for (item of items(); track item.id; let last = $last) {\n <c2g-danger-zone-item [item]=\"item\" (triggered)=\"onItemTriggered($event)\" />\n\n @if (!last) {\n <div class=\"c2g-danger-zone__divider\" aria-hidden=\"true\"></div>\n }\n }\n </div>\n</section>", styles: [".c2g-danger-zone{background:var(--c2g-card-background, #fff);border-radius:12px;border:1px solid var(--c2g-outline-variant, #d8d8d8);border-top:3px solid var(--mat-sys-error, #d32f2f);overflow:hidden}.c2g-danger-zone__heading{margin:0;padding:1rem 1.25rem .75rem;font-size:.875rem;font-weight:700;color:var(--mat-sys-error, #d32f2f);letter-spacing:.02em;text-transform:uppercase;background:var(--c2g-bg-primary, #f8f8f8);border-bottom:1px solid var(--c2g-outline-variant, #d8d8d8)}.c2g-danger-zone__content{padding:.25rem 0}.c2g-danger-zone__divider{height:1px;margin:0 1.25rem;background:var(--c2g-outline-variant, #d8d8d8)}\n"] }]
129
+ }], propDecorators: { headingKey: [{ type: i0.Input, args: [{ isSignal: true, alias: "headingKey", required: false }] }], items: [{ type: i0.Input, args: [{ isSignal: true, alias: "items", required: true }] }], itemTriggered: [{ type: i0.Output, args: ["itemTriggered"] }] } });
130
+
131
+ class ListItemComponent {
132
+ group = input(null, ...(ngDevMode ? [{ debugName: "group" }] : []));
133
+ active = input(false, ...(ngDevMode ? [{ debugName: "active" }] : []));
134
+ selected = output();
135
+ opened = output();
136
+ static ɵfac = i0.ɵɵngDeclareFactory({ minVersion: "12.0.0", version: "20.3.19", ngImport: i0, type: ListItemComponent, deps: [], target: i0.ɵɵFactoryTarget.Component });
137
+ static ɵcmp = i0.ɵɵngDeclareComponent({ minVersion: "17.0.0", version: "20.3.19", type: ListItemComponent, isStandalone: true, selector: "c2g-list-item", inputs: { group: { classPropertyName: "group", publicName: "group", isSignal: true, isRequired: false, transformFunction: null }, active: { classPropertyName: "active", publicName: "active", isSignal: true, isRequired: false, transformFunction: null } }, outputs: { selected: "selected", opened: "opened" }, ngImport: i0, template: "<li\n class=\"c2g-list-item\"\n [class.c2g-list-item--active]=\"active()\"\n role=\"button\"\n tabindex=\"0\"\n [attr.aria-label]=\"group()?.name\"\n (click)=\"selected.emit(group())\"\n (keyup.enter)=\"selected.emit(group())\"\n (keydown.space)=\"$event.preventDefault(); selected.emit(group())\"\n>\n <div class=\"c2g-list-item__avatar\">\n <mat-icon>group</mat-icon>\n </div>\n\n <div class=\"c2g-list-item__info\">\n <span class=\"c2g-list-item__name\">{{ group()?.name }}</span>\n @if (group()?.description) {\n <span class=\"c2g-list-item__desc\">{{ group()?.description }}</span>\n }\n </div>\n\n <div class=\"c2g-list-item__end\">\n <span class=\"c2g-list-item__members\">\n <mat-icon>group</mat-icon>\n {{ group()?.memberCount ?? group()?.members?.length ?? 0 }}\n </span>\n <button\n mat-icon-button\n class=\"c2g-list-item__open-btn\"\n [matTooltip]=\"'groups.open' | translate\"\n [attr.aria-label]=\"'groups.open' | translate\"\n (click)=\"$event.stopPropagation(); opened.emit(group())\"\n >\n <mat-icon>arrow_forward</mat-icon>\n </button>\n </div>\n</li>\n", styles: [":host{display:contents}.c2g-list-item{display:flex;align-items:center;gap:var(--spacing-3, 12px);padding:var(--spacing-3, 12px) var(--spacing-4, 16px);background:var(--c2g-glass-bg, rgba(255, 255, 255, .95));border:1px solid rgba(0,0,0,.06);border-radius:12px;cursor:pointer;transition:background .15s,border-color .15s,box-shadow .15s;list-style:none}.c2g-list-item:hover{background:#fff;box-shadow:0 2px 8px #00000014}.c2g-list-item--active{border-color:var(--c2g-primary, #16213e);background:#16213e0a;box-shadow:0 0 0 2px #16213e1f}.c2g-list-item:focus-visible{outline:2px solid var(--c2g-primary, #16213e);outline-offset:2px}.c2g-list-item__avatar{width:40px;height:40px;border-radius:50%;background:var(--c2g-primary, #16213e);display:flex;align-items:center;justify-content:center;flex-shrink:0;color:#fff}.c2g-list-item__avatar mat-icon{font-size:20px;width:20px;height:20px}.c2g-list-item__info{flex:1;min-width:0;display:flex;flex-direction:column;gap:2px}.c2g-list-item__name{font-weight:600;font-size:14px;color:var(--c2g-text-primary, #1a1a2e);white-space:nowrap;overflow:hidden;text-overflow:ellipsis}.c2g-list-item__desc{font-size:12px;color:var(--c2g-text-muted, #6b5e52);white-space:nowrap;overflow:hidden;text-overflow:ellipsis}.c2g-list-item__end{display:flex;align-items:center;gap:var(--spacing-2, 8px);flex-shrink:0}.c2g-list-item__members{display:flex;align-items:center;gap:4px;font-size:13px;font-weight:500;color:var(--c2g-text-muted, #6b5e52);white-space:nowrap}.c2g-list-item__members mat-icon{font-size:16px;width:16px;height:16px}.c2g-list-item__open-btn{color:var(--c2g-text-muted, #6b5e52);transition:color .15s}.c2g-list-item__open-btn:hover{color:var(--c2g-primary, #16213e)}\n"], dependencies: [{ kind: "ngmodule", type: MatButtonModule }, { kind: "component", type: i1$2.MatIconButton, selector: "button[mat-icon-button], a[mat-icon-button], button[matIconButton], a[matIconButton]", exportAs: ["matButton", "matAnchor"] }, { kind: "ngmodule", type: MatIconModule }, { kind: "component", type: i1$1.MatIcon, selector: "mat-icon", inputs: ["color", "inline", "svgIcon", "fontSet", "fontIcon"], exportAs: ["matIcon"] }, { kind: "ngmodule", type: MatTooltipModule }, { kind: "directive", type: i3.MatTooltip, selector: "[matTooltip]", inputs: ["matTooltipPosition", "matTooltipPositionAtOrigin", "matTooltipDisabled", "matTooltipShowDelay", "matTooltipHideDelay", "matTooltipTouchGestures", "matTooltip", "matTooltipClass"], exportAs: ["matTooltip"] }, { kind: "ngmodule", type: TranslateModule }, { kind: "pipe", type: i1.TranslatePipe, name: "translate" }], changeDetection: i0.ChangeDetectionStrategy.OnPush });
138
+ }
139
+ i0.ɵɵngDeclareClassMetadata({ minVersion: "12.0.0", version: "20.3.19", ngImport: i0, type: ListItemComponent, decorators: [{
140
+ type: Component,
141
+ args: [{ selector: 'c2g-list-item', standalone: true, changeDetection: ChangeDetectionStrategy.OnPush, imports: [MatButtonModule, MatIconModule, MatTooltipModule, TranslateModule], template: "<li\n class=\"c2g-list-item\"\n [class.c2g-list-item--active]=\"active()\"\n role=\"button\"\n tabindex=\"0\"\n [attr.aria-label]=\"group()?.name\"\n (click)=\"selected.emit(group())\"\n (keyup.enter)=\"selected.emit(group())\"\n (keydown.space)=\"$event.preventDefault(); selected.emit(group())\"\n>\n <div class=\"c2g-list-item__avatar\">\n <mat-icon>group</mat-icon>\n </div>\n\n <div class=\"c2g-list-item__info\">\n <span class=\"c2g-list-item__name\">{{ group()?.name }}</span>\n @if (group()?.description) {\n <span class=\"c2g-list-item__desc\">{{ group()?.description }}</span>\n }\n </div>\n\n <div class=\"c2g-list-item__end\">\n <span class=\"c2g-list-item__members\">\n <mat-icon>group</mat-icon>\n {{ group()?.memberCount ?? group()?.members?.length ?? 0 }}\n </span>\n <button\n mat-icon-button\n class=\"c2g-list-item__open-btn\"\n [matTooltip]=\"'groups.open' | translate\"\n [attr.aria-label]=\"'groups.open' | translate\"\n (click)=\"$event.stopPropagation(); opened.emit(group())\"\n >\n <mat-icon>arrow_forward</mat-icon>\n </button>\n </div>\n</li>\n", styles: [":host{display:contents}.c2g-list-item{display:flex;align-items:center;gap:var(--spacing-3, 12px);padding:var(--spacing-3, 12px) var(--spacing-4, 16px);background:var(--c2g-glass-bg, rgba(255, 255, 255, .95));border:1px solid rgba(0,0,0,.06);border-radius:12px;cursor:pointer;transition:background .15s,border-color .15s,box-shadow .15s;list-style:none}.c2g-list-item:hover{background:#fff;box-shadow:0 2px 8px #00000014}.c2g-list-item--active{border-color:var(--c2g-primary, #16213e);background:#16213e0a;box-shadow:0 0 0 2px #16213e1f}.c2g-list-item:focus-visible{outline:2px solid var(--c2g-primary, #16213e);outline-offset:2px}.c2g-list-item__avatar{width:40px;height:40px;border-radius:50%;background:var(--c2g-primary, #16213e);display:flex;align-items:center;justify-content:center;flex-shrink:0;color:#fff}.c2g-list-item__avatar mat-icon{font-size:20px;width:20px;height:20px}.c2g-list-item__info{flex:1;min-width:0;display:flex;flex-direction:column;gap:2px}.c2g-list-item__name{font-weight:600;font-size:14px;color:var(--c2g-text-primary, #1a1a2e);white-space:nowrap;overflow:hidden;text-overflow:ellipsis}.c2g-list-item__desc{font-size:12px;color:var(--c2g-text-muted, #6b5e52);white-space:nowrap;overflow:hidden;text-overflow:ellipsis}.c2g-list-item__end{display:flex;align-items:center;gap:var(--spacing-2, 8px);flex-shrink:0}.c2g-list-item__members{display:flex;align-items:center;gap:4px;font-size:13px;font-weight:500;color:var(--c2g-text-muted, #6b5e52);white-space:nowrap}.c2g-list-item__members mat-icon{font-size:16px;width:16px;height:16px}.c2g-list-item__open-btn{color:var(--c2g-text-muted, #6b5e52);transition:color .15s}.c2g-list-item__open-btn:hover{color:var(--c2g-primary, #16213e)}\n"] }]
142
+ }], propDecorators: { group: [{ type: i0.Input, args: [{ isSignal: true, alias: "group", required: false }] }], active: [{ type: i0.Input, args: [{ isSignal: true, alias: "active", required: false }] }], selected: [{ type: i0.Output, args: ["selected"] }], opened: [{ type: i0.Output, args: ["opened"] }] } });
143
+
144
+ class StatCardComponent {
145
+ data = input.required(...(ngDevMode ? [{ debugName: "data" }] : []));
146
+ cardBackgroundStyle = computed(() => {
147
+ const background = this.data().background;
148
+ if (!background) {
149
+ return null;
150
+ }
151
+ if (background.type === 'gradient') {
152
+ return { backgroundImage: background.value };
153
+ }
154
+ const imageUrl = background.value.startsWith('url(')
155
+ ? background.value
156
+ : `url('${background.value}')`;
157
+ const overlay = background.overlay ?? 'linear-gradient(rgba(0, 0, 0, 0.34), rgba(0, 0, 0, 0.34))';
158
+ return {
159
+ backgroundImage: `${overlay}, ${imageUrl}`,
160
+ backgroundSize: 'cover',
161
+ backgroundPosition: 'center',
162
+ backgroundRepeat: 'no-repeat',
163
+ };
164
+ }, ...(ngDevMode ? [{ debugName: "cardBackgroundStyle" }] : []));
165
+ static ɵfac = i0.ɵɵngDeclareFactory({ minVersion: "12.0.0", version: "20.3.19", ngImport: i0, type: StatCardComponent, deps: [], target: i0.ɵɵFactoryTarget.Component });
166
+ static ɵcmp = i0.ɵɵngDeclareComponent({ minVersion: "17.0.0", version: "20.3.19", type: StatCardComponent, isStandalone: true, selector: "c2g-stat-card", inputs: { data: { classPropertyName: "data", publicName: "data", isSignal: true, isRequired: true, transformFunction: null } }, ngImport: i0, template: "<div\n class=\"stat-card\"\n [class]=\"'stat-card--' + (data().iconBackgroundTone || 'neutral')\"\n [class.stat-card--disabled]=\"data().disabled\"\n [class.stat-card--custom-bg]=\"!!data().background\"\n [ngStyle]=\"cardBackgroundStyle()\"\n>\n @if (data().lottiePreset) {\n <div class=\"stat-icon-wrapper stat-icon-wrapper--lottie\">\n <c2g-lottie-loader\n [preset]=\"data().lottiePreset!\"\n width=\"28px\"\n height=\"28px\"\n [showLabel]=\"false\"\n label=\"Animation\"\n ></c2g-lottie-loader>\n </div>\n } @else if (data().icon) {\n <div class=\"stat-icon-wrapper\">\n <mat-icon class=\"stat-icon\">{{ data().icon }}</mat-icon>\n </div>\n }\n\n <div class=\"stat-content\">\n <div class=\"stat-value\">{{ data().value }}</div>\n <div class=\"stat-label\">{{ data().label | translate }}</div>\n </div>\n\n @if (data().trend) {\n <div class=\"stat-trend\" [class]=\"'stat-trend--' + data().trend!.direction\">\n <mat-icon class=\"trend-icon\">\n @switch (data().trend!.direction) {\n @case ('up') {\n trending_up\n }\n @case ('down') {\n trending_down\n }\n @case ('neutral') {\n trending_flat\n }\n }\n </mat-icon>\n <span class=\"trend-value\">{{ data().trend!.value }}</span>\n </div>\n }\n</div>\n", styles: [".stat-card{display:flex;align-items:center;gap:var(--c2g-space-4, 1rem);min-height:5rem;padding:var(--c2g-space-5, 1.25rem);border:1px solid var(--c2g-color-border-subtle, #e5dfd7);border-radius:var(--c2g-radius-lg, 12px);background:var(--c2g-color-surface, #ffffff);opacity:1;transition:opacity .2s ease-in-out}.stat-card.stat-card--disabled{opacity:.5;pointer-events:none}.stat-card.stat-card--custom-bg{border-color:color-mix(in srgb,#ffffff 45%,transparent)}.stat-card.stat-card--custom-bg .stat-value,.stat-card.stat-card--custom-bg .stat-label{color:#fff;text-shadow:0 1px 2px rgba(0,0,0,.28)}.stat-card.stat-card--custom-bg .stat-icon-wrapper{background-color:#ffffff2e;border:1px solid rgba(255,255,255,.26);-webkit-backdrop-filter:blur(2px);backdrop-filter:blur(2px)}.stat-card.stat-card--custom-bg .stat-icon{color:#fff}.stat-card.stat-card--custom-bg .stat-trend--up{color:#b9f6ca}.stat-card.stat-card--custom-bg .stat-trend--down{color:#ffccbc}.stat-card.stat-card--custom-bg .stat-trend--neutral{color:#eceff1}.stat-card--primary{border-left:4px solid var(--c2g-color-primary, #ff6b35)}.stat-card--primary .stat-value{color:var(--c2g-color-primary, #ff6b35)}.stat-card--primary .stat-icon-wrapper{background-color:color-mix(in srgb,var(--c2g-color-primary, #ff6b35) 10%,#ffffff)}.stat-card--primary .stat-icon{color:var(--c2g-color-primary, #ff6b35)}.stat-card--secondary{border-left:4px solid var(--c2g-color-secondary, #2c5f5d)}.stat-card--secondary .stat-value{color:var(--c2g-color-secondary, #2c5f5d)}.stat-card--secondary .stat-icon-wrapper{background-color:color-mix(in srgb,var(--c2g-color-secondary, #2c5f5d) 10%,#ffffff)}.stat-card--secondary .stat-icon{color:var(--c2g-color-secondary, #2c5f5d)}.stat-card--neutral{border-left:4px solid var(--c2g-color-border-subtle, #d0c6bb)}.stat-card--neutral .stat-value{color:var(--c2g-color-text-primary, #2f2925)}.stat-card--neutral .stat-icon-wrapper{background-color:var(--c2g-color-surface-subtle, #f7f3ef)}.stat-card--neutral .stat-icon{color:var(--c2g-color-text-secondary, #4a423b)}.stat-icon-wrapper{display:flex;align-items:center;justify-content:center;width:3rem;height:3rem;border-radius:var(--c2g-radius-md, 8px);flex-shrink:0}.stat-icon-wrapper--lottie c2g-lottie-loader{display:inline-flex}.stat-icon{font-size:1.5rem;width:1.5rem;height:1.5rem}.stat-content{display:flex;flex:1;flex-direction:column;gap:var(--c2g-space-1, .25rem)}.stat-value{font-size:var(--c2g-font-size-xl, 1.5rem);font-weight:var(--c2g-font-weight-bold, 700);line-height:1.2}.stat-label{color:var(--c2g-color-text-secondary, #4a423b);font-size:var(--c2g-font-size-sm, .875rem);font-weight:var(--c2g-font-weight-medium, 500)}.stat-trend{display:flex;align-items:center;gap:var(--c2g-space-1, .25rem)}.stat-trend--up{color:var(--c2g-color-success, #2e7d32)}.stat-trend--down{color:var(--c2g-color-danger, #c62828)}.stat-trend--neutral{color:var(--c2g-color-text-muted, #7a6f64)}.trend-icon{font-size:1rem;width:1rem;height:1rem}.trend-value{font-size:var(--c2g-font-size-xs, .75rem);font-weight:var(--c2g-font-weight-medium, 500)}\n"], dependencies: [{ kind: "ngmodule", type: CommonModule }, { kind: "directive", type: i1$3.NgStyle, selector: "[ngStyle]", inputs: ["ngStyle"] }, { kind: "component", type: MatIcon, selector: "mat-icon", inputs: ["color", "inline", "svgIcon", "fontSet", "fontIcon"], exportAs: ["matIcon"] }, { kind: "ngmodule", type: TranslateModule }, { kind: "component", type: LottieLoaderComponent, selector: "c2g-lottie-loader", inputs: ["preset", "presetMode", "animationPath", "animationData", "loop", "autoplay", "width", "height", "label", "showLabel"] }, { kind: "pipe", type: i1.TranslatePipe, name: "translate" }], changeDetection: i0.ChangeDetectionStrategy.OnPush });
167
+ }
168
+ i0.ɵɵngDeclareClassMetadata({ minVersion: "12.0.0", version: "20.3.19", ngImport: i0, type: StatCardComponent, decorators: [{
169
+ type: Component,
170
+ args: [{ selector: 'c2g-stat-card', standalone: true, imports: [CommonModule, MatIcon, TranslateModule, LottieLoaderComponent], changeDetection: ChangeDetectionStrategy.OnPush, template: "<div\n class=\"stat-card\"\n [class]=\"'stat-card--' + (data().iconBackgroundTone || 'neutral')\"\n [class.stat-card--disabled]=\"data().disabled\"\n [class.stat-card--custom-bg]=\"!!data().background\"\n [ngStyle]=\"cardBackgroundStyle()\"\n>\n @if (data().lottiePreset) {\n <div class=\"stat-icon-wrapper stat-icon-wrapper--lottie\">\n <c2g-lottie-loader\n [preset]=\"data().lottiePreset!\"\n width=\"28px\"\n height=\"28px\"\n [showLabel]=\"false\"\n label=\"Animation\"\n ></c2g-lottie-loader>\n </div>\n } @else if (data().icon) {\n <div class=\"stat-icon-wrapper\">\n <mat-icon class=\"stat-icon\">{{ data().icon }}</mat-icon>\n </div>\n }\n\n <div class=\"stat-content\">\n <div class=\"stat-value\">{{ data().value }}</div>\n <div class=\"stat-label\">{{ data().label | translate }}</div>\n </div>\n\n @if (data().trend) {\n <div class=\"stat-trend\" [class]=\"'stat-trend--' + data().trend!.direction\">\n <mat-icon class=\"trend-icon\">\n @switch (data().trend!.direction) {\n @case ('up') {\n trending_up\n }\n @case ('down') {\n trending_down\n }\n @case ('neutral') {\n trending_flat\n }\n }\n </mat-icon>\n <span class=\"trend-value\">{{ data().trend!.value }}</span>\n </div>\n }\n</div>\n", styles: [".stat-card{display:flex;align-items:center;gap:var(--c2g-space-4, 1rem);min-height:5rem;padding:var(--c2g-space-5, 1.25rem);border:1px solid var(--c2g-color-border-subtle, #e5dfd7);border-radius:var(--c2g-radius-lg, 12px);background:var(--c2g-color-surface, #ffffff);opacity:1;transition:opacity .2s ease-in-out}.stat-card.stat-card--disabled{opacity:.5;pointer-events:none}.stat-card.stat-card--custom-bg{border-color:color-mix(in srgb,#ffffff 45%,transparent)}.stat-card.stat-card--custom-bg .stat-value,.stat-card.stat-card--custom-bg .stat-label{color:#fff;text-shadow:0 1px 2px rgba(0,0,0,.28)}.stat-card.stat-card--custom-bg .stat-icon-wrapper{background-color:#ffffff2e;border:1px solid rgba(255,255,255,.26);-webkit-backdrop-filter:blur(2px);backdrop-filter:blur(2px)}.stat-card.stat-card--custom-bg .stat-icon{color:#fff}.stat-card.stat-card--custom-bg .stat-trend--up{color:#b9f6ca}.stat-card.stat-card--custom-bg .stat-trend--down{color:#ffccbc}.stat-card.stat-card--custom-bg .stat-trend--neutral{color:#eceff1}.stat-card--primary{border-left:4px solid var(--c2g-color-primary, #ff6b35)}.stat-card--primary .stat-value{color:var(--c2g-color-primary, #ff6b35)}.stat-card--primary .stat-icon-wrapper{background-color:color-mix(in srgb,var(--c2g-color-primary, #ff6b35) 10%,#ffffff)}.stat-card--primary .stat-icon{color:var(--c2g-color-primary, #ff6b35)}.stat-card--secondary{border-left:4px solid var(--c2g-color-secondary, #2c5f5d)}.stat-card--secondary .stat-value{color:var(--c2g-color-secondary, #2c5f5d)}.stat-card--secondary .stat-icon-wrapper{background-color:color-mix(in srgb,var(--c2g-color-secondary, #2c5f5d) 10%,#ffffff)}.stat-card--secondary .stat-icon{color:var(--c2g-color-secondary, #2c5f5d)}.stat-card--neutral{border-left:4px solid var(--c2g-color-border-subtle, #d0c6bb)}.stat-card--neutral .stat-value{color:var(--c2g-color-text-primary, #2f2925)}.stat-card--neutral .stat-icon-wrapper{background-color:var(--c2g-color-surface-subtle, #f7f3ef)}.stat-card--neutral .stat-icon{color:var(--c2g-color-text-secondary, #4a423b)}.stat-icon-wrapper{display:flex;align-items:center;justify-content:center;width:3rem;height:3rem;border-radius:var(--c2g-radius-md, 8px);flex-shrink:0}.stat-icon-wrapper--lottie c2g-lottie-loader{display:inline-flex}.stat-icon{font-size:1.5rem;width:1.5rem;height:1.5rem}.stat-content{display:flex;flex:1;flex-direction:column;gap:var(--c2g-space-1, .25rem)}.stat-value{font-size:var(--c2g-font-size-xl, 1.5rem);font-weight:var(--c2g-font-weight-bold, 700);line-height:1.2}.stat-label{color:var(--c2g-color-text-secondary, #4a423b);font-size:var(--c2g-font-size-sm, .875rem);font-weight:var(--c2g-font-weight-medium, 500)}.stat-trend{display:flex;align-items:center;gap:var(--c2g-space-1, .25rem)}.stat-trend--up{color:var(--c2g-color-success, #2e7d32)}.stat-trend--down{color:var(--c2g-color-danger, #c62828)}.stat-trend--neutral{color:var(--c2g-color-text-muted, #7a6f64)}.trend-icon{font-size:1rem;width:1rem;height:1rem}.trend-value{font-size:var(--c2g-font-size-xs, .75rem);font-weight:var(--c2g-font-weight-medium, 500)}\n"] }]
171
+ }], propDecorators: { data: [{ type: i0.Input, args: [{ isSignal: true, alias: "data", required: true }] }] } });
172
+
173
+ class ActionCardComponent {
174
+ data = input.required(...(ngDevMode ? [{ debugName: "data" }] : []));
175
+ clickable = input(true, ...(ngDevMode ? [{ debugName: "clickable" }] : []));
176
+ variant = input('icon-left', ...(ngDevMode ? [{ debugName: "variant" }] : []));
177
+ cardClicked = output();
178
+ effectiveText = computed(() => this.data().text ?? this.data().description ?? '', ...(ngDevMode ? [{ debugName: "effectiveText" }] : []));
179
+ supportingDescription = computed(() => {
180
+ const d = this.data();
181
+ return d.text ? (d.description ?? '') : '';
182
+ }, ...(ngDevMode ? [{ debugName: "supportingDescription" }] : []));
183
+ isInteractive = computed(() => this.clickable() && !this.data().disabled, ...(ngDevMode ? [{ debugName: "isInteractive" }] : []));
184
+ iconToneClass = computed(() => this.data().iconBackgroundTone ?? 'neutral', ...(ngDevMode ? [{ debugName: "iconToneClass" }] : []));
185
+ onCardClick() {
186
+ if (this.isInteractive()) {
187
+ this.cardClicked.emit();
188
+ }
189
+ }
190
+ onKeyDown(event) {
191
+ if (!this.isInteractive()) {
192
+ return;
193
+ }
194
+ if (event.key === 'Enter' || event.key === ' ') {
195
+ event.preventDefault();
196
+ this.cardClicked.emit();
197
+ }
198
+ }
199
+ static ɵfac = i0.ɵɵngDeclareFactory({ minVersion: "12.0.0", version: "20.3.19", ngImport: i0, type: ActionCardComponent, deps: [], target: i0.ɵɵFactoryTarget.Component });
200
+ static ɵcmp = i0.ɵɵngDeclareComponent({ minVersion: "17.0.0", version: "20.3.19", type: ActionCardComponent, isStandalone: true, selector: "c2g-action-card", inputs: { data: { classPropertyName: "data", publicName: "data", isSignal: true, isRequired: true, transformFunction: null }, clickable: { classPropertyName: "clickable", publicName: "clickable", isSignal: true, isRequired: false, transformFunction: null }, variant: { classPropertyName: "variant", publicName: "variant", isSignal: true, isRequired: false, transformFunction: null } }, outputs: { cardClicked: "cardClicked" }, ngImport: i0, template: "<mat-card\n class=\"action-card\"\n [class.clickable]=\"isInteractive()\"\n [class.disabled]=\"data().disabled\"\n [class.variant-icon-left]=\"variant() === 'icon-left'\"\n [class.variant-hero-top]=\"variant() === 'hero-top'\"\n [class.variant-icon-detail]=\"variant() === 'icon-detail'\"\n (click)=\"onCardClick()\"\n (keydown)=\"onKeyDown($event)\"\n [attr.role]=\"isInteractive() ? 'button' : null\"\n [attr.tabindex]=\"isInteractive() ? '0' : null\">\n\n @if (variant() === 'hero-top') {\n <div class=\"hero-top-header\" [class.has-image]=\"data().image || data().lottiePreset\">\n @if (data().lottiePreset) {\n <div class=\"hero-image hero-image--lottie\">\n <c2g-lottie-loader\n [preset]=\"data().lottiePreset!\"\n [showLabel]=\"false\"\n width=\"100%\"\n height=\"100%\"\n ></c2g-lottie-loader>\n </div>\n } @else if (data().image) {\n <div class=\"hero-image\">\n <img [src]=\"data().image\" [alt]=\"data().title | translate\" />\n </div>\n }\n\n <div class=\"hero-top-title-wrap\">\n <h3 class=\"hero-top-title\">{{ data().title | translate }}</h3>\n @if (effectiveText()) {\n <p class=\"hero-top-description\">{{ effectiveText() | translate }}</p>\n }\n </div>\n </div>\n } @else if (variant() === 'icon-detail') {\n <div class=\"icon-detail-layout\">\n @if (data().icon) {\n <div class=\"icon-chip\" [ngClass]=\"iconToneClass()\">\n <mat-icon class=\"hero-icon\">{{ data().icon }}</mat-icon>\n </div>\n }\n <div class=\"icon-detail-body\">\n <h3 class=\"hero-title\">{{ data().title | translate }}</h3>\n @if (effectiveText()) {\n <p class=\"hero-description\">{{ effectiveText() | translate }}</p>\n }\n <div class=\"icon-detail-cta\" (click)=\"$event.stopPropagation()\">\n @if (data().ctaLabel) {\n <c2g-button variant=\"ghost\" size=\"sm\">{{ data().ctaLabel! | translate }}</c2g-button>\n }\n <ng-content select=\"[ctas]\"></ng-content>\n </div>\n </div>\n </div>\n } @else {\n <div class=\"icon-left-header\">\n @if (data().icon) {\n <div class=\"icon-chip\" [ngClass]=\"iconToneClass()\">\n <mat-icon class=\"hero-icon\">{{ data().icon }}</mat-icon>\n </div>\n }\n\n <div class=\"icon-left-title-wrap\">\n <h3 class=\"hero-title\">{{ data().title | translate }}</h3>\n </div>\n </div>\n }\n\n @if (variant() !== 'icon-detail') {\n <div class=\"content-section\">\n @if (variant() !== 'hero-top' && effectiveText()) {\n <p class=\"hero-description\">{{ effectiveText() | translate }}</p>\n }\n\n @if (supportingDescription()) {\n <p class=\"hero-description supporting\">{{ supportingDescription() | translate }}</p>\n }\n\n <ng-content></ng-content>\n </div>\n }\n\n @if (variant() !== 'icon-detail') {\n <div class=\"cta-section\" (click)=\"$event.stopPropagation()\">\n @if (data().ctaLabel) {\n <c2g-button variant=\"ghost\" size=\"sm\">{{ data().ctaLabel! | translate }}</c2g-button>\n }\n\n <ng-content select=\"[ctas]\"></ng-content>\n </div>\n }\n\n</mat-card>\n", styles: [".action-card{border-radius:var(--c2g-radius-lg);overflow:hidden;transition:all var(--c2g-transition-fast);box-shadow:var(--c2g-shadow-sm);background-color:var(--c2g-neutral-50);border:1px solid var(--c2g-neutral-300);display:flex;flex-direction:column;min-height:100%}.action-card.clickable{cursor:pointer}.action-card.clickable:hover{transform:translateY(-2px);box-shadow:var(--c2g-shadow-md)}.action-card.disabled{opacity:.6;cursor:not-allowed}.action-card.disabled:hover{transform:none;box-shadow:var(--c2g-shadow-sm)}.action-card.variant-hero-top .hero-top-header{min-height:132px}.icon-left-header{display:flex;align-items:center;gap:var(--c2g-space-md);padding:var(--c2g-space-lg)}.icon-detail-layout{display:flex;flex-direction:row;align-items:flex-start;gap:var(--c2g-space-md);padding:var(--c2g-space-lg);flex:1}.icon-detail-body{display:flex;flex-direction:column;flex:1;min-width:0}.icon-detail-cta{display:flex;justify-content:flex-end;margin-top:auto;padding-top:var(--c2g-space-sm)}.icon-chip{width:48px;height:48px;border-radius:var(--c2g-radius-md);display:inline-flex;align-items:center;justify-content:center;flex-shrink:0}.icon-chip.primary{background:var(--c2g-primary);color:var(--c2g-neutral-50)}.icon-chip.secondary{background:var(--c2g-secondary);color:var(--c2g-neutral-50)}.icon-chip.neutral{background:var(--c2g-neutral-200);color:var(--c2g-neutral-900)}.hero-icon{display:inline-flex!important;align-items:center;justify-content:center;font-size:24px;width:24px;height:24px;vertical-align:middle;flex-shrink:0}.icon-left-title-wrap{min-width:0}.hero-top-header{position:relative;min-height:120px;display:flex;align-items:flex-end;justify-content:flex-end;padding:var(--c2g-space-lg);background:linear-gradient(135deg,var(--c2g-primary-light) 0%,var(--c2g-secondary-light) 100%)}@media(min-width:768px){.hero-top-header{min-height:140px}}.hero-top-header.has-image .hero-top-title-wrap{background:#1f1c199e;border-radius:var(--c2g-radius-sm);padding:var(--c2g-space-sm) var(--c2g-space-md);z-index:1}.hero-top-header.has-image .hero-top-title{color:var(--c2g-neutral-50)}.hero-top-header.has-image .hero-top-description{color:#fffc}.hero-image{position:absolute;top:0;left:0;width:100%;height:120px;overflow:hidden}.hero-image img{width:100%;height:100%;object-fit:cover}@media(min-width:768px){.hero-image{height:140px}}.hero-top-title{margin:0;font-size:16px;font-weight:600;line-height:1.3;color:var(--c2g-neutral-50)}@media(min-width:768px){.hero-top-title{font-size:18px}}.hero-top-description{margin:2px 0 0;font-size:12px;font-weight:500;line-height:1.3;color:#ffffffbf}.hero-title{margin:0;font-size:16px;font-weight:600;line-height:1.3}@media(min-width:768px){.hero-title{font-size:18px}}.content-section{display:flex;flex-direction:column;gap:var(--c2g-space-sm);flex:1}.content-section:empty{display:none}.content-section:not(:empty){padding:var(--c2g-space-lg)}.cta-section:empty{display:none}.cta-section:not(:empty){padding:var(--c2g-space-sm) var(--c2g-space-lg) var(--c2g-space-lg);display:flex;gap:var(--c2g-space-sm);justify-content:flex-start;align-items:center}.cta-section:not(:empty) button mat-icon{display:inline-flex!important;align-items:center;justify-content:center;line-height:1!important;vertical-align:middle;font-size:20px;width:20px;height:20px}.hero-description{margin:0;font-size:14px;line-height:1.4;opacity:.8;color:var(--c2g-neutral-700)}@media(min-width:768px){.hero-description{font-size:15px}}.hero-description.supporting{color:var(--c2g-neutral-600)}\n"], dependencies: [{ kind: "ngmodule", type: CommonModule }, { kind: "directive", type: i1$3.NgClass, selector: "[ngClass]", inputs: ["class", "ngClass"] }, { kind: "ngmodule", type: TranslateModule }, { kind: "component", type: MatCard, selector: "mat-card", inputs: ["appearance"], exportAs: ["matCard"] }, { kind: "component", type: MatIcon, selector: "mat-icon", inputs: ["color", "inline", "svgIcon", "fontSet", "fontIcon"], exportAs: ["matIcon"] }, { kind: "component", type: ButtonComponent, selector: "c2g-button", inputs: ["variant", "size", "disabled", "loading", "icon", "iconPosition", "iconOnly", "ariaLabel", "loadingAriaLabel", "type"], outputs: ["clicked"] }, { kind: "component", type: LottieLoaderComponent, selector: "c2g-lottie-loader", inputs: ["preset", "presetMode", "animationPath", "animationData", "loop", "autoplay", "width", "height", "label", "showLabel"] }, { kind: "pipe", type: i1.TranslatePipe, name: "translate" }], changeDetection: i0.ChangeDetectionStrategy.OnPush });
201
+ }
202
+ i0.ɵɵngDeclareClassMetadata({ minVersion: "12.0.0", version: "20.3.19", ngImport: i0, type: ActionCardComponent, decorators: [{
203
+ type: Component,
204
+ args: [{ selector: 'c2g-action-card', standalone: true, imports: [
205
+ CommonModule,
206
+ TranslateModule,
207
+ MatCard,
208
+ MatIcon,
209
+ ButtonComponent,
210
+ LottieLoaderComponent
211
+ ], changeDetection: ChangeDetectionStrategy.OnPush, template: "<mat-card\n class=\"action-card\"\n [class.clickable]=\"isInteractive()\"\n [class.disabled]=\"data().disabled\"\n [class.variant-icon-left]=\"variant() === 'icon-left'\"\n [class.variant-hero-top]=\"variant() === 'hero-top'\"\n [class.variant-icon-detail]=\"variant() === 'icon-detail'\"\n (click)=\"onCardClick()\"\n (keydown)=\"onKeyDown($event)\"\n [attr.role]=\"isInteractive() ? 'button' : null\"\n [attr.tabindex]=\"isInteractive() ? '0' : null\">\n\n @if (variant() === 'hero-top') {\n <div class=\"hero-top-header\" [class.has-image]=\"data().image || data().lottiePreset\">\n @if (data().lottiePreset) {\n <div class=\"hero-image hero-image--lottie\">\n <c2g-lottie-loader\n [preset]=\"data().lottiePreset!\"\n [showLabel]=\"false\"\n width=\"100%\"\n height=\"100%\"\n ></c2g-lottie-loader>\n </div>\n } @else if (data().image) {\n <div class=\"hero-image\">\n <img [src]=\"data().image\" [alt]=\"data().title | translate\" />\n </div>\n }\n\n <div class=\"hero-top-title-wrap\">\n <h3 class=\"hero-top-title\">{{ data().title | translate }}</h3>\n @if (effectiveText()) {\n <p class=\"hero-top-description\">{{ effectiveText() | translate }}</p>\n }\n </div>\n </div>\n } @else if (variant() === 'icon-detail') {\n <div class=\"icon-detail-layout\">\n @if (data().icon) {\n <div class=\"icon-chip\" [ngClass]=\"iconToneClass()\">\n <mat-icon class=\"hero-icon\">{{ data().icon }}</mat-icon>\n </div>\n }\n <div class=\"icon-detail-body\">\n <h3 class=\"hero-title\">{{ data().title | translate }}</h3>\n @if (effectiveText()) {\n <p class=\"hero-description\">{{ effectiveText() | translate }}</p>\n }\n <div class=\"icon-detail-cta\" (click)=\"$event.stopPropagation()\">\n @if (data().ctaLabel) {\n <c2g-button variant=\"ghost\" size=\"sm\">{{ data().ctaLabel! | translate }}</c2g-button>\n }\n <ng-content select=\"[ctas]\"></ng-content>\n </div>\n </div>\n </div>\n } @else {\n <div class=\"icon-left-header\">\n @if (data().icon) {\n <div class=\"icon-chip\" [ngClass]=\"iconToneClass()\">\n <mat-icon class=\"hero-icon\">{{ data().icon }}</mat-icon>\n </div>\n }\n\n <div class=\"icon-left-title-wrap\">\n <h3 class=\"hero-title\">{{ data().title | translate }}</h3>\n </div>\n </div>\n }\n\n @if (variant() !== 'icon-detail') {\n <div class=\"content-section\">\n @if (variant() !== 'hero-top' && effectiveText()) {\n <p class=\"hero-description\">{{ effectiveText() | translate }}</p>\n }\n\n @if (supportingDescription()) {\n <p class=\"hero-description supporting\">{{ supportingDescription() | translate }}</p>\n }\n\n <ng-content></ng-content>\n </div>\n }\n\n @if (variant() !== 'icon-detail') {\n <div class=\"cta-section\" (click)=\"$event.stopPropagation()\">\n @if (data().ctaLabel) {\n <c2g-button variant=\"ghost\" size=\"sm\">{{ data().ctaLabel! | translate }}</c2g-button>\n }\n\n <ng-content select=\"[ctas]\"></ng-content>\n </div>\n }\n\n</mat-card>\n", styles: [".action-card{border-radius:var(--c2g-radius-lg);overflow:hidden;transition:all var(--c2g-transition-fast);box-shadow:var(--c2g-shadow-sm);background-color:var(--c2g-neutral-50);border:1px solid var(--c2g-neutral-300);display:flex;flex-direction:column;min-height:100%}.action-card.clickable{cursor:pointer}.action-card.clickable:hover{transform:translateY(-2px);box-shadow:var(--c2g-shadow-md)}.action-card.disabled{opacity:.6;cursor:not-allowed}.action-card.disabled:hover{transform:none;box-shadow:var(--c2g-shadow-sm)}.action-card.variant-hero-top .hero-top-header{min-height:132px}.icon-left-header{display:flex;align-items:center;gap:var(--c2g-space-md);padding:var(--c2g-space-lg)}.icon-detail-layout{display:flex;flex-direction:row;align-items:flex-start;gap:var(--c2g-space-md);padding:var(--c2g-space-lg);flex:1}.icon-detail-body{display:flex;flex-direction:column;flex:1;min-width:0}.icon-detail-cta{display:flex;justify-content:flex-end;margin-top:auto;padding-top:var(--c2g-space-sm)}.icon-chip{width:48px;height:48px;border-radius:var(--c2g-radius-md);display:inline-flex;align-items:center;justify-content:center;flex-shrink:0}.icon-chip.primary{background:var(--c2g-primary);color:var(--c2g-neutral-50)}.icon-chip.secondary{background:var(--c2g-secondary);color:var(--c2g-neutral-50)}.icon-chip.neutral{background:var(--c2g-neutral-200);color:var(--c2g-neutral-900)}.hero-icon{display:inline-flex!important;align-items:center;justify-content:center;font-size:24px;width:24px;height:24px;vertical-align:middle;flex-shrink:0}.icon-left-title-wrap{min-width:0}.hero-top-header{position:relative;min-height:120px;display:flex;align-items:flex-end;justify-content:flex-end;padding:var(--c2g-space-lg);background:linear-gradient(135deg,var(--c2g-primary-light) 0%,var(--c2g-secondary-light) 100%)}@media(min-width:768px){.hero-top-header{min-height:140px}}.hero-top-header.has-image .hero-top-title-wrap{background:#1f1c199e;border-radius:var(--c2g-radius-sm);padding:var(--c2g-space-sm) var(--c2g-space-md);z-index:1}.hero-top-header.has-image .hero-top-title{color:var(--c2g-neutral-50)}.hero-top-header.has-image .hero-top-description{color:#fffc}.hero-image{position:absolute;top:0;left:0;width:100%;height:120px;overflow:hidden}.hero-image img{width:100%;height:100%;object-fit:cover}@media(min-width:768px){.hero-image{height:140px}}.hero-top-title{margin:0;font-size:16px;font-weight:600;line-height:1.3;color:var(--c2g-neutral-50)}@media(min-width:768px){.hero-top-title{font-size:18px}}.hero-top-description{margin:2px 0 0;font-size:12px;font-weight:500;line-height:1.3;color:#ffffffbf}.hero-title{margin:0;font-size:16px;font-weight:600;line-height:1.3}@media(min-width:768px){.hero-title{font-size:18px}}.content-section{display:flex;flex-direction:column;gap:var(--c2g-space-sm);flex:1}.content-section:empty{display:none}.content-section:not(:empty){padding:var(--c2g-space-lg)}.cta-section:empty{display:none}.cta-section:not(:empty){padding:var(--c2g-space-sm) var(--c2g-space-lg) var(--c2g-space-lg);display:flex;gap:var(--c2g-space-sm);justify-content:flex-start;align-items:center}.cta-section:not(:empty) button mat-icon{display:inline-flex!important;align-items:center;justify-content:center;line-height:1!important;vertical-align:middle;font-size:20px;width:20px;height:20px}.hero-description{margin:0;font-size:14px;line-height:1.4;opacity:.8;color:var(--c2g-neutral-700)}@media(min-width:768px){.hero-description{font-size:15px}}.hero-description.supporting{color:var(--c2g-neutral-600)}\n"] }]
212
+ }], propDecorators: { data: [{ type: i0.Input, args: [{ isSignal: true, alias: "data", required: true }] }], clickable: [{ type: i0.Input, args: [{ isSignal: true, alias: "clickable", required: false }] }], variant: [{ type: i0.Input, args: [{ isSignal: true, alias: "variant", required: false }] }], cardClicked: [{ type: i0.Output, args: ["cardClicked"] }] } });
213
+
214
+ class ViewToggleComponent {
215
+ options = input.required(...(ngDevMode ? [{ debugName: "options" }] : []));
216
+ activeValue = input(null, ...(ngDevMode ? [{ debugName: "activeValue" }] : []));
217
+ valueChange = output();
218
+ static ɵfac = i0.ɵɵngDeclareFactory({ minVersion: "12.0.0", version: "20.3.19", ngImport: i0, type: ViewToggleComponent, deps: [], target: i0.ɵɵFactoryTarget.Component });
219
+ static ɵcmp = i0.ɵɵngDeclareComponent({ minVersion: "17.0.0", version: "20.3.19", type: ViewToggleComponent, isStandalone: true, selector: "app-view-toggle", inputs: { options: { classPropertyName: "options", publicName: "options", isSignal: true, isRequired: true, transformFunction: null }, activeValue: { classPropertyName: "activeValue", publicName: "activeValue", isSignal: true, isRequired: false, transformFunction: null } }, outputs: { valueChange: "valueChange" }, ngImport: i0, template: "<div class=\"view-toggle\" role=\"group\">\n @for (option of options(); track option.value) {\n <button\n mat-icon-button\n [class.active]=\"activeValue() === option.value\"\n (click)=\"valueChange.emit(option.value)\"\n [matTooltip]=\"option.label | translate\"\n [attr.aria-label]=\"option.label | translate\"\n [attr.aria-pressed]=\"activeValue() === option.value\"\n >\n <mat-icon>{{ option.icon }}</mat-icon>\n </button>\n }\n</div>\n", styles: [".view-toggle{display:flex;border:1px solid var(--c2g-color-border-subtle, rgba(17, 24, 39, .12));border-radius:var(--c2g-radius-md, .625rem);overflow:hidden;background:var(--c2g-glass-bg, rgba(255, 255, 255, .95))}.view-toggle button{border-radius:0!important;min-width:2.5rem;width:2.5rem;height:2.5rem;padding:0;border-right:1px solid var(--c2g-color-border-soft, rgba(17, 24, 39, .08));display:flex;align-items:center;justify-content:center;transition:background-color var(--c2g-motion-duration-base, .2s) var(--c2g-motion-ease-standard, ease)}.view-toggle button:last-child{border-right:none}.view-toggle button.active{background:color-mix(in srgb,var(--c2g-color-text-primary) 8%,transparent)}.view-toggle button:hover:not(.active){background:color-mix(in srgb,var(--c2g-color-text-primary) 4%,transparent)}.view-toggle button mat-icon{display:flex;align-items:center;justify-content:center;font-size:1.25rem;width:1.25rem;height:1.25rem;line-height:1.25rem}\n"], dependencies: [{ kind: "ngmodule", type: MatIconModule }, { kind: "component", type: i1$1.MatIcon, selector: "mat-icon", inputs: ["color", "inline", "svgIcon", "fontSet", "fontIcon"], exportAs: ["matIcon"] }, { kind: "ngmodule", type: MatButtonModule }, { kind: "component", type: i1$2.MatIconButton, selector: "button[mat-icon-button], a[mat-icon-button], button[matIconButton], a[matIconButton]", exportAs: ["matButton", "matAnchor"] }, { kind: "ngmodule", type: MatTooltipModule }, { kind: "directive", type: i3.MatTooltip, selector: "[matTooltip]", inputs: ["matTooltipPosition", "matTooltipPositionAtOrigin", "matTooltipDisabled", "matTooltipShowDelay", "matTooltipHideDelay", "matTooltipTouchGestures", "matTooltip", "matTooltipClass"], exportAs: ["matTooltip"] }, { kind: "ngmodule", type: TranslateModule }, { kind: "pipe", type: i1.TranslatePipe, name: "translate" }], changeDetection: i0.ChangeDetectionStrategy.OnPush });
220
+ }
221
+ i0.ɵɵngDeclareClassMetadata({ minVersion: "12.0.0", version: "20.3.19", ngImport: i0, type: ViewToggleComponent, decorators: [{
222
+ type: Component,
223
+ args: [{ selector: 'app-view-toggle', standalone: true, changeDetection: ChangeDetectionStrategy.OnPush, imports: [
224
+ MatIconModule,
225
+ MatButtonModule,
226
+ MatTooltipModule,
227
+ TranslateModule
228
+ ], template: "<div class=\"view-toggle\" role=\"group\">\n @for (option of options(); track option.value) {\n <button\n mat-icon-button\n [class.active]=\"activeValue() === option.value\"\n (click)=\"valueChange.emit(option.value)\"\n [matTooltip]=\"option.label | translate\"\n [attr.aria-label]=\"option.label | translate\"\n [attr.aria-pressed]=\"activeValue() === option.value\"\n >\n <mat-icon>{{ option.icon }}</mat-icon>\n </button>\n }\n</div>\n", styles: [".view-toggle{display:flex;border:1px solid var(--c2g-color-border-subtle, rgba(17, 24, 39, .12));border-radius:var(--c2g-radius-md, .625rem);overflow:hidden;background:var(--c2g-glass-bg, rgba(255, 255, 255, .95))}.view-toggle button{border-radius:0!important;min-width:2.5rem;width:2.5rem;height:2.5rem;padding:0;border-right:1px solid var(--c2g-color-border-soft, rgba(17, 24, 39, .08));display:flex;align-items:center;justify-content:center;transition:background-color var(--c2g-motion-duration-base, .2s) var(--c2g-motion-ease-standard, ease)}.view-toggle button:last-child{border-right:none}.view-toggle button.active{background:color-mix(in srgb,var(--c2g-color-text-primary) 8%,transparent)}.view-toggle button:hover:not(.active){background:color-mix(in srgb,var(--c2g-color-text-primary) 4%,transparent)}.view-toggle button mat-icon{display:flex;align-items:center;justify-content:center;font-size:1.25rem;width:1.25rem;height:1.25rem;line-height:1.25rem}\n"] }]
229
+ }], propDecorators: { options: [{ type: i0.Input, args: [{ isSignal: true, alias: "options", required: true }] }], activeValue: [{ type: i0.Input, args: [{ isSignal: true, alias: "activeValue", required: false }] }], valueChange: [{ type: i0.Output, args: ["valueChange"] }] } });
230
+
231
+ class SegmentedToggleComponent {
232
+ options = input([], ...(ngDevMode ? [{ debugName: "options" }] : []));
233
+ disabled = input(false, ...(ngDevMode ? [{ debugName: "disabled" }] : []));
234
+ ariaLabel = input('Auswahl', ...(ngDevMode ? [{ debugName: "ariaLabel" }] : []));
235
+ iconOnly = input(false, ...(ngDevMode ? [{ debugName: "iconOnly" }] : []));
236
+ valueChange = output();
237
+ value = signal(null, ...(ngDevMode ? [{ debugName: "value" }] : []));
238
+ cvaDisabled = signal(false, ...(ngDevMode ? [{ debugName: "cvaDisabled" }] : []));
239
+ isDisabled = computed(() => this.disabled() || this.cvaDisabled(), ...(ngDevMode ? [{ debugName: "isDisabled" }] : []));
240
+ onChange = () => { };
241
+ onTouched = () => { };
242
+ writeValue(value) {
243
+ this.value.set(value);
244
+ }
245
+ registerOnChange(fn) {
246
+ this.onChange = fn;
247
+ }
248
+ registerOnTouched(fn) {
249
+ this.onTouched = fn;
250
+ }
251
+ setDisabledState(isDisabled) {
252
+ this.cvaDisabled.set(isDisabled);
253
+ }
254
+ tabIndexFor(option) {
255
+ if (this.value() === option) {
256
+ return 0;
257
+ }
258
+ if (this.value() === null && this.options()[0]?.value === option) {
259
+ return 0;
260
+ }
261
+ return -1;
262
+ }
263
+ select(next) {
264
+ if (this.isDisabled()) {
265
+ return;
266
+ }
267
+ this.value.set(next);
268
+ this.onChange(next);
269
+ this.valueChange.emit(next);
270
+ this.onTouched();
271
+ }
272
+ onKeydown(event, index) {
273
+ if (event.key !== 'ArrowRight' &&
274
+ event.key !== 'ArrowLeft' &&
275
+ event.key !== 'ArrowUp' &&
276
+ event.key !== 'ArrowDown' &&
277
+ event.key !== 'Home' &&
278
+ event.key !== 'End') {
279
+ return;
280
+ }
281
+ event.preventDefault();
282
+ const enabled = this.options().filter((option) => !option.disabled);
283
+ if (enabled.length === 0) {
284
+ return;
285
+ }
286
+ if (event.key === 'Home') {
287
+ const next = enabled[0].value;
288
+ this.select(next);
289
+ this.focusValue(next, event.currentTarget);
290
+ return;
291
+ }
292
+ if (event.key === 'End') {
293
+ const next = enabled[enabled.length - 1].value;
294
+ this.select(next);
295
+ this.focusValue(next, event.currentTarget);
296
+ return;
297
+ }
298
+ const selectedValue = this.value();
299
+ const fallbackValue = this.options()[index]?.value ?? null;
300
+ const baseValue = selectedValue ?? fallbackValue;
301
+ const currentEnabledIndex = enabled.findIndex((option) => option.value === baseValue);
302
+ const start = currentEnabledIndex >= 0 ? currentEnabledIndex : 0;
303
+ const delta = event.key === 'ArrowRight' || event.key === 'ArrowDown' ? 1 : -1;
304
+ const nextIndex = (start + delta + enabled.length) % enabled.length;
305
+ const next = enabled[nextIndex].value;
306
+ this.select(next);
307
+ this.focusValue(next, event.currentTarget);
308
+ }
309
+ focusValue(next, eventTarget) {
310
+ const trigger = eventTarget instanceof HTMLElement ? eventTarget : null;
311
+ const root = trigger?.closest('.c2g-segmented');
312
+ const allButtons = root?.querySelectorAll('button[role="radio"]');
313
+ if (!allButtons) {
314
+ return;
315
+ }
316
+ const optionIndex = this.options().findIndex((option) => option.value === next);
317
+ if (optionIndex >= 0) {
318
+ allButtons[optionIndex]?.focus();
319
+ }
320
+ }
321
+ static ɵfac = i0.ɵɵngDeclareFactory({ minVersion: "12.0.0", version: "20.3.19", ngImport: i0, type: SegmentedToggleComponent, deps: [], target: i0.ɵɵFactoryTarget.Component });
322
+ static ɵcmp = i0.ɵɵngDeclareComponent({ minVersion: "17.0.0", version: "20.3.19", type: SegmentedToggleComponent, isStandalone: true, selector: "c2g-segmented-toggle", inputs: { options: { classPropertyName: "options", publicName: "options", isSignal: true, isRequired: false, transformFunction: null }, disabled: { classPropertyName: "disabled", publicName: "disabled", isSignal: true, isRequired: false, transformFunction: null }, ariaLabel: { classPropertyName: "ariaLabel", publicName: "ariaLabel", isSignal: true, isRequired: false, transformFunction: null }, iconOnly: { classPropertyName: "iconOnly", publicName: "iconOnly", isSignal: true, isRequired: false, transformFunction: null } }, outputs: { valueChange: "valueChange" }, providers: [
323
+ {
324
+ provide: NG_VALUE_ACCESSOR,
325
+ useExisting: forwardRef(() => SegmentedToggleComponent),
326
+ multi: true,
327
+ },
328
+ ], ngImport: i0, template: `
329
+ <div class="c2g-segmented" role="radiogroup" [attr.aria-label]="ariaLabel()">
330
+ @for (option of options(); track option.value; let index = $index) {
331
+ <button
332
+ type="button"
333
+ role="radio"
334
+ class="c2g-segmented__item"
335
+ [class.c2g-segmented__item--active]="value() === option.value"
336
+ [attr.aria-checked]="value() === option.value ? 'true' : 'false'"
337
+ [disabled]="isDisabled() || !!option.disabled"
338
+ [attr.tabindex]="tabIndexFor(option.value)"
339
+ (click)="select(option.value)"
340
+ (keydown)="onKeydown($event, index)"
341
+ >
342
+ @if (option.icon || option.iconFontIcon) {
343
+ <mat-icon
344
+ class="c2g-segmented__icon"
345
+ [fontSet]="option.iconFontSet || ''"
346
+ [fontIcon]="option.iconFontIcon || ''"
347
+ [attr.aria-label]="option.iconAriaLabel || null"
348
+ [attr.aria-hidden]="option.iconAriaLabel ? null : 'true'"
349
+ >
350
+ {{ option.icon || '' }}
351
+ </mat-icon>
352
+ }
353
+ <span [class.c2g-segmented__sr-only]="iconOnly()">{{ option.label }}</span>
354
+ </button>
355
+ }
356
+ </div>
357
+ `, isInline: true, styles: [".c2g-segmented{display:inline-flex;align-items:center;border:1px solid var(--c2g-color-border-subtle, rgba(74, 66, 59, .18));border-radius:var(--c2g-radius-md, .625rem);padding:var(--c2g-space-1, .25rem);background:var(--c2g-color-surface, #ffffff);gap:var(--c2g-space-1, .25rem);font-family:var(--c2g-font-family-base, \"Quicksand\", \"Segoe UI\", sans-serif)}.c2g-segmented__item{border:none;background:transparent;border-radius:var(--c2g-radius-sm, .375rem);padding:var(--c2g-space-2, .5rem) var(--c2g-space-3, .75rem);display:inline-flex;align-items:center;gap:var(--c2g-space-2, .5rem);font-size:var(--c2g-font-size-sm, .875rem);color:var(--c2g-color-text-secondary, #4a423b);cursor:pointer;transition:all var(--c2g-motion-duration-fast, .12s) var(--c2g-motion-ease-standard, ease)}.c2g-segmented__icon{display:inline-flex;align-items:center;justify-content:center;width:1rem;height:1rem;font-size:.875rem;line-height:1}.c2g-segmented__sr-only{position:absolute;width:1px;height:1px;padding:0;margin:-1px;overflow:hidden;clip:rect(0,0,0,0);white-space:nowrap;border:0}.c2g-segmented__item--active{background:var(--c2g-color-primary, #ff6b35);color:var(--c2g-color-text-primary, #1a1714);font-weight:var(--c2g-font-weight-semibold, 600)}.c2g-segmented__item:focus-visible{outline:none;box-shadow:0 0 0 3px color-mix(in srgb,var(--c2g-color-focus, #e55623) 24%,transparent)}.c2g-segmented__item:disabled{cursor:not-allowed;opacity:.5}\n"], dependencies: [{ kind: "ngmodule", type: MatIconModule }, { kind: "component", type: i1$1.MatIcon, selector: "mat-icon", inputs: ["color", "inline", "svgIcon", "fontSet", "fontIcon"], exportAs: ["matIcon"] }], changeDetection: i0.ChangeDetectionStrategy.OnPush });
358
+ }
359
+ i0.ɵɵngDeclareClassMetadata({ minVersion: "12.0.0", version: "20.3.19", ngImport: i0, type: SegmentedToggleComponent, decorators: [{
360
+ type: Component,
361
+ args: [{ selector: 'c2g-segmented-toggle', standalone: true, imports: [MatIconModule], changeDetection: ChangeDetectionStrategy.OnPush, providers: [
362
+ {
363
+ provide: NG_VALUE_ACCESSOR,
364
+ useExisting: forwardRef(() => SegmentedToggleComponent),
365
+ multi: true,
366
+ },
367
+ ], template: `
368
+ <div class="c2g-segmented" role="radiogroup" [attr.aria-label]="ariaLabel()">
369
+ @for (option of options(); track option.value; let index = $index) {
370
+ <button
371
+ type="button"
372
+ role="radio"
373
+ class="c2g-segmented__item"
374
+ [class.c2g-segmented__item--active]="value() === option.value"
375
+ [attr.aria-checked]="value() === option.value ? 'true' : 'false'"
376
+ [disabled]="isDisabled() || !!option.disabled"
377
+ [attr.tabindex]="tabIndexFor(option.value)"
378
+ (click)="select(option.value)"
379
+ (keydown)="onKeydown($event, index)"
380
+ >
381
+ @if (option.icon || option.iconFontIcon) {
382
+ <mat-icon
383
+ class="c2g-segmented__icon"
384
+ [fontSet]="option.iconFontSet || ''"
385
+ [fontIcon]="option.iconFontIcon || ''"
386
+ [attr.aria-label]="option.iconAriaLabel || null"
387
+ [attr.aria-hidden]="option.iconAriaLabel ? null : 'true'"
388
+ >
389
+ {{ option.icon || '' }}
390
+ </mat-icon>
391
+ }
392
+ <span [class.c2g-segmented__sr-only]="iconOnly()">{{ option.label }}</span>
393
+ </button>
394
+ }
395
+ </div>
396
+ `, styles: [".c2g-segmented{display:inline-flex;align-items:center;border:1px solid var(--c2g-color-border-subtle, rgba(74, 66, 59, .18));border-radius:var(--c2g-radius-md, .625rem);padding:var(--c2g-space-1, .25rem);background:var(--c2g-color-surface, #ffffff);gap:var(--c2g-space-1, .25rem);font-family:var(--c2g-font-family-base, \"Quicksand\", \"Segoe UI\", sans-serif)}.c2g-segmented__item{border:none;background:transparent;border-radius:var(--c2g-radius-sm, .375rem);padding:var(--c2g-space-2, .5rem) var(--c2g-space-3, .75rem);display:inline-flex;align-items:center;gap:var(--c2g-space-2, .5rem);font-size:var(--c2g-font-size-sm, .875rem);color:var(--c2g-color-text-secondary, #4a423b);cursor:pointer;transition:all var(--c2g-motion-duration-fast, .12s) var(--c2g-motion-ease-standard, ease)}.c2g-segmented__icon{display:inline-flex;align-items:center;justify-content:center;width:1rem;height:1rem;font-size:.875rem;line-height:1}.c2g-segmented__sr-only{position:absolute;width:1px;height:1px;padding:0;margin:-1px;overflow:hidden;clip:rect(0,0,0,0);white-space:nowrap;border:0}.c2g-segmented__item--active{background:var(--c2g-color-primary, #ff6b35);color:var(--c2g-color-text-primary, #1a1714);font-weight:var(--c2g-font-weight-semibold, 600)}.c2g-segmented__item:focus-visible{outline:none;box-shadow:0 0 0 3px color-mix(in srgb,var(--c2g-color-focus, #e55623) 24%,transparent)}.c2g-segmented__item:disabled{cursor:not-allowed;opacity:.5}\n"] }]
397
+ }], propDecorators: { options: [{ type: i0.Input, args: [{ isSignal: true, alias: "options", required: false }] }], disabled: [{ type: i0.Input, args: [{ isSignal: true, alias: "disabled", required: false }] }], ariaLabel: [{ type: i0.Input, args: [{ isSignal: true, alias: "ariaLabel", required: false }] }], iconOnly: [{ type: i0.Input, args: [{ isSignal: true, alias: "iconOnly", required: false }] }], valueChange: [{ type: i0.Output, args: ["valueChange"] }] } });
398
+
399
+ class SearchInputComponent {
400
+ searchChange = output();
401
+ onInput(event) {
402
+ const inputEl = event.target;
403
+ this.searchChange.emit(inputEl.value);
404
+ }
405
+ static ɵfac = i0.ɵɵngDeclareFactory({ minVersion: "12.0.0", version: "20.3.19", ngImport: i0, type: SearchInputComponent, deps: [], target: i0.ɵɵFactoryTarget.Component });
406
+ static ɵcmp = i0.ɵɵngDeclareComponent({ minVersion: "14.0.0", version: "20.3.19", type: SearchInputComponent, isStandalone: true, selector: "app-search-input", outputs: { searchChange: "searchChange" }, ngImport: i0, template: "<div class=\"search-input\">\n <mat-icon class=\"search-input__icon\">search</mat-icon>\n <input\n class=\"search-input__field\"\n type=\"text\"\n [placeholder]=\"'equipment.workspace.search' | translate\"\n [attr.aria-label]=\"'equipment.workspace.search' | translate\"\n (input)=\"onInput($event)\"\n />\n</div>\n", styles: [".search-input{display:flex;align-items:center;gap:var(--c2g-space-2, .5rem);background:var(--c2g-glass-bg, rgba(255, 255, 255, .95));border:1px solid var(--c2g-color-border-subtle, rgba(17, 24, 39, .12));border-radius:var(--c2g-radius-lg, .75rem);padding:0 var(--spacing-3, .75rem);height:2.75rem;flex:1;box-shadow:var(--c2g-shadow-sm, 0 1px 2px rgba(15, 23, 42, .08))}.search-input__icon{font-size:1.25rem;width:1.25rem;height:1.25rem;color:var(--c2g-text-muted, #6b7280);flex-shrink:0}.search-input__field{flex:1;border:none;outline:none;background:transparent;font-size:var(--c2g-font-size-sm, .875rem);color:var(--c2g-text-primary, #1f2937)}.search-input__field::placeholder{color:var(--c2g-text-muted, #6b7280)}\n"], dependencies: [{ kind: "ngmodule", type: MatIconModule }, { kind: "component", type: i1$1.MatIcon, selector: "mat-icon", inputs: ["color", "inline", "svgIcon", "fontSet", "fontIcon"], exportAs: ["matIcon"] }, { kind: "ngmodule", type: TranslateModule }, { kind: "pipe", type: i1.TranslatePipe, name: "translate" }], changeDetection: i0.ChangeDetectionStrategy.OnPush });
407
+ }
408
+ i0.ɵɵngDeclareClassMetadata({ minVersion: "12.0.0", version: "20.3.19", ngImport: i0, type: SearchInputComponent, decorators: [{
409
+ type: Component,
410
+ args: [{ selector: 'app-search-input', standalone: true, changeDetection: ChangeDetectionStrategy.OnPush, imports: [
411
+ MatIconModule,
412
+ TranslateModule
413
+ ], template: "<div class=\"search-input\">\n <mat-icon class=\"search-input__icon\">search</mat-icon>\n <input\n class=\"search-input__field\"\n type=\"text\"\n [placeholder]=\"'equipment.workspace.search' | translate\"\n [attr.aria-label]=\"'equipment.workspace.search' | translate\"\n (input)=\"onInput($event)\"\n />\n</div>\n", styles: [".search-input{display:flex;align-items:center;gap:var(--c2g-space-2, .5rem);background:var(--c2g-glass-bg, rgba(255, 255, 255, .95));border:1px solid var(--c2g-color-border-subtle, rgba(17, 24, 39, .12));border-radius:var(--c2g-radius-lg, .75rem);padding:0 var(--spacing-3, .75rem);height:2.75rem;flex:1;box-shadow:var(--c2g-shadow-sm, 0 1px 2px rgba(15, 23, 42, .08))}.search-input__icon{font-size:1.25rem;width:1.25rem;height:1.25rem;color:var(--c2g-text-muted, #6b7280);flex-shrink:0}.search-input__field{flex:1;border:none;outline:none;background:transparent;font-size:var(--c2g-font-size-sm, .875rem);color:var(--c2g-text-primary, #1f2937)}.search-input__field::placeholder{color:var(--c2g-text-muted, #6b7280)}\n"] }]
414
+ }], propDecorators: { searchChange: [{ type: i0.Output, args: ["searchChange"] }] } });
415
+
416
+ class EmptyStateComponent {
417
+ data = input.required(...(ngDevMode ? [{ debugName: "data" }] : []));
418
+ actionClicked = output();
419
+ static ɵfac = i0.ɵɵngDeclareFactory({ minVersion: "12.0.0", version: "20.3.19", ngImport: i0, type: EmptyStateComponent, deps: [], target: i0.ɵɵFactoryTarget.Component });
420
+ static ɵcmp = i0.ɵɵngDeclareComponent({ minVersion: "17.0.0", version: "20.3.19", type: EmptyStateComponent, isStandalone: true, selector: "c2g-empty-state", inputs: { data: { classPropertyName: "data", publicName: "data", isSignal: true, isRequired: true, transformFunction: null } }, outputs: { actionClicked: "actionClicked" }, ngImport: i0, template: "<div class=\"c2g-empty-state\">\n @if (data().lottiePreset) {\n <div class=\"c2g-empty-state__lottie\">\n <c2g-lottie-loader\n [preset]=\"data().lottiePreset!\"\n width=\"120px\"\n height=\"120px\"\n [showLabel]=\"false\"\n label=\"Illustration\"\n />\n </div>\n } @else if (data().icon) {\n <span class=\"c2g-empty-state__icon\" aria-hidden=\"true\">{{ data().icon }}</span>\n }\n\n <h3 class=\"c2g-empty-state__title\">{{ data().title }}</h3>\n\n @if (data().description) {\n <p class=\"c2g-empty-state__description\">{{ data().description }}</p>\n }\n\n @if (data().actionLabel) {\n <button\n class=\"c2g-empty-state__action\"\n type=\"button\"\n (click)=\"actionClicked.emit()\">\n {{ data().actionLabel }}\n </button>\n }\n\n <ng-content />\n</div>\n", styles: [".c2g-empty-state{display:flex;flex-direction:column;align-items:center;justify-content:center;text-align:center;padding:var(--c2g-spacing-8, 2rem) var(--c2g-spacing-4, 1rem);gap:var(--c2g-spacing-3, .75rem);color:var(--c2g-text-primary, #111827)}.c2g-empty-state__lottie{margin-bottom:var(--c2g-spacing-2, .5rem)}.c2g-empty-state__icon{font-size:3rem;line-height:1;margin-bottom:var(--c2g-spacing-2, .5rem)}.c2g-empty-state__title{margin:0;font-size:var(--c2g-font-size-lg, 1.125rem);font-weight:var(--c2g-font-weight-semibold, 600);color:var(--c2g-text-primary, #111827)}.c2g-empty-state__description{margin:0;font-size:var(--c2g-font-size-sm, .875rem);color:var(--c2g-text-secondary, #6b7280);max-width:32ch;line-height:1.6}.c2g-empty-state__action{margin-top:var(--c2g-spacing-2, .5rem);padding:var(--c2g-spacing-2, .5rem) var(--c2g-spacing-5, 1.25rem);background-color:var(--c2g-color-primary, #ff6b35);color:var(--c2g-color-on-primary, #ffffff);border:none;border-radius:var(--c2g-radius-md, .5rem);font-size:var(--c2g-font-size-sm, .875rem);font-weight:var(--c2g-font-weight-medium, 500);cursor:pointer;transition:opacity .15s ease}.c2g-empty-state__action:hover{opacity:.88}.c2g-empty-state__action:focus-visible{outline:2px solid var(--c2g-focus-ring, #3b82f6);outline-offset:2px}\n"], dependencies: [{ kind: "component", type: LottieLoaderComponent, selector: "c2g-lottie-loader", inputs: ["preset", "presetMode", "animationPath", "animationData", "loop", "autoplay", "width", "height", "label", "showLabel"] }], changeDetection: i0.ChangeDetectionStrategy.OnPush });
421
+ }
422
+ i0.ɵɵngDeclareClassMetadata({ minVersion: "12.0.0", version: "20.3.19", ngImport: i0, type: EmptyStateComponent, decorators: [{
423
+ type: Component,
424
+ args: [{ selector: 'c2g-empty-state', standalone: true, imports: [LottieLoaderComponent], changeDetection: ChangeDetectionStrategy.OnPush, template: "<div class=\"c2g-empty-state\">\n @if (data().lottiePreset) {\n <div class=\"c2g-empty-state__lottie\">\n <c2g-lottie-loader\n [preset]=\"data().lottiePreset!\"\n width=\"120px\"\n height=\"120px\"\n [showLabel]=\"false\"\n label=\"Illustration\"\n />\n </div>\n } @else if (data().icon) {\n <span class=\"c2g-empty-state__icon\" aria-hidden=\"true\">{{ data().icon }}</span>\n }\n\n <h3 class=\"c2g-empty-state__title\">{{ data().title }}</h3>\n\n @if (data().description) {\n <p class=\"c2g-empty-state__description\">{{ data().description }}</p>\n }\n\n @if (data().actionLabel) {\n <button\n class=\"c2g-empty-state__action\"\n type=\"button\"\n (click)=\"actionClicked.emit()\">\n {{ data().actionLabel }}\n </button>\n }\n\n <ng-content />\n</div>\n", styles: [".c2g-empty-state{display:flex;flex-direction:column;align-items:center;justify-content:center;text-align:center;padding:var(--c2g-spacing-8, 2rem) var(--c2g-spacing-4, 1rem);gap:var(--c2g-spacing-3, .75rem);color:var(--c2g-text-primary, #111827)}.c2g-empty-state__lottie{margin-bottom:var(--c2g-spacing-2, .5rem)}.c2g-empty-state__icon{font-size:3rem;line-height:1;margin-bottom:var(--c2g-spacing-2, .5rem)}.c2g-empty-state__title{margin:0;font-size:var(--c2g-font-size-lg, 1.125rem);font-weight:var(--c2g-font-weight-semibold, 600);color:var(--c2g-text-primary, #111827)}.c2g-empty-state__description{margin:0;font-size:var(--c2g-font-size-sm, .875rem);color:var(--c2g-text-secondary, #6b7280);max-width:32ch;line-height:1.6}.c2g-empty-state__action{margin-top:var(--c2g-spacing-2, .5rem);padding:var(--c2g-spacing-2, .5rem) var(--c2g-spacing-5, 1.25rem);background-color:var(--c2g-color-primary, #ff6b35);color:var(--c2g-color-on-primary, #ffffff);border:none;border-radius:var(--c2g-radius-md, .5rem);font-size:var(--c2g-font-size-sm, .875rem);font-weight:var(--c2g-font-weight-medium, 500);cursor:pointer;transition:opacity .15s ease}.c2g-empty-state__action:hover{opacity:.88}.c2g-empty-state__action:focus-visible{outline:2px solid var(--c2g-focus-ring, #3b82f6);outline-offset:2px}\n"] }]
425
+ }], propDecorators: { data: [{ type: i0.Input, args: [{ isSignal: true, alias: "data", required: true }] }], actionClicked: [{ type: i0.Output, args: ["actionClicked"] }] } });
426
+
427
+ const MAX_VISIBLE_PAGES = 5;
428
+ class PaginationComponent {
429
+ state = input.required(...(ngDevMode ? [{ debugName: "state" }] : []));
430
+ ariaLabel = input('Seitennavigation', ...(ngDevMode ? [{ debugName: "ariaLabel" }] : []));
431
+ pageChanged = output();
432
+ currentPage = computed(() => this.state().currentPage, ...(ngDevMode ? [{ debugName: "currentPage" }] : []));
433
+ totalPages = computed(() => this.state().totalPages, ...(ngDevMode ? [{ debugName: "totalPages" }] : []));
434
+ hasPrev = computed(() => this.currentPage() > 1, ...(ngDevMode ? [{ debugName: "hasPrev" }] : []));
435
+ hasNext = computed(() => this.currentPage() < this.totalPages(), ...(ngDevMode ? [{ debugName: "hasNext" }] : []));
436
+ visiblePages = computed(() => {
437
+ const total = this.totalPages();
438
+ const current = this.currentPage();
439
+ const half = Math.floor(MAX_VISIBLE_PAGES / 2);
440
+ let start = Math.max(1, current - half);
441
+ let end = Math.min(total, start + MAX_VISIBLE_PAGES - 1);
442
+ if (end - start < MAX_VISIBLE_PAGES - 1) {
443
+ start = Math.max(1, end - MAX_VISIBLE_PAGES + 1);
444
+ }
445
+ return Array.from({ length: end - start + 1 }, (_, i) => start + i);
446
+ }, ...(ngDevMode ? [{ debugName: "visiblePages" }] : []));
447
+ showStartEllipsis = computed(() => (this.visiblePages()[0] ?? 1) > 1, ...(ngDevMode ? [{ debugName: "showStartEllipsis" }] : []));
448
+ showEndEllipsis = computed(() => (this.visiblePages().at(-1) ?? this.totalPages()) < this.totalPages(), ...(ngDevMode ? [{ debugName: "showEndEllipsis" }] : []));
449
+ go(page) {
450
+ if (page < 1 || page > this.totalPages() || page === this.currentPage())
451
+ return;
452
+ this.pageChanged.emit(page);
453
+ }
454
+ static ɵfac = i0.ɵɵngDeclareFactory({ minVersion: "12.0.0", version: "20.3.19", ngImport: i0, type: PaginationComponent, deps: [], target: i0.ɵɵFactoryTarget.Component });
455
+ static ɵcmp = i0.ɵɵngDeclareComponent({ minVersion: "17.0.0", version: "20.3.19", type: PaginationComponent, isStandalone: true, selector: "c2g-pagination", inputs: { state: { classPropertyName: "state", publicName: "state", isSignal: true, isRequired: true, transformFunction: null }, ariaLabel: { classPropertyName: "ariaLabel", publicName: "ariaLabel", isSignal: true, isRequired: false, transformFunction: null } }, outputs: { pageChanged: "pageChanged" }, ngImport: i0, template: "<nav class=\"c2g-pagination\" [attr.aria-label]=\"ariaLabel()\">\n <button\n class=\"c2g-pagination__btn c2g-pagination__btn--nav\"\n type=\"button\"\n aria-label=\"Vorherige Seite\"\n [disabled]=\"!hasPrev()\"\n (click)=\"go(currentPage() - 1)\">\n \u2039\n </button>\n\n @if (showStartEllipsis()) {\n <button\n class=\"c2g-pagination__btn\"\n type=\"button\"\n [attr.aria-label]=\"'Seite 1'\"\n (click)=\"go(1)\">\n 1\n </button>\n <span class=\"c2g-pagination__ellipsis\" aria-hidden=\"true\">\u2026</span>\n }\n\n @for (page of visiblePages(); track page) {\n <button\n class=\"c2g-pagination__btn\"\n [class.c2g-pagination__btn--active]=\"page === currentPage()\"\n type=\"button\"\n [attr.aria-label]=\"'Seite ' + page\"\n [attr.aria-current]=\"page === currentPage() ? 'page' : null\"\n (click)=\"go(page)\">\n {{ page }}\n </button>\n }\n\n @if (showEndEllipsis()) {\n <span class=\"c2g-pagination__ellipsis\" aria-hidden=\"true\">\u2026</span>\n <button\n class=\"c2g-pagination__btn\"\n type=\"button\"\n [attr.aria-label]=\"'Seite ' + totalPages()\"\n (click)=\"go(totalPages())\">\n {{ totalPages() }}\n </button>\n }\n\n <button\n class=\"c2g-pagination__btn c2g-pagination__btn--nav\"\n type=\"button\"\n aria-label=\"N\u00E4chste Seite\"\n [disabled]=\"!hasNext()\"\n (click)=\"go(currentPage() + 1)\">\n \u203A\n </button>\n</nav>\n", styles: [".c2g-pagination{display:flex;align-items:center;gap:var(--c2g-spacing-1, .25rem);flex-wrap:wrap}.c2g-pagination__btn{display:inline-flex;align-items:center;justify-content:center;min-width:2.25rem;height:2.25rem;padding:0 var(--c2g-spacing-2, .5rem);border:1px solid var(--c2g-border-color, #e5e7eb);border-radius:var(--c2g-radius-md, .5rem);background-color:var(--c2g-surface-bg, #ffffff);color:var(--c2g-text-primary, #111827);font-size:var(--c2g-font-size-sm, .875rem);font-weight:var(--c2g-font-weight-medium, 500);cursor:pointer;transition:background-color .15s ease,border-color .15s ease,color .15s ease;line-height:1}.c2g-pagination__btn:hover:not(:disabled){background-color:var(--c2g-hover-bg, #f3f4f6);border-color:var(--c2g-border-color-strong, #d1d5db)}.c2g-pagination__btn:disabled{opacity:.4;cursor:not-allowed}.c2g-pagination__btn:focus-visible{outline:2px solid var(--c2g-focus-ring, #3b82f6);outline-offset:2px}.c2g-pagination__btn--active{background-color:var(--c2g-color-primary, #ff6b35);border-color:var(--c2g-color-primary, #ff6b35);color:var(--c2g-color-on-primary, #ffffff)}.c2g-pagination__btn--active:hover:not(:disabled){background-color:var(--c2g-color-primary, #ff6b35);opacity:.88}.c2g-pagination__btn--nav{font-size:1.25rem}.c2g-pagination__ellipsis{display:inline-flex;align-items:center;justify-content:center;min-width:2.25rem;height:2.25rem;color:var(--c2g-text-secondary, #6b7280);font-size:var(--c2g-font-size-sm, .875rem);-webkit-user-select:none;user-select:none}\n"], changeDetection: i0.ChangeDetectionStrategy.OnPush });
456
+ }
457
+ i0.ɵɵngDeclareClassMetadata({ minVersion: "12.0.0", version: "20.3.19", ngImport: i0, type: PaginationComponent, decorators: [{
458
+ type: Component,
459
+ args: [{ selector: 'c2g-pagination', standalone: true, imports: [], changeDetection: ChangeDetectionStrategy.OnPush, template: "<nav class=\"c2g-pagination\" [attr.aria-label]=\"ariaLabel()\">\n <button\n class=\"c2g-pagination__btn c2g-pagination__btn--nav\"\n type=\"button\"\n aria-label=\"Vorherige Seite\"\n [disabled]=\"!hasPrev()\"\n (click)=\"go(currentPage() - 1)\">\n \u2039\n </button>\n\n @if (showStartEllipsis()) {\n <button\n class=\"c2g-pagination__btn\"\n type=\"button\"\n [attr.aria-label]=\"'Seite 1'\"\n (click)=\"go(1)\">\n 1\n </button>\n <span class=\"c2g-pagination__ellipsis\" aria-hidden=\"true\">\u2026</span>\n }\n\n @for (page of visiblePages(); track page) {\n <button\n class=\"c2g-pagination__btn\"\n [class.c2g-pagination__btn--active]=\"page === currentPage()\"\n type=\"button\"\n [attr.aria-label]=\"'Seite ' + page\"\n [attr.aria-current]=\"page === currentPage() ? 'page' : null\"\n (click)=\"go(page)\">\n {{ page }}\n </button>\n }\n\n @if (showEndEllipsis()) {\n <span class=\"c2g-pagination__ellipsis\" aria-hidden=\"true\">\u2026</span>\n <button\n class=\"c2g-pagination__btn\"\n type=\"button\"\n [attr.aria-label]=\"'Seite ' + totalPages()\"\n (click)=\"go(totalPages())\">\n {{ totalPages() }}\n </button>\n }\n\n <button\n class=\"c2g-pagination__btn c2g-pagination__btn--nav\"\n type=\"button\"\n aria-label=\"N\u00E4chste Seite\"\n [disabled]=\"!hasNext()\"\n (click)=\"go(currentPage() + 1)\">\n \u203A\n </button>\n</nav>\n", styles: [".c2g-pagination{display:flex;align-items:center;gap:var(--c2g-spacing-1, .25rem);flex-wrap:wrap}.c2g-pagination__btn{display:inline-flex;align-items:center;justify-content:center;min-width:2.25rem;height:2.25rem;padding:0 var(--c2g-spacing-2, .5rem);border:1px solid var(--c2g-border-color, #e5e7eb);border-radius:var(--c2g-radius-md, .5rem);background-color:var(--c2g-surface-bg, #ffffff);color:var(--c2g-text-primary, #111827);font-size:var(--c2g-font-size-sm, .875rem);font-weight:var(--c2g-font-weight-medium, 500);cursor:pointer;transition:background-color .15s ease,border-color .15s ease,color .15s ease;line-height:1}.c2g-pagination__btn:hover:not(:disabled){background-color:var(--c2g-hover-bg, #f3f4f6);border-color:var(--c2g-border-color-strong, #d1d5db)}.c2g-pagination__btn:disabled{opacity:.4;cursor:not-allowed}.c2g-pagination__btn:focus-visible{outline:2px solid var(--c2g-focus-ring, #3b82f6);outline-offset:2px}.c2g-pagination__btn--active{background-color:var(--c2g-color-primary, #ff6b35);border-color:var(--c2g-color-primary, #ff6b35);color:var(--c2g-color-on-primary, #ffffff)}.c2g-pagination__btn--active:hover:not(:disabled){background-color:var(--c2g-color-primary, #ff6b35);opacity:.88}.c2g-pagination__btn--nav{font-size:1.25rem}.c2g-pagination__ellipsis{display:inline-flex;align-items:center;justify-content:center;min-width:2.25rem;height:2.25rem;color:var(--c2g-text-secondary, #6b7280);font-size:var(--c2g-font-size-sm, .875rem);-webkit-user-select:none;user-select:none}\n"] }]
460
+ }], propDecorators: { state: [{ type: i0.Input, args: [{ isSignal: true, alias: "state", required: true }] }], ariaLabel: [{ type: i0.Input, args: [{ isSignal: true, alias: "ariaLabel", required: false }] }], pageChanged: [{ type: i0.Output, args: ["pageChanged"] }] } });
461
+
462
+ class TableComponent {
463
+ rows = input.required(...(ngDevMode ? [{ debugName: "rows" }] : []));
464
+ columns = input.required(...(ngDevMode ? [{ debugName: "columns" }] : []));
465
+ rowHeight = input(48, ...(ngDevMode ? [{ debugName: "rowHeight" }] : []));
466
+ maxHeight = input('480px', ...(ngDevMode ? [{ debugName: "maxHeight" }] : []));
467
+ selectable = input(false, ...(ngDevMode ? [{ debugName: "selectable" }] : []));
468
+ virtualScroll = input(true, ...(ngDevMode ? [{ debugName: "virtualScroll" }] : []));
469
+ sortChanged = output();
470
+ rowSelected = output();
471
+ sortState = signal({ key: '', direction: null }, ...(ngDevMode ? [{ debugName: "sortState" }] : []));
472
+ selectedRow = signal(null, ...(ngDevMode ? [{ debugName: "selectedRow" }] : []));
473
+ sortedRows = computed(() => {
474
+ const { key, direction } = this.sortState();
475
+ const rows = [...this.rows()];
476
+ if (!key || !direction)
477
+ return rows;
478
+ return rows.sort((a, b) => {
479
+ const col = this.columns().find(c => c.key === key);
480
+ const av = col?.valueGetter ? col.valueGetter(a) : a[key];
481
+ const bv = col?.valueGetter ? col.valueGetter(b) : b[key];
482
+ const cmp = av < bv ? -1 : av > bv ? 1 : 0;
483
+ return direction === 'asc' ? cmp : -cmp;
484
+ });
485
+ }, ...(ngDevMode ? [{ debugName: "sortedRows" }] : []));
486
+ getCellValue(row, col) {
487
+ return col.valueGetter ? col.valueGetter(row) : row[col.key] ?? '';
488
+ }
489
+ sort(key) {
490
+ const current = this.sortState();
491
+ const direction = current.key === key
492
+ ? current.direction === 'asc' ? 'desc' : current.direction === 'desc' ? null : 'asc'
493
+ : 'asc';
494
+ const next = { key, direction };
495
+ this.sortState.set(next);
496
+ this.sortChanged.emit(next);
497
+ }
498
+ select(row) {
499
+ if (!this.selectable())
500
+ return;
501
+ this.selectedRow.set(row);
502
+ this.rowSelected.emit(row);
503
+ }
504
+ isSelected(row) {
505
+ return this.selectedRow() === row;
506
+ }
507
+ sortIcon(key) {
508
+ const s = this.sortState();
509
+ if (s.key !== key || !s.direction)
510
+ return '↕';
511
+ return s.direction === 'asc' ? '↑' : '↓';
512
+ }
513
+ static ɵfac = i0.ɵɵngDeclareFactory({ minVersion: "12.0.0", version: "20.3.19", ngImport: i0, type: TableComponent, deps: [], target: i0.ɵɵFactoryTarget.Component });
514
+ static ɵcmp = i0.ɵɵngDeclareComponent({ minVersion: "17.0.0", version: "20.3.19", type: TableComponent, isStandalone: true, selector: "c2g-table", inputs: { rows: { classPropertyName: "rows", publicName: "rows", isSignal: true, isRequired: true, transformFunction: null }, columns: { classPropertyName: "columns", publicName: "columns", isSignal: true, isRequired: true, transformFunction: null }, rowHeight: { classPropertyName: "rowHeight", publicName: "rowHeight", isSignal: true, isRequired: false, transformFunction: null }, maxHeight: { classPropertyName: "maxHeight", publicName: "maxHeight", isSignal: true, isRequired: false, transformFunction: null }, selectable: { classPropertyName: "selectable", publicName: "selectable", isSignal: true, isRequired: false, transformFunction: null }, virtualScroll: { classPropertyName: "virtualScroll", publicName: "virtualScroll", isSignal: true, isRequired: false, transformFunction: null } }, outputs: { sortChanged: "sortChanged", rowSelected: "rowSelected" }, ngImport: i0, template: "<div class=\"c2g-table-wrapper\" [style.maxHeight]=\"maxHeight()\">\n @if (virtualScroll()) {\n <cdk-virtual-scroll-viewport [itemSize]=\"rowHeight()\" class=\"c2g-table-viewport\" [style.height]=\"maxHeight()\">\n <table class=\"c2g-table\" role=\"grid\">\n <thead class=\"c2g-table__head\">\n <tr>\n @for (col of columns(); track col.key) {\n <th\n class=\"c2g-table__th\"\n [class.c2g-table__th--sortable]=\"col.sortable\"\n [class.c2g-table__th--sorted]=\"sortState().key === col.key\"\n (click)=\"col.sortable && sort(col.key)\"\n [attr.aria-sort]=\"col.sortable ? (sortState().key === col.key ? (sortState().direction ?? 'none') : 'none') : null\"\n >\n <span class=\"c2g-table__th-label\">{{ col.label }}</span>\n @if (col.sortable) {\n <span class=\"c2g-table__sort-icon\" aria-hidden=\"true\">{{ sortIcon(col.key) }}</span>\n }\n </th>\n }\n </tr>\n </thead>\n <tbody>\n <tr\n *cdkVirtualFor=\"let row of sortedRows()\"\n class=\"c2g-table__row\"\n [class.c2g-table__row--selectable]=\"selectable()\"\n [class.c2g-table__row--selected]=\"selectedRow() === row\"\n (click)=\"select(row)\"\n [attr.tabindex]=\"selectable() ? 0 : null\"\n (keydown.enter)=\"selectable() && select(row)\"\n >\n @for (col of columns(); track col.key) {\n <td class=\"c2g-table__td\">{{ getCellValue(row, col) }}</td>\n }\n </tr>\n </tbody>\n </table>\n </cdk-virtual-scroll-viewport>\n } @else {\n <table class=\"c2g-table\" role=\"grid\">\n <thead class=\"c2g-table__head\">\n <tr>\n @for (col of columns(); track col.key) {\n <th\n class=\"c2g-table__th\"\n [class.c2g-table__th--sortable]=\"col.sortable\"\n [class.c2g-table__th--sorted]=\"sortState().key === col.key\"\n (click)=\"col.sortable && sort(col.key)\"\n [attr.aria-sort]=\"col.sortable ? (sortState().key === col.key ? (sortState().direction ?? 'none') : 'none') : null\"\n >\n <span class=\"c2g-table__th-label\">{{ col.label }}</span>\n @if (col.sortable) {\n <span class=\"c2g-table__sort-icon\" aria-hidden=\"true\">{{ sortIcon(col.key) }}</span>\n }\n </th>\n }\n </tr>\n </thead>\n <tbody>\n @for (row of sortedRows(); track $index) {\n <tr\n class=\"c2g-table__row\"\n [class.c2g-table__row--selectable]=\"selectable()\"\n [class.c2g-table__row--selected]=\"selectedRow() === row\"\n (click)=\"select(row)\"\n [attr.tabindex]=\"selectable() ? 0 : null\"\n (keydown.enter)=\"selectable() && select(row)\"\n >\n @for (col of columns(); track col.key) {\n <td class=\"c2g-table__td\">{{ getCellValue(row, col) }}</td>\n }\n </tr>\n }\n </tbody>\n </table>\n }\n</div>\n", styles: [":host{display:block;width:100%;transition:background-color var(--c2g-transition-medium, .25s ease),color var(--c2g-transition-medium, .25s ease),border-color var(--c2g-transition-medium, .25s ease)}.c2g-table-wrapper{overflow:auto;border:1px solid var(--c2g-theme-outline-variant, var(--c2g-color-outline));border-radius:var(--c2g-radius-md, 8px);background:var(--c2g-theme-surface, var(--c2g-color-surface))}.c2g-table-viewport{width:100%}.c2g-table{width:100%;border-collapse:collapse;font-family:var(--c2g-font-family-base, \"Quicksand\", sans-serif);font-size:var(--c2g-font-size-sm, .875rem);color:var(--c2g-theme-on-surface, var(--c2g-color-text-primary))}.c2g-table__head{position:sticky;top:0;z-index:1;background:var(--c2g-theme-surface-container, var(--c2g-color-bg-secondary))}.c2g-table__th{padding:12px 16px;text-align:left;font-weight:600;color:var(--c2g-theme-on-surface-variant, var(--c2g-color-text-secondary));border-bottom:2px solid var(--c2g-theme-outline-variant, var(--c2g-color-outline));white-space:nowrap;-webkit-user-select:none;user-select:none}.c2g-table__th--sortable{cursor:pointer}.c2g-table__th--sortable:hover{background:var(--c2g-theme-surface-container-low, var(--c2g-color-bg-base));color:var(--c2g-theme-on-surface, var(--c2g-color-text-primary))}.c2g-table__th--sorted{color:var(--c2g-theme-primary, var(--c2g-color-primary))}.c2g-table__th-label{display:inline}.c2g-table__sort-icon{margin-left:6px;opacity:.5;font-size:.75rem}.c2g-table__row{border-bottom:1px solid var(--c2g-theme-outline-variant, var(--c2g-color-outline));transition:background .15s ease}.c2g-table__row:last-child{border-bottom:none}.c2g-table__row--selectable{cursor:pointer}.c2g-table__row--selectable:hover{background:var(--c2g-theme-surface-container-low, var(--c2g-color-bg-base))}.c2g-table__row--selectable:focus{outline:2px solid var(--c2g-theme-primary, var(--c2g-color-primary));outline-offset:-2px}.c2g-table__row--selected,.c2g-table__row--selected:hover{background:var(--c2g-theme-primary-container, var(--c2g-color-primary-container))}.c2g-table__td{padding:12px 16px;color:var(--c2g-theme-on-surface, var(--c2g-color-text-primary));vertical-align:middle}\n"], dependencies: [{ kind: "ngmodule", type: ScrollingModule }, { kind: "directive", type: i1$4.CdkFixedSizeVirtualScroll, selector: "cdk-virtual-scroll-viewport[itemSize]", inputs: ["itemSize", "minBufferPx", "maxBufferPx"] }, { kind: "directive", type: i1$4.CdkVirtualForOf, selector: "[cdkVirtualFor][cdkVirtualForOf]", inputs: ["cdkVirtualForOf", "cdkVirtualForTrackBy", "cdkVirtualForTemplate", "cdkVirtualForTemplateCacheSize"] }, { kind: "component", type: i1$4.CdkVirtualScrollViewport, selector: "cdk-virtual-scroll-viewport", inputs: ["orientation", "appendOnly"], outputs: ["scrolledIndexChange"] }], changeDetection: i0.ChangeDetectionStrategy.OnPush });
515
+ }
516
+ i0.ɵɵngDeclareClassMetadata({ minVersion: "12.0.0", version: "20.3.19", ngImport: i0, type: TableComponent, decorators: [{
517
+ type: Component,
518
+ args: [{ selector: 'c2g-table', standalone: true, imports: [ScrollingModule, NgClass, NgTemplateOutlet], changeDetection: ChangeDetectionStrategy.OnPush, template: "<div class=\"c2g-table-wrapper\" [style.maxHeight]=\"maxHeight()\">\n @if (virtualScroll()) {\n <cdk-virtual-scroll-viewport [itemSize]=\"rowHeight()\" class=\"c2g-table-viewport\" [style.height]=\"maxHeight()\">\n <table class=\"c2g-table\" role=\"grid\">\n <thead class=\"c2g-table__head\">\n <tr>\n @for (col of columns(); track col.key) {\n <th\n class=\"c2g-table__th\"\n [class.c2g-table__th--sortable]=\"col.sortable\"\n [class.c2g-table__th--sorted]=\"sortState().key === col.key\"\n (click)=\"col.sortable && sort(col.key)\"\n [attr.aria-sort]=\"col.sortable ? (sortState().key === col.key ? (sortState().direction ?? 'none') : 'none') : null\"\n >\n <span class=\"c2g-table__th-label\">{{ col.label }}</span>\n @if (col.sortable) {\n <span class=\"c2g-table__sort-icon\" aria-hidden=\"true\">{{ sortIcon(col.key) }}</span>\n }\n </th>\n }\n </tr>\n </thead>\n <tbody>\n <tr\n *cdkVirtualFor=\"let row of sortedRows()\"\n class=\"c2g-table__row\"\n [class.c2g-table__row--selectable]=\"selectable()\"\n [class.c2g-table__row--selected]=\"selectedRow() === row\"\n (click)=\"select(row)\"\n [attr.tabindex]=\"selectable() ? 0 : null\"\n (keydown.enter)=\"selectable() && select(row)\"\n >\n @for (col of columns(); track col.key) {\n <td class=\"c2g-table__td\">{{ getCellValue(row, col) }}</td>\n }\n </tr>\n </tbody>\n </table>\n </cdk-virtual-scroll-viewport>\n } @else {\n <table class=\"c2g-table\" role=\"grid\">\n <thead class=\"c2g-table__head\">\n <tr>\n @for (col of columns(); track col.key) {\n <th\n class=\"c2g-table__th\"\n [class.c2g-table__th--sortable]=\"col.sortable\"\n [class.c2g-table__th--sorted]=\"sortState().key === col.key\"\n (click)=\"col.sortable && sort(col.key)\"\n [attr.aria-sort]=\"col.sortable ? (sortState().key === col.key ? (sortState().direction ?? 'none') : 'none') : null\"\n >\n <span class=\"c2g-table__th-label\">{{ col.label }}</span>\n @if (col.sortable) {\n <span class=\"c2g-table__sort-icon\" aria-hidden=\"true\">{{ sortIcon(col.key) }}</span>\n }\n </th>\n }\n </tr>\n </thead>\n <tbody>\n @for (row of sortedRows(); track $index) {\n <tr\n class=\"c2g-table__row\"\n [class.c2g-table__row--selectable]=\"selectable()\"\n [class.c2g-table__row--selected]=\"selectedRow() === row\"\n (click)=\"select(row)\"\n [attr.tabindex]=\"selectable() ? 0 : null\"\n (keydown.enter)=\"selectable() && select(row)\"\n >\n @for (col of columns(); track col.key) {\n <td class=\"c2g-table__td\">{{ getCellValue(row, col) }}</td>\n }\n </tr>\n }\n </tbody>\n </table>\n }\n</div>\n", styles: [":host{display:block;width:100%;transition:background-color var(--c2g-transition-medium, .25s ease),color var(--c2g-transition-medium, .25s ease),border-color var(--c2g-transition-medium, .25s ease)}.c2g-table-wrapper{overflow:auto;border:1px solid var(--c2g-theme-outline-variant, var(--c2g-color-outline));border-radius:var(--c2g-radius-md, 8px);background:var(--c2g-theme-surface, var(--c2g-color-surface))}.c2g-table-viewport{width:100%}.c2g-table{width:100%;border-collapse:collapse;font-family:var(--c2g-font-family-base, \"Quicksand\", sans-serif);font-size:var(--c2g-font-size-sm, .875rem);color:var(--c2g-theme-on-surface, var(--c2g-color-text-primary))}.c2g-table__head{position:sticky;top:0;z-index:1;background:var(--c2g-theme-surface-container, var(--c2g-color-bg-secondary))}.c2g-table__th{padding:12px 16px;text-align:left;font-weight:600;color:var(--c2g-theme-on-surface-variant, var(--c2g-color-text-secondary));border-bottom:2px solid var(--c2g-theme-outline-variant, var(--c2g-color-outline));white-space:nowrap;-webkit-user-select:none;user-select:none}.c2g-table__th--sortable{cursor:pointer}.c2g-table__th--sortable:hover{background:var(--c2g-theme-surface-container-low, var(--c2g-color-bg-base));color:var(--c2g-theme-on-surface, var(--c2g-color-text-primary))}.c2g-table__th--sorted{color:var(--c2g-theme-primary, var(--c2g-color-primary))}.c2g-table__th-label{display:inline}.c2g-table__sort-icon{margin-left:6px;opacity:.5;font-size:.75rem}.c2g-table__row{border-bottom:1px solid var(--c2g-theme-outline-variant, var(--c2g-color-outline));transition:background .15s ease}.c2g-table__row:last-child{border-bottom:none}.c2g-table__row--selectable{cursor:pointer}.c2g-table__row--selectable:hover{background:var(--c2g-theme-surface-container-low, var(--c2g-color-bg-base))}.c2g-table__row--selectable:focus{outline:2px solid var(--c2g-theme-primary, var(--c2g-color-primary));outline-offset:-2px}.c2g-table__row--selected,.c2g-table__row--selected:hover{background:var(--c2g-theme-primary-container, var(--c2g-color-primary-container))}.c2g-table__td{padding:12px 16px;color:var(--c2g-theme-on-surface, var(--c2g-color-text-primary));vertical-align:middle}\n"] }]
519
+ }], propDecorators: { rows: [{ type: i0.Input, args: [{ isSignal: true, alias: "rows", required: true }] }], columns: [{ type: i0.Input, args: [{ isSignal: true, alias: "columns", required: true }] }], rowHeight: [{ type: i0.Input, args: [{ isSignal: true, alias: "rowHeight", required: false }] }], maxHeight: [{ type: i0.Input, args: [{ isSignal: true, alias: "maxHeight", required: false }] }], selectable: [{ type: i0.Input, args: [{ isSignal: true, alias: "selectable", required: false }] }], virtualScroll: [{ type: i0.Input, args: [{ isSignal: true, alias: "virtualScroll", required: false }] }], sortChanged: [{ type: i0.Output, args: ["sortChanged"] }], rowSelected: [{ type: i0.Output, args: ["rowSelected"] }] } });
520
+
521
+ class TabsComponent {
522
+ tabs = input.required(...(ngDevMode ? [{ debugName: "tabs" }] : []));
523
+ activeKey = model('', ...(ngDevMode ? [{ debugName: "activeKey" }] : []));
524
+ tabChanged = output();
525
+ activeTab = computed(() => this.tabs().find(t => t.key === this.activeKey()) ?? this.tabs()[0], ...(ngDevMode ? [{ debugName: "activeTab" }] : []));
526
+ select(tab) {
527
+ if (tab.disabled)
528
+ return;
529
+ this.activeKey.set(tab.key);
530
+ this.tabChanged.emit(tab);
531
+ }
532
+ isActive(tab) {
533
+ const key = this.activeKey();
534
+ return key ? tab.key === key : tab === this.tabs()[0];
535
+ }
536
+ static ɵfac = i0.ɵɵngDeclareFactory({ minVersion: "12.0.0", version: "20.3.19", ngImport: i0, type: TabsComponent, deps: [], target: i0.ɵɵFactoryTarget.Component });
537
+ static ɵcmp = i0.ɵɵngDeclareComponent({ minVersion: "17.0.0", version: "20.3.19", type: TabsComponent, isStandalone: true, selector: "c2g-tabs", inputs: { tabs: { classPropertyName: "tabs", publicName: "tabs", isSignal: true, isRequired: true, transformFunction: null }, activeKey: { classPropertyName: "activeKey", publicName: "activeKey", isSignal: true, isRequired: false, transformFunction: null } }, outputs: { activeKey: "activeKeyChange", tabChanged: "tabChanged" }, ngImport: i0, template: "<div class=\"c2g-tabs\" role=\"tablist\" [attr.aria-label]=\"'Tabs'\">\n <div class=\"c2g-tabs__nav\">\n @for (tab of tabs(); track tab.key) {\n <button\n class=\"c2g-tabs__tab\"\n role=\"tab\"\n [class.c2g-tabs__tab--active]=\"isActive(tab)\"\n [class.c2g-tabs__tab--disabled]=\"tab.disabled\"\n [attr.aria-selected]=\"isActive(tab)\"\n [attr.aria-disabled]=\"tab.disabled || null\"\n [disabled]=\"tab.disabled || null\"\n (click)=\"select(tab)\"\n >\n @if (tab.icon) {\n <span class=\"c2g-tabs__tab-icon\" aria-hidden=\"true\">{{ tab.icon }}</span>\n }\n <span class=\"c2g-tabs__tab-label\">{{ tab.label }}</span>\n @if (tab.badge !== undefined) {\n <span class=\"c2g-tabs__tab-badge\">{{ tab.badge }}</span>\n }\n </button>\n }\n </div>\n\n <div class=\"c2g-tabs__indicator-bar\" aria-hidden=\"true\"></div>\n\n <div class=\"c2g-tabs__panel\" role=\"tabpanel\">\n <ng-content></ng-content>\n </div>\n</div>\n", styles: [":host{display:block;width:100%;transition:background-color var(--c2g-transition-medium, .25s ease),color var(--c2g-transition-medium, .25s ease),border-color var(--c2g-transition-medium, .25s ease)}.c2g-tabs{font-family:var(--c2g-font-family-base, \"Quicksand\", sans-serif)}.c2g-tabs__nav{display:flex;gap:4px;border-bottom:2px solid var(--c2g-theme-outline-variant, var(--c2g-color-outline));overflow-x:auto;scrollbar-width:none}.c2g-tabs__nav::-webkit-scrollbar{display:none}.c2g-tabs__tab{position:relative;display:inline-flex;align-items:center;gap:6px;padding:10px 16px;border:none;background:none;cursor:pointer;font-family:inherit;font-size:var(--c2g-font-size-sm, .875rem);font-weight:500;color:var(--c2g-theme-on-surface-variant, var(--c2g-color-text-secondary));white-space:nowrap;transition:color .15s ease;border-bottom:2px solid transparent;margin-bottom:-2px}.c2g-tabs__tab:hover:not(.c2g-tabs__tab--disabled){color:var(--c2g-theme-on-surface, var(--c2g-color-text-primary))}.c2g-tabs__tab--active{color:var(--c2g-theme-primary, var(--c2g-color-primary));border-bottom-color:var(--c2g-theme-primary, var(--c2g-color-primary));font-weight:600}.c2g-tabs__tab--disabled{opacity:.4;cursor:not-allowed}.c2g-tabs__tab:focus-visible{outline:2px solid var(--c2g-theme-primary, var(--c2g-color-primary));outline-offset:2px;border-radius:var(--c2g-radius-sm, 4px)}.c2g-tabs__tab-icon{font-size:1rem}.c2g-tabs__tab-badge{display:inline-flex;align-items:center;justify-content:center;min-width:18px;height:18px;padding:0 5px;border-radius:9px;background:var(--c2g-theme-primary, var(--c2g-color-primary));color:var(--c2g-theme-surface, var(--c2g-color-surface));font-size:.7rem;font-weight:700;line-height:1}.c2g-tabs__panel{padding-top:16px}\n"], changeDetection: i0.ChangeDetectionStrategy.OnPush });
538
+ }
539
+ i0.ɵɵngDeclareClassMetadata({ minVersion: "12.0.0", version: "20.3.19", ngImport: i0, type: TabsComponent, decorators: [{
540
+ type: Component,
541
+ args: [{ selector: 'c2g-tabs', standalone: true, imports: [], changeDetection: ChangeDetectionStrategy.OnPush, template: "<div class=\"c2g-tabs\" role=\"tablist\" [attr.aria-label]=\"'Tabs'\">\n <div class=\"c2g-tabs__nav\">\n @for (tab of tabs(); track tab.key) {\n <button\n class=\"c2g-tabs__tab\"\n role=\"tab\"\n [class.c2g-tabs__tab--active]=\"isActive(tab)\"\n [class.c2g-tabs__tab--disabled]=\"tab.disabled\"\n [attr.aria-selected]=\"isActive(tab)\"\n [attr.aria-disabled]=\"tab.disabled || null\"\n [disabled]=\"tab.disabled || null\"\n (click)=\"select(tab)\"\n >\n @if (tab.icon) {\n <span class=\"c2g-tabs__tab-icon\" aria-hidden=\"true\">{{ tab.icon }}</span>\n }\n <span class=\"c2g-tabs__tab-label\">{{ tab.label }}</span>\n @if (tab.badge !== undefined) {\n <span class=\"c2g-tabs__tab-badge\">{{ tab.badge }}</span>\n }\n </button>\n }\n </div>\n\n <div class=\"c2g-tabs__indicator-bar\" aria-hidden=\"true\"></div>\n\n <div class=\"c2g-tabs__panel\" role=\"tabpanel\">\n <ng-content></ng-content>\n </div>\n</div>\n", styles: [":host{display:block;width:100%;transition:background-color var(--c2g-transition-medium, .25s ease),color var(--c2g-transition-medium, .25s ease),border-color var(--c2g-transition-medium, .25s ease)}.c2g-tabs{font-family:var(--c2g-font-family-base, \"Quicksand\", sans-serif)}.c2g-tabs__nav{display:flex;gap:4px;border-bottom:2px solid var(--c2g-theme-outline-variant, var(--c2g-color-outline));overflow-x:auto;scrollbar-width:none}.c2g-tabs__nav::-webkit-scrollbar{display:none}.c2g-tabs__tab{position:relative;display:inline-flex;align-items:center;gap:6px;padding:10px 16px;border:none;background:none;cursor:pointer;font-family:inherit;font-size:var(--c2g-font-size-sm, .875rem);font-weight:500;color:var(--c2g-theme-on-surface-variant, var(--c2g-color-text-secondary));white-space:nowrap;transition:color .15s ease;border-bottom:2px solid transparent;margin-bottom:-2px}.c2g-tabs__tab:hover:not(.c2g-tabs__tab--disabled){color:var(--c2g-theme-on-surface, var(--c2g-color-text-primary))}.c2g-tabs__tab--active{color:var(--c2g-theme-primary, var(--c2g-color-primary));border-bottom-color:var(--c2g-theme-primary, var(--c2g-color-primary));font-weight:600}.c2g-tabs__tab--disabled{opacity:.4;cursor:not-allowed}.c2g-tabs__tab:focus-visible{outline:2px solid var(--c2g-theme-primary, var(--c2g-color-primary));outline-offset:2px;border-radius:var(--c2g-radius-sm, 4px)}.c2g-tabs__tab-icon{font-size:1rem}.c2g-tabs__tab-badge{display:inline-flex;align-items:center;justify-content:center;min-width:18px;height:18px;padding:0 5px;border-radius:9px;background:var(--c2g-theme-primary, var(--c2g-color-primary));color:var(--c2g-theme-surface, var(--c2g-color-surface));font-size:.7rem;font-weight:700;line-height:1}.c2g-tabs__panel{padding-top:16px}\n"] }]
542
+ }], propDecorators: { tabs: [{ type: i0.Input, args: [{ isSignal: true, alias: "tabs", required: true }] }], activeKey: [{ type: i0.Input, args: [{ isSignal: true, alias: "activeKey", required: false }] }, { type: i0.Output, args: ["activeKeyChange"] }], tabChanged: [{ type: i0.Output, args: ["tabChanged"] }] } });
543
+
544
+ class BreadcrumbComponent {
545
+ items = input.required(...(ngDevMode ? [{ debugName: "items" }] : []));
546
+ separator = input('›', ...(ngDevMode ? [{ debugName: "separator" }] : []));
547
+ itemClicked = output();
548
+ navigate(event, item) {
549
+ if (!item.href) {
550
+ event.preventDefault();
551
+ this.itemClicked.emit(item);
552
+ }
553
+ }
554
+ static ɵfac = i0.ɵɵngDeclareFactory({ minVersion: "12.0.0", version: "20.3.19", ngImport: i0, type: BreadcrumbComponent, deps: [], target: i0.ɵɵFactoryTarget.Component });
555
+ static ɵcmp = i0.ɵɵngDeclareComponent({ minVersion: "17.0.0", version: "20.3.19", type: BreadcrumbComponent, isStandalone: true, selector: "c2g-breadcrumb", inputs: { items: { classPropertyName: "items", publicName: "items", isSignal: true, isRequired: true, transformFunction: null }, separator: { classPropertyName: "separator", publicName: "separator", isSignal: true, isRequired: false, transformFunction: null } }, outputs: { itemClicked: "itemClicked" }, ngImport: i0, template: "<nav class=\"c2g-breadcrumb\" aria-label=\"Breadcrumb\">\n <ol class=\"c2g-breadcrumb__list\">\n @for (item of items(); track item.label; let last = $last) {\n <li class=\"c2g-breadcrumb__item\">\n @if (!last) {\n <a\n class=\"c2g-breadcrumb__link\"\n [href]=\"item.href || '#'\"\n (click)=\"navigate($event, item)\"\n >\n @if (item.icon) {\n <span class=\"c2g-breadcrumb__icon\" aria-hidden=\"true\">{{ item.icon }}</span>\n }\n {{ item.label }}\n </a>\n <span class=\"c2g-breadcrumb__separator\" aria-hidden=\"true\">{{ separator() }}</span>\n } @else {\n <span class=\"c2g-breadcrumb__current\" aria-current=\"page\">\n @if (item.icon) {\n <span class=\"c2g-breadcrumb__icon\" aria-hidden=\"true\">{{ item.icon }}</span>\n }\n {{ item.label }}\n </span>\n }\n </li>\n }\n </ol>\n</nav>\n", styles: [":host{display:block;transition:background-color var(--c2g-transition-medium, .25s ease),color var(--c2g-transition-medium, .25s ease),border-color var(--c2g-transition-medium, .25s ease)}.c2g-breadcrumb{font-family:var(--c2g-font-family-base, \"Quicksand\", sans-serif)}.c2g-breadcrumb__list{display:flex;align-items:center;flex-wrap:wrap;gap:4px;list-style:none;margin:0;padding:0;font-size:var(--c2g-font-size-sm, .875rem)}.c2g-breadcrumb__item{display:flex;align-items:center;gap:4px}.c2g-breadcrumb__link{color:var(--c2g-theme-on-surface-variant, var(--c2g-color-text-secondary));text-decoration:none;transition:color .15s ease;display:inline-flex;align-items:center;gap:4px;border-radius:var(--c2g-radius-sm, 4px);padding:2px 4px}.c2g-breadcrumb__link:hover{color:var(--c2g-theme-primary, var(--c2g-color-primary));text-decoration:underline}.c2g-breadcrumb__link:focus-visible{outline:2px solid var(--c2g-theme-primary, var(--c2g-color-primary));outline-offset:2px}.c2g-breadcrumb__separator{color:var(--c2g-theme-on-surface-variant, var(--c2g-color-text-muted));-webkit-user-select:none;user-select:none;font-size:.9em}.c2g-breadcrumb__current{color:var(--c2g-theme-on-surface, var(--c2g-color-text-primary));font-weight:600;display:inline-flex;align-items:center;gap:4px}.c2g-breadcrumb__icon{font-size:1em;line-height:1}\n"], changeDetection: i0.ChangeDetectionStrategy.OnPush });
556
+ }
557
+ i0.ɵɵngDeclareClassMetadata({ minVersion: "12.0.0", version: "20.3.19", ngImport: i0, type: BreadcrumbComponent, decorators: [{
558
+ type: Component,
559
+ args: [{ selector: 'c2g-breadcrumb', standalone: true, imports: [], changeDetection: ChangeDetectionStrategy.OnPush, template: "<nav class=\"c2g-breadcrumb\" aria-label=\"Breadcrumb\">\n <ol class=\"c2g-breadcrumb__list\">\n @for (item of items(); track item.label; let last = $last) {\n <li class=\"c2g-breadcrumb__item\">\n @if (!last) {\n <a\n class=\"c2g-breadcrumb__link\"\n [href]=\"item.href || '#'\"\n (click)=\"navigate($event, item)\"\n >\n @if (item.icon) {\n <span class=\"c2g-breadcrumb__icon\" aria-hidden=\"true\">{{ item.icon }}</span>\n }\n {{ item.label }}\n </a>\n <span class=\"c2g-breadcrumb__separator\" aria-hidden=\"true\">{{ separator() }}</span>\n } @else {\n <span class=\"c2g-breadcrumb__current\" aria-current=\"page\">\n @if (item.icon) {\n <span class=\"c2g-breadcrumb__icon\" aria-hidden=\"true\">{{ item.icon }}</span>\n }\n {{ item.label }}\n </span>\n }\n </li>\n }\n </ol>\n</nav>\n", styles: [":host{display:block;transition:background-color var(--c2g-transition-medium, .25s ease),color var(--c2g-transition-medium, .25s ease),border-color var(--c2g-transition-medium, .25s ease)}.c2g-breadcrumb{font-family:var(--c2g-font-family-base, \"Quicksand\", sans-serif)}.c2g-breadcrumb__list{display:flex;align-items:center;flex-wrap:wrap;gap:4px;list-style:none;margin:0;padding:0;font-size:var(--c2g-font-size-sm, .875rem)}.c2g-breadcrumb__item{display:flex;align-items:center;gap:4px}.c2g-breadcrumb__link{color:var(--c2g-theme-on-surface-variant, var(--c2g-color-text-secondary));text-decoration:none;transition:color .15s ease;display:inline-flex;align-items:center;gap:4px;border-radius:var(--c2g-radius-sm, 4px);padding:2px 4px}.c2g-breadcrumb__link:hover{color:var(--c2g-theme-primary, var(--c2g-color-primary));text-decoration:underline}.c2g-breadcrumb__link:focus-visible{outline:2px solid var(--c2g-theme-primary, var(--c2g-color-primary));outline-offset:2px}.c2g-breadcrumb__separator{color:var(--c2g-theme-on-surface-variant, var(--c2g-color-text-muted));-webkit-user-select:none;user-select:none;font-size:.9em}.c2g-breadcrumb__current{color:var(--c2g-theme-on-surface, var(--c2g-color-text-primary));font-weight:600;display:inline-flex;align-items:center;gap:4px}.c2g-breadcrumb__icon{font-size:1em;line-height:1}\n"] }]
560
+ }], propDecorators: { items: [{ type: i0.Input, args: [{ isSignal: true, alias: "items", required: true }] }], separator: [{ type: i0.Input, args: [{ isSignal: true, alias: "separator", required: false }] }], itemClicked: [{ type: i0.Output, args: ["itemClicked"] }] } });
561
+
562
+ class StepperComponent {
563
+ steps = input.required(...(ngDevMode ? [{ debugName: "steps" }] : []));
564
+ activeIndex = model(0, ...(ngDevMode ? [{ debugName: "activeIndex" }] : []));
565
+ completedIndices = input([], ...(ngDevMode ? [{ debugName: "completedIndices" }] : []));
566
+ errorIndices = input([], ...(ngDevMode ? [{ debugName: "errorIndices" }] : []));
567
+ orientation = input('horizontal', ...(ngDevMode ? [{ debugName: "orientation" }] : []));
568
+ stepChanged = output();
569
+ canGoNext = computed(() => this.activeIndex() < this.steps().length - 1, ...(ngDevMode ? [{ debugName: "canGoNext" }] : []));
570
+ canGoPrev = computed(() => this.activeIndex() > 0, ...(ngDevMode ? [{ debugName: "canGoPrev" }] : []));
571
+ getState(index) {
572
+ if (this.errorIndices().includes(index))
573
+ return 'error';
574
+ if (this.completedIndices().includes(index))
575
+ return 'completed';
576
+ if (index === this.activeIndex())
577
+ return 'active';
578
+ return 'pending';
579
+ }
580
+ goTo(index) {
581
+ if (index < 0 || index >= this.steps().length)
582
+ return;
583
+ this.activeIndex.set(index);
584
+ this.stepChanged.emit({ step: this.steps()[index], index });
585
+ }
586
+ next() { this.goTo(this.activeIndex() + 1); }
587
+ prev() { this.goTo(this.activeIndex() - 1); }
588
+ static ɵfac = i0.ɵɵngDeclareFactory({ minVersion: "12.0.0", version: "20.3.19", ngImport: i0, type: StepperComponent, deps: [], target: i0.ɵɵFactoryTarget.Component });
589
+ static ɵcmp = i0.ɵɵngDeclareComponent({ minVersion: "17.0.0", version: "20.3.19", type: StepperComponent, isStandalone: true, selector: "c2g-stepper", inputs: { steps: { classPropertyName: "steps", publicName: "steps", isSignal: true, isRequired: true, transformFunction: null }, activeIndex: { classPropertyName: "activeIndex", publicName: "activeIndex", isSignal: true, isRequired: false, transformFunction: null }, completedIndices: { classPropertyName: "completedIndices", publicName: "completedIndices", isSignal: true, isRequired: false, transformFunction: null }, errorIndices: { classPropertyName: "errorIndices", publicName: "errorIndices", isSignal: true, isRequired: false, transformFunction: null }, orientation: { classPropertyName: "orientation", publicName: "orientation", isSignal: true, isRequired: false, transformFunction: null } }, outputs: { activeIndex: "activeIndexChange", stepChanged: "stepChanged" }, ngImport: i0, template: "<div\n class=\"c2g-stepper\"\n [class.c2g-stepper--horizontal]=\"orientation() === 'horizontal'\"\n [class.c2g-stepper--vertical]=\"orientation() === 'vertical'\"\n role=\"list\"\n [attr.aria-label]=\"'Steps'\"\n>\n @for (step of steps(); track step.label; let i = $index; let last = $last) {\n <div\n class=\"c2g-stepper__step\"\n [class.c2g-stepper__step--active]=\"getState(i) === 'active'\"\n [class.c2g-stepper__step--completed]=\"getState(i) === 'completed'\"\n [class.c2g-stepper__step--error]=\"getState(i) === 'error'\"\n [class.c2g-stepper__step--pending]=\"getState(i) === 'pending'\"\n role=\"listitem\"\n >\n <div class=\"c2g-stepper__header\">\n <button\n class=\"c2g-stepper__marker\"\n type=\"button\"\n [attr.aria-label]=\"'Step ' + (i + 1) + ': ' + step.label\"\n [attr.aria-current]=\"getState(i) === 'active' ? 'step' : null\"\n (click)=\"goTo(i)\"\n >\n @if (getState(i) === 'completed') {\n <span class=\"c2g-stepper__check\" aria-hidden=\"true\">\u2713</span>\n } @else if (getState(i) === 'error') {\n <span class=\"c2g-stepper__error-icon\" aria-hidden=\"true\">!</span>\n } @else {\n <span class=\"c2g-stepper__index\" aria-hidden=\"true\">{{ i + 1 }}</span>\n }\n </button>\n\n <div class=\"c2g-stepper__label-group\">\n <span class=\"c2g-stepper__label\">{{ step.label }}</span>\n @if (step.description) {\n <span class=\"c2g-stepper__description\">{{ step.description }}</span>\n }\n </div>\n </div>\n\n @if (!last) {\n <div class=\"c2g-stepper__connector\" aria-hidden=\"true\">\n <div\n class=\"c2g-stepper__connector-line\"\n [class.c2g-stepper__connector-line--filled]=\"getState(i) === 'completed'\"\n ></div>\n </div>\n }\n </div>\n }\n</div>\n", styles: [":host{display:block;transition:background-color var(--c2g-transition-medium, .25s ease),color var(--c2g-transition-medium, .25s ease),border-color var(--c2g-transition-medium, .25s ease)}.c2g-stepper{font-family:var(--c2g-font-family-base, \"Quicksand\", sans-serif)}.c2g-stepper--horizontal{display:flex;align-items:flex-start}.c2g-stepper--horizontal .c2g-stepper__step{flex:1;display:flex;flex-direction:column;align-items:center}.c2g-stepper--horizontal .c2g-stepper__header{display:flex;flex-direction:column;align-items:center;text-align:center;gap:8px}.c2g-stepper--horizontal .c2g-stepper__connector{flex:1;display:flex;align-items:center;padding-top:20px}.c2g-stepper--horizontal .c2g-stepper__connector-line{flex:1;height:2px;background:var(--c2g-theme-outline-variant, var(--c2g-color-outline));margin:0 8px}.c2g-stepper--horizontal .c2g-stepper__connector-line--filled{background:var(--c2g-theme-primary, var(--c2g-color-primary))}.c2g-stepper--vertical,.c2g-stepper--vertical .c2g-stepper__step{display:flex;flex-direction:column}.c2g-stepper--vertical .c2g-stepper__header{display:flex;align-items:center;gap:12px}.c2g-stepper--vertical .c2g-stepper__connector{display:flex;padding-left:20px;min-height:24px}.c2g-stepper--vertical .c2g-stepper__connector-line{width:2px;flex:1;background:var(--c2g-theme-outline-variant, var(--c2g-color-outline));margin:4px 0}.c2g-stepper--vertical .c2g-stepper__connector-line--filled{background:var(--c2g-theme-primary, var(--c2g-color-primary))}.c2g-stepper__marker{display:inline-flex;align-items:center;justify-content:center;width:40px;height:40px;border-radius:50%;border:2px solid var(--c2g-theme-outline-variant, var(--c2g-color-outline));background:var(--c2g-theme-surface, var(--c2g-color-surface));cursor:pointer;font-weight:700;font-size:.875rem;color:var(--c2g-theme-on-surface-variant, var(--c2g-color-text-secondary));transition:border-color .2s ease,background .2s ease,color .2s ease;flex-shrink:0}.c2g-stepper__marker:focus-visible{outline:2px solid var(--c2g-theme-primary, var(--c2g-color-primary));outline-offset:3px}.c2g-stepper__step--active .c2g-stepper__marker{border-color:var(--c2g-theme-primary, var(--c2g-color-primary));background:var(--c2g-theme-primary, var(--c2g-color-primary));color:var(--c2g-theme-surface, var(--c2g-color-surface))}.c2g-stepper__step--completed .c2g-stepper__marker{border-color:var(--c2g-theme-success, var(--c2g-color-success));background:var(--c2g-theme-success, var(--c2g-color-success));color:var(--c2g-theme-surface, var(--c2g-color-surface))}.c2g-stepper__step--error .c2g-stepper__marker{border-color:var(--c2g-theme-error, var(--c2g-color-error));background:var(--c2g-theme-error, var(--c2g-color-error));color:var(--c2g-theme-surface, var(--c2g-color-surface))}.c2g-stepper__label{font-weight:600;font-size:var(--c2g-font-size-sm, .875rem);color:var(--c2g-theme-on-surface-variant, var(--c2g-color-text-secondary))}.c2g-stepper__step--active .c2g-stepper__label{color:var(--c2g-theme-primary, var(--c2g-color-primary))}.c2g-stepper__step--completed .c2g-stepper__label{color:var(--c2g-theme-on-surface, var(--c2g-color-text-primary))}.c2g-stepper__description{font-size:var(--c2g-font-size-xs, .75rem);color:var(--c2g-theme-on-surface-variant, var(--c2g-color-text-muted));margin-top:2px}\n"], changeDetection: i0.ChangeDetectionStrategy.OnPush });
590
+ }
591
+ i0.ɵɵngDeclareClassMetadata({ minVersion: "12.0.0", version: "20.3.19", ngImport: i0, type: StepperComponent, decorators: [{
592
+ type: Component,
593
+ args: [{ selector: 'c2g-stepper', standalone: true, imports: [], changeDetection: ChangeDetectionStrategy.OnPush, template: "<div\n class=\"c2g-stepper\"\n [class.c2g-stepper--horizontal]=\"orientation() === 'horizontal'\"\n [class.c2g-stepper--vertical]=\"orientation() === 'vertical'\"\n role=\"list\"\n [attr.aria-label]=\"'Steps'\"\n>\n @for (step of steps(); track step.label; let i = $index; let last = $last) {\n <div\n class=\"c2g-stepper__step\"\n [class.c2g-stepper__step--active]=\"getState(i) === 'active'\"\n [class.c2g-stepper__step--completed]=\"getState(i) === 'completed'\"\n [class.c2g-stepper__step--error]=\"getState(i) === 'error'\"\n [class.c2g-stepper__step--pending]=\"getState(i) === 'pending'\"\n role=\"listitem\"\n >\n <div class=\"c2g-stepper__header\">\n <button\n class=\"c2g-stepper__marker\"\n type=\"button\"\n [attr.aria-label]=\"'Step ' + (i + 1) + ': ' + step.label\"\n [attr.aria-current]=\"getState(i) === 'active' ? 'step' : null\"\n (click)=\"goTo(i)\"\n >\n @if (getState(i) === 'completed') {\n <span class=\"c2g-stepper__check\" aria-hidden=\"true\">\u2713</span>\n } @else if (getState(i) === 'error') {\n <span class=\"c2g-stepper__error-icon\" aria-hidden=\"true\">!</span>\n } @else {\n <span class=\"c2g-stepper__index\" aria-hidden=\"true\">{{ i + 1 }}</span>\n }\n </button>\n\n <div class=\"c2g-stepper__label-group\">\n <span class=\"c2g-stepper__label\">{{ step.label }}</span>\n @if (step.description) {\n <span class=\"c2g-stepper__description\">{{ step.description }}</span>\n }\n </div>\n </div>\n\n @if (!last) {\n <div class=\"c2g-stepper__connector\" aria-hidden=\"true\">\n <div\n class=\"c2g-stepper__connector-line\"\n [class.c2g-stepper__connector-line--filled]=\"getState(i) === 'completed'\"\n ></div>\n </div>\n }\n </div>\n }\n</div>\n", styles: [":host{display:block;transition:background-color var(--c2g-transition-medium, .25s ease),color var(--c2g-transition-medium, .25s ease),border-color var(--c2g-transition-medium, .25s ease)}.c2g-stepper{font-family:var(--c2g-font-family-base, \"Quicksand\", sans-serif)}.c2g-stepper--horizontal{display:flex;align-items:flex-start}.c2g-stepper--horizontal .c2g-stepper__step{flex:1;display:flex;flex-direction:column;align-items:center}.c2g-stepper--horizontal .c2g-stepper__header{display:flex;flex-direction:column;align-items:center;text-align:center;gap:8px}.c2g-stepper--horizontal .c2g-stepper__connector{flex:1;display:flex;align-items:center;padding-top:20px}.c2g-stepper--horizontal .c2g-stepper__connector-line{flex:1;height:2px;background:var(--c2g-theme-outline-variant, var(--c2g-color-outline));margin:0 8px}.c2g-stepper--horizontal .c2g-stepper__connector-line--filled{background:var(--c2g-theme-primary, var(--c2g-color-primary))}.c2g-stepper--vertical,.c2g-stepper--vertical .c2g-stepper__step{display:flex;flex-direction:column}.c2g-stepper--vertical .c2g-stepper__header{display:flex;align-items:center;gap:12px}.c2g-stepper--vertical .c2g-stepper__connector{display:flex;padding-left:20px;min-height:24px}.c2g-stepper--vertical .c2g-stepper__connector-line{width:2px;flex:1;background:var(--c2g-theme-outline-variant, var(--c2g-color-outline));margin:4px 0}.c2g-stepper--vertical .c2g-stepper__connector-line--filled{background:var(--c2g-theme-primary, var(--c2g-color-primary))}.c2g-stepper__marker{display:inline-flex;align-items:center;justify-content:center;width:40px;height:40px;border-radius:50%;border:2px solid var(--c2g-theme-outline-variant, var(--c2g-color-outline));background:var(--c2g-theme-surface, var(--c2g-color-surface));cursor:pointer;font-weight:700;font-size:.875rem;color:var(--c2g-theme-on-surface-variant, var(--c2g-color-text-secondary));transition:border-color .2s ease,background .2s ease,color .2s ease;flex-shrink:0}.c2g-stepper__marker:focus-visible{outline:2px solid var(--c2g-theme-primary, var(--c2g-color-primary));outline-offset:3px}.c2g-stepper__step--active .c2g-stepper__marker{border-color:var(--c2g-theme-primary, var(--c2g-color-primary));background:var(--c2g-theme-primary, var(--c2g-color-primary));color:var(--c2g-theme-surface, var(--c2g-color-surface))}.c2g-stepper__step--completed .c2g-stepper__marker{border-color:var(--c2g-theme-success, var(--c2g-color-success));background:var(--c2g-theme-success, var(--c2g-color-success));color:var(--c2g-theme-surface, var(--c2g-color-surface))}.c2g-stepper__step--error .c2g-stepper__marker{border-color:var(--c2g-theme-error, var(--c2g-color-error));background:var(--c2g-theme-error, var(--c2g-color-error));color:var(--c2g-theme-surface, var(--c2g-color-surface))}.c2g-stepper__label{font-weight:600;font-size:var(--c2g-font-size-sm, .875rem);color:var(--c2g-theme-on-surface-variant, var(--c2g-color-text-secondary))}.c2g-stepper__step--active .c2g-stepper__label{color:var(--c2g-theme-primary, var(--c2g-color-primary))}.c2g-stepper__step--completed .c2g-stepper__label{color:var(--c2g-theme-on-surface, var(--c2g-color-text-primary))}.c2g-stepper__description{font-size:var(--c2g-font-size-xs, .75rem);color:var(--c2g-theme-on-surface-variant, var(--c2g-color-text-muted));margin-top:2px}\n"] }]
594
+ }], propDecorators: { steps: [{ type: i0.Input, args: [{ isSignal: true, alias: "steps", required: true }] }], activeIndex: [{ type: i0.Input, args: [{ isSignal: true, alias: "activeIndex", required: false }] }, { type: i0.Output, args: ["activeIndexChange"] }], completedIndices: [{ type: i0.Input, args: [{ isSignal: true, alias: "completedIndices", required: false }] }], errorIndices: [{ type: i0.Input, args: [{ isSignal: true, alias: "errorIndices", required: false }] }], orientation: [{ type: i0.Input, args: [{ isSignal: true, alias: "orientation", required: false }] }], stepChanged: [{ type: i0.Output, args: ["stepChanged"] }] } });
595
+
596
+ class C2gKpiCardComponent {
597
+ el;
598
+ data = input.required(...(ngDevMode ? [{ debugName: "data" }] : []));
599
+ color = computed(() => this.data().color ?? 'neutral', ...(ngDevMode ? [{ debugName: "color" }] : []));
600
+ hostClass = computed(() => `c2g-kpi-card c2g-kpi-card--${this.color()}`, ...(ngDevMode ? [{ debugName: "hostClass" }] : []));
601
+ // Count-up animation
602
+ displayValue = signal('', ...(ngDevMode ? [{ debugName: "displayValue" }] : []));
603
+ countUpRaf = 0;
604
+ constructor(el) {
605
+ this.el = el;
606
+ effect(() => {
607
+ const raw = this.data().value;
608
+ this.startCountUp(raw);
609
+ });
610
+ }
611
+ startCountUp(raw) {
612
+ cancelAnimationFrame(this.countUpRaf);
613
+ const target = parseFloat(String(raw).replace(/[^0-9.-]/g, ''));
614
+ if (isNaN(target)) {
615
+ this.displayValue.set(String(raw));
616
+ return;
617
+ }
618
+ const isFloat = String(raw).includes('.');
619
+ const decimals = isFloat ? (String(raw).split('.')[1]?.length ?? 1) : 0;
620
+ const suffix = String(raw).replace(/^[0-9.,\s-]+/, '');
621
+ const prefix = String(raw).replace(/[0-9.,\s]+.*$/, '');
622
+ const duration = 900;
623
+ const start = performance.now();
624
+ const tick = (now) => {
625
+ const progress = Math.min((now - start) / duration, 1);
626
+ const ease = 1 - Math.pow(1 - progress, 3); // ease-out cubic
627
+ const current = ease * target;
628
+ const formatted = decimals > 0
629
+ ? current.toFixed(decimals)
630
+ : Math.round(current).toLocaleString('de-DE');
631
+ this.displayValue.set(`${prefix}${formatted}${suffix}`);
632
+ if (progress < 1)
633
+ this.countUpRaf = requestAnimationFrame(tick);
634
+ };
635
+ this.countUpRaf = requestAnimationFrame(tick);
636
+ }
637
+ // Sparkline SVG path
638
+ sparklinePath = computed(() => {
639
+ const pts = this.data().sparkline;
640
+ if (!pts || pts.length < 2)
641
+ return null;
642
+ const w = 80, h = 28;
643
+ const min = Math.min(...pts);
644
+ const max = Math.max(...pts);
645
+ const range = max - min || 1;
646
+ const coords = pts.map((v, i) => ({
647
+ x: (i / (pts.length - 1)) * w,
648
+ y: h - ((v - min) / range) * h,
649
+ }));
650
+ // Smooth bezier
651
+ const d = coords.reduce((acc, p, i) => {
652
+ if (i === 0)
653
+ return `M ${p.x} ${p.y}`;
654
+ const prev = coords[i - 1];
655
+ const cpx = (prev.x + p.x) / 2;
656
+ return `${acc} C ${cpx} ${prev.y} ${cpx} ${p.y} ${p.x} ${p.y}`;
657
+ }, '');
658
+ // Area fill path
659
+ const area = `${d} L ${coords[coords.length - 1].x} ${h} L 0 ${h} Z`;
660
+ return { line: d, area, lastX: coords[coords.length - 1].x, lastY: coords[coords.length - 1].y };
661
+ }, ...(ngDevMode ? [{ debugName: "sparklinePath" }] : []));
662
+ // 3D tilt
663
+ tilt = signal({ x: 0, y: 0 }, ...(ngDevMode ? [{ debugName: "tilt" }] : []));
664
+ onMouseMove(e) {
665
+ const rect = this.el.nativeElement.getBoundingClientRect();
666
+ const cx = rect.left + rect.width / 2;
667
+ const cy = rect.top + rect.height / 2;
668
+ const maxTilt = 6;
669
+ this.tilt.set({
670
+ x: ((e.clientY - cy) / (rect.height / 2)) * -maxTilt,
671
+ y: ((e.clientX - cx) / (rect.width / 2)) * maxTilt,
672
+ });
673
+ }
674
+ onMouseLeave() {
675
+ this.tilt.set({ x: 0, y: 0 });
676
+ }
677
+ tiltStyle = computed(() => {
678
+ const { x, y } = this.tilt();
679
+ return `perspective(600px) rotateX(${x}deg) rotateY(${y}deg) translateZ(0)`;
680
+ }, ...(ngDevMode ? [{ debugName: "tiltStyle" }] : []));
681
+ trendArrow = computed(() => {
682
+ const t = this.data().trend;
683
+ if (t === 'up')
684
+ return '↑';
685
+ if (t === 'down')
686
+ return '↓';
687
+ return '→';
688
+ }, ...(ngDevMode ? [{ debugName: "trendArrow" }] : []));
689
+ ngOnDestroy() {
690
+ cancelAnimationFrame(this.countUpRaf);
691
+ }
692
+ static ɵfac = i0.ɵɵngDeclareFactory({ minVersion: "12.0.0", version: "20.3.19", ngImport: i0, type: C2gKpiCardComponent, deps: [{ token: i0.ElementRef }], target: i0.ɵɵFactoryTarget.Component });
693
+ static ɵcmp = i0.ɵɵngDeclareComponent({ minVersion: "17.0.0", version: "20.3.19", type: C2gKpiCardComponent, isStandalone: true, selector: "c2g-kpi-card", inputs: { data: { classPropertyName: "data", publicName: "data", isSignal: true, isRequired: true, transformFunction: null } }, host: { listeners: { "mousemove": "onMouseMove($event)", "mouseleave": "onMouseLeave()" }, properties: { "class": "hostClass()" } }, ngImport: i0, template: "<div class=\"c2g-kpi-card__inner\" [style.transform]=\"tiltStyle()\">\n\n <!-- Glassmorphism icon orb -->\n @if (data().icon) {\n <div class=\"c2g-kpi-card__orb\" aria-hidden=\"true\">\n <span class=\"c2g-kpi-card__orb-icon\">{{ data().icon }}</span>\n </div>\n }\n\n <!-- Decorative blob -->\n <div class=\"c2g-kpi-card__blob\" aria-hidden=\"true\"></div>\n\n <!-- Label -->\n <p class=\"c2g-kpi-card__label\">{{ data().label }}</p>\n\n <!-- Main value -->\n <div class=\"c2g-kpi-card__value-row\">\n <span class=\"c2g-kpi-card__value\">{{ displayValue() }}</span>\n @if (data().unit) {\n <span class=\"c2g-kpi-card__unit\">{{ data().unit }}</span>\n }\n </div>\n\n <!-- Sparkline -->\n @if (sparklinePath(); as sp) {\n <div class=\"c2g-kpi-card__sparkline\" aria-hidden=\"true\">\n <svg viewBox=\"0 0 80 28\" preserveAspectRatio=\"none\" width=\"100%\" height=\"28\">\n <defs>\n <linearGradient [id]=\"'spark-grad-' + color()\" x1=\"0\" y1=\"0\" x2=\"0\" y2=\"1\">\n <stop offset=\"0%\" class=\"c2g-kpi-card__spark-stop-top\" />\n <stop offset=\"100%\" class=\"c2g-kpi-card__spark-stop-bottom\" />\n </linearGradient>\n </defs>\n <path class=\"c2g-kpi-card__spark-area\"\n [attr.d]=\"sp.area\"\n [attr.fill]=\"'url(#spark-grad-' + color() + ')'\" />\n <path class=\"c2g-kpi-card__spark-line\" [attr.d]=\"sp.line\" fill=\"none\" />\n <!-- Dot at latest value -->\n <circle class=\"c2g-kpi-card__spark-dot\"\n [attr.cx]=\"sp.lastX\" [attr.cy]=\"sp.lastY\" r=\"2.5\" />\n </svg>\n </div>\n }\n\n <!-- Trend footer -->\n @if (data().trend || data().change !== undefined) {\n <div class=\"c2g-kpi-card__footer\"\n [class.c2g-kpi-card__footer--up]=\"data().trend === 'up'\"\n [class.c2g-kpi-card__footer--down]=\"data().trend === 'down'\">\n <span class=\"c2g-kpi-card__arrow\">{{ trendArrow() }}</span>\n @if (data().change !== undefined) {\n <span class=\"c2g-kpi-card__change\">{{ data().change }}</span>\n }\n @if (data().changeLabel) {\n <span class=\"c2g-kpi-card__change-label\">{{ data().changeLabel }}</span>\n }\n </div>\n }\n\n</div>\n", styles: [":host{display:block;border-radius:var(--c2g-radius-xl, 20px);position:relative;isolation:isolate;cursor:default;font-family:var(--c2g-font-family-base, \"Quicksand\", sans-serif);will-change:transform}:host.c2g-kpi-card--primary{background:linear-gradient(145deg,#ff6b35,#e03e1a);box-shadow:0 4px 24px #ff6b3559,0 1px #ffffff1f inset}:host.c2g-kpi-card--primary:hover{box-shadow:0 8px 40px #ff6b358c,0 1px #ffffff29 inset}:host.c2g-kpi-card--primary .c2g-kpi-card__orb{background:#ff6b352e}:host.c2g-kpi-card--primary .c2g-kpi-card__spark-line{stroke:#ffffffe6}:host.c2g-kpi-card--primary .c2g-kpi-card__spark-dot{fill:#fff}:host.c2g-kpi-card--primary .c2g-kpi-card__spark-stop-top{stop-color:#ffffff4d}:host.c2g-kpi-card--primary .c2g-kpi-card__spark-stop-bottom{stop-color:#fff0}:host.c2g-kpi-card--success{background:linear-gradient(145deg,#22c55e,#16a34a);box-shadow:0 4px 24px #22c55e4d,0 1px #ffffff1f inset}:host.c2g-kpi-card--success:hover{box-shadow:0 8px 40px #22c55e80,0 1px #ffffff29 inset}:host.c2g-kpi-card--success .c2g-kpi-card__orb{background:#22c55e26}:host.c2g-kpi-card--success .c2g-kpi-card__spark-line{stroke:#ffffffe6}:host.c2g-kpi-card--success .c2g-kpi-card__spark-dot{fill:#fff}:host.c2g-kpi-card--success .c2g-kpi-card__spark-stop-top{stop-color:#ffffff4d}:host.c2g-kpi-card--success .c2g-kpi-card__spark-stop-bottom{stop-color:#fff0}:host.c2g-kpi-card--warning{background:linear-gradient(145deg,#f59e0b,#d97706);box-shadow:0 4px 24px #f59e0b4d,0 1px #ffffff1f inset}:host.c2g-kpi-card--warning:hover{box-shadow:0 8px 40px #f59e0b80,0 1px #ffffff29 inset}:host.c2g-kpi-card--warning .c2g-kpi-card__orb{background:#f59e0b26}:host.c2g-kpi-card--warning .c2g-kpi-card__spark-line{stroke:#ffffffe6}:host.c2g-kpi-card--warning .c2g-kpi-card__spark-dot{fill:#fff}:host.c2g-kpi-card--warning .c2g-kpi-card__spark-stop-top{stop-color:#ffffff4d}:host.c2g-kpi-card--warning .c2g-kpi-card__spark-stop-bottom{stop-color:#fff0}:host.c2g-kpi-card--danger{background:linear-gradient(145deg,#ef4444,#dc2626);box-shadow:0 4px 24px #ef44444d,0 1px #ffffff1f inset}:host.c2g-kpi-card--danger:hover{box-shadow:0 8px 40px #ef444480,0 1px #ffffff29 inset}:host.c2g-kpi-card--danger .c2g-kpi-card__orb{background:#ef444426}:host.c2g-kpi-card--danger .c2g-kpi-card__spark-line{stroke:#ffffffe6}:host.c2g-kpi-card--danger .c2g-kpi-card__spark-dot{fill:#fff}:host.c2g-kpi-card--danger .c2g-kpi-card__spark-stop-top{stop-color:#ffffff4d}:host.c2g-kpi-card--danger .c2g-kpi-card__spark-stop-bottom{stop-color:#fff0}:host.c2g-kpi-card--neutral{background:linear-gradient(145deg,#6b7280,#4b5563);box-shadow:0 4px 24px #6b728033,0 1px #ffffff1f inset}:host.c2g-kpi-card--neutral:hover{box-shadow:0 8px 40px #6b728066,0 1px #ffffff29 inset}:host.c2g-kpi-card--neutral .c2g-kpi-card__orb{background:#6b72801f}:host.c2g-kpi-card--neutral .c2g-kpi-card__spark-line{stroke:#ffffffe6}:host.c2g-kpi-card--neutral .c2g-kpi-card__spark-dot{fill:#fff}:host.c2g-kpi-card--neutral .c2g-kpi-card__spark-stop-top{stop-color:#ffffff4d}:host.c2g-kpi-card--neutral .c2g-kpi-card__spark-stop-bottom{stop-color:#fff0}.c2g-kpi-card__inner{position:relative;padding:22px 22px 18px;border-radius:inherit;transition:transform .12s ease-out;overflow:hidden;color:#fff;min-height:148px;display:flex;flex-direction:column;gap:4px}.c2g-kpi-card__blob{pointer-events:none;position:absolute;top:-48px;right:-48px;width:180px;height:180px;border-radius:50%;background:#ffffff14;animation:c2g-kpi-breathe 4s ease-in-out infinite;z-index:0}.c2g-kpi-card__blob:after{content:\"\";position:absolute;bottom:-60px;left:-30px;width:120px;height:120px;border-radius:50%;background:#ffffff0d}@keyframes c2g-kpi-breathe{0%,to{transform:scale(1) translateY(0)}50%{transform:scale(1.08) translateY(-8px)}}.c2g-kpi-card__orb{position:absolute;top:18px;right:18px;width:44px;height:44px;border-radius:14px;display:flex;align-items:center;justify-content:center;-webkit-backdrop-filter:blur(8px);backdrop-filter:blur(8px);border:1px solid rgba(255,255,255,.2);z-index:1;transition:transform .2s ease}:host:hover .c2g-kpi-card__orb{transform:scale(1.1) rotate(-4deg)}.c2g-kpi-card__orb-icon{font-size:1.375rem;line-height:1;filter:drop-shadow(0 1px 4px rgba(0,0,0,.25))}.c2g-kpi-card__label{margin:0;font-size:.72rem;font-weight:700;text-transform:uppercase;letter-spacing:.1em;opacity:.75;position:relative;z-index:1}.c2g-kpi-card__value-row{display:flex;align-items:baseline;gap:5px;position:relative;z-index:1;margin-top:4px}.c2g-kpi-card__value{font-size:2.6rem;font-weight:900;line-height:1;letter-spacing:-.02em;text-shadow:0 2px 12px rgba(0,0,0,.2)}.c2g-kpi-card__unit{font-size:1.1rem;font-weight:600;opacity:.7;margin-bottom:2px}.c2g-kpi-card__sparkline{position:relative;z-index:1;margin-top:auto;padding-top:8px}.c2g-kpi-card__sparkline svg{display:block;overflow:visible}.c2g-kpi-card__spark-line{stroke-width:1.5;stroke-linecap:round;stroke-linejoin:round}.c2g-kpi-card__spark-dot{filter:drop-shadow(0 0 3px rgba(255,255,255,.8))}.c2g-kpi-card__footer{display:flex;align-items:center;gap:4px;font-size:.75rem;font-weight:600;opacity:.85;position:relative;z-index:1;margin-top:6px}.c2g-kpi-card__footer--up,.c2g-kpi-card__footer--down{opacity:1}.c2g-kpi-card__arrow{font-size:.9rem}.c2g-kpi-card__change{font-weight:800}.c2g-kpi-card__change-label{opacity:.7;font-weight:500}\n"], changeDetection: i0.ChangeDetectionStrategy.OnPush });
694
+ }
695
+ i0.ɵɵngDeclareClassMetadata({ minVersion: "12.0.0", version: "20.3.19", ngImport: i0, type: C2gKpiCardComponent, decorators: [{
696
+ type: Component,
697
+ args: [{ selector: 'c2g-kpi-card', standalone: true, imports: [], changeDetection: ChangeDetectionStrategy.OnPush, host: {
698
+ '[class]': 'hostClass()',
699
+ '(mousemove)': 'onMouseMove($event)',
700
+ '(mouseleave)': 'onMouseLeave()',
701
+ }, template: "<div class=\"c2g-kpi-card__inner\" [style.transform]=\"tiltStyle()\">\n\n <!-- Glassmorphism icon orb -->\n @if (data().icon) {\n <div class=\"c2g-kpi-card__orb\" aria-hidden=\"true\">\n <span class=\"c2g-kpi-card__orb-icon\">{{ data().icon }}</span>\n </div>\n }\n\n <!-- Decorative blob -->\n <div class=\"c2g-kpi-card__blob\" aria-hidden=\"true\"></div>\n\n <!-- Label -->\n <p class=\"c2g-kpi-card__label\">{{ data().label }}</p>\n\n <!-- Main value -->\n <div class=\"c2g-kpi-card__value-row\">\n <span class=\"c2g-kpi-card__value\">{{ displayValue() }}</span>\n @if (data().unit) {\n <span class=\"c2g-kpi-card__unit\">{{ data().unit }}</span>\n }\n </div>\n\n <!-- Sparkline -->\n @if (sparklinePath(); as sp) {\n <div class=\"c2g-kpi-card__sparkline\" aria-hidden=\"true\">\n <svg viewBox=\"0 0 80 28\" preserveAspectRatio=\"none\" width=\"100%\" height=\"28\">\n <defs>\n <linearGradient [id]=\"'spark-grad-' + color()\" x1=\"0\" y1=\"0\" x2=\"0\" y2=\"1\">\n <stop offset=\"0%\" class=\"c2g-kpi-card__spark-stop-top\" />\n <stop offset=\"100%\" class=\"c2g-kpi-card__spark-stop-bottom\" />\n </linearGradient>\n </defs>\n <path class=\"c2g-kpi-card__spark-area\"\n [attr.d]=\"sp.area\"\n [attr.fill]=\"'url(#spark-grad-' + color() + ')'\" />\n <path class=\"c2g-kpi-card__spark-line\" [attr.d]=\"sp.line\" fill=\"none\" />\n <!-- Dot at latest value -->\n <circle class=\"c2g-kpi-card__spark-dot\"\n [attr.cx]=\"sp.lastX\" [attr.cy]=\"sp.lastY\" r=\"2.5\" />\n </svg>\n </div>\n }\n\n <!-- Trend footer -->\n @if (data().trend || data().change !== undefined) {\n <div class=\"c2g-kpi-card__footer\"\n [class.c2g-kpi-card__footer--up]=\"data().trend === 'up'\"\n [class.c2g-kpi-card__footer--down]=\"data().trend === 'down'\">\n <span class=\"c2g-kpi-card__arrow\">{{ trendArrow() }}</span>\n @if (data().change !== undefined) {\n <span class=\"c2g-kpi-card__change\">{{ data().change }}</span>\n }\n @if (data().changeLabel) {\n <span class=\"c2g-kpi-card__change-label\">{{ data().changeLabel }}</span>\n }\n </div>\n }\n\n</div>\n", styles: [":host{display:block;border-radius:var(--c2g-radius-xl, 20px);position:relative;isolation:isolate;cursor:default;font-family:var(--c2g-font-family-base, \"Quicksand\", sans-serif);will-change:transform}:host.c2g-kpi-card--primary{background:linear-gradient(145deg,#ff6b35,#e03e1a);box-shadow:0 4px 24px #ff6b3559,0 1px #ffffff1f inset}:host.c2g-kpi-card--primary:hover{box-shadow:0 8px 40px #ff6b358c,0 1px #ffffff29 inset}:host.c2g-kpi-card--primary .c2g-kpi-card__orb{background:#ff6b352e}:host.c2g-kpi-card--primary .c2g-kpi-card__spark-line{stroke:#ffffffe6}:host.c2g-kpi-card--primary .c2g-kpi-card__spark-dot{fill:#fff}:host.c2g-kpi-card--primary .c2g-kpi-card__spark-stop-top{stop-color:#ffffff4d}:host.c2g-kpi-card--primary .c2g-kpi-card__spark-stop-bottom{stop-color:#fff0}:host.c2g-kpi-card--success{background:linear-gradient(145deg,#22c55e,#16a34a);box-shadow:0 4px 24px #22c55e4d,0 1px #ffffff1f inset}:host.c2g-kpi-card--success:hover{box-shadow:0 8px 40px #22c55e80,0 1px #ffffff29 inset}:host.c2g-kpi-card--success .c2g-kpi-card__orb{background:#22c55e26}:host.c2g-kpi-card--success .c2g-kpi-card__spark-line{stroke:#ffffffe6}:host.c2g-kpi-card--success .c2g-kpi-card__spark-dot{fill:#fff}:host.c2g-kpi-card--success .c2g-kpi-card__spark-stop-top{stop-color:#ffffff4d}:host.c2g-kpi-card--success .c2g-kpi-card__spark-stop-bottom{stop-color:#fff0}:host.c2g-kpi-card--warning{background:linear-gradient(145deg,#f59e0b,#d97706);box-shadow:0 4px 24px #f59e0b4d,0 1px #ffffff1f inset}:host.c2g-kpi-card--warning:hover{box-shadow:0 8px 40px #f59e0b80,0 1px #ffffff29 inset}:host.c2g-kpi-card--warning .c2g-kpi-card__orb{background:#f59e0b26}:host.c2g-kpi-card--warning .c2g-kpi-card__spark-line{stroke:#ffffffe6}:host.c2g-kpi-card--warning .c2g-kpi-card__spark-dot{fill:#fff}:host.c2g-kpi-card--warning .c2g-kpi-card__spark-stop-top{stop-color:#ffffff4d}:host.c2g-kpi-card--warning .c2g-kpi-card__spark-stop-bottom{stop-color:#fff0}:host.c2g-kpi-card--danger{background:linear-gradient(145deg,#ef4444,#dc2626);box-shadow:0 4px 24px #ef44444d,0 1px #ffffff1f inset}:host.c2g-kpi-card--danger:hover{box-shadow:0 8px 40px #ef444480,0 1px #ffffff29 inset}:host.c2g-kpi-card--danger .c2g-kpi-card__orb{background:#ef444426}:host.c2g-kpi-card--danger .c2g-kpi-card__spark-line{stroke:#ffffffe6}:host.c2g-kpi-card--danger .c2g-kpi-card__spark-dot{fill:#fff}:host.c2g-kpi-card--danger .c2g-kpi-card__spark-stop-top{stop-color:#ffffff4d}:host.c2g-kpi-card--danger .c2g-kpi-card__spark-stop-bottom{stop-color:#fff0}:host.c2g-kpi-card--neutral{background:linear-gradient(145deg,#6b7280,#4b5563);box-shadow:0 4px 24px #6b728033,0 1px #ffffff1f inset}:host.c2g-kpi-card--neutral:hover{box-shadow:0 8px 40px #6b728066,0 1px #ffffff29 inset}:host.c2g-kpi-card--neutral .c2g-kpi-card__orb{background:#6b72801f}:host.c2g-kpi-card--neutral .c2g-kpi-card__spark-line{stroke:#ffffffe6}:host.c2g-kpi-card--neutral .c2g-kpi-card__spark-dot{fill:#fff}:host.c2g-kpi-card--neutral .c2g-kpi-card__spark-stop-top{stop-color:#ffffff4d}:host.c2g-kpi-card--neutral .c2g-kpi-card__spark-stop-bottom{stop-color:#fff0}.c2g-kpi-card__inner{position:relative;padding:22px 22px 18px;border-radius:inherit;transition:transform .12s ease-out;overflow:hidden;color:#fff;min-height:148px;display:flex;flex-direction:column;gap:4px}.c2g-kpi-card__blob{pointer-events:none;position:absolute;top:-48px;right:-48px;width:180px;height:180px;border-radius:50%;background:#ffffff14;animation:c2g-kpi-breathe 4s ease-in-out infinite;z-index:0}.c2g-kpi-card__blob:after{content:\"\";position:absolute;bottom:-60px;left:-30px;width:120px;height:120px;border-radius:50%;background:#ffffff0d}@keyframes c2g-kpi-breathe{0%,to{transform:scale(1) translateY(0)}50%{transform:scale(1.08) translateY(-8px)}}.c2g-kpi-card__orb{position:absolute;top:18px;right:18px;width:44px;height:44px;border-radius:14px;display:flex;align-items:center;justify-content:center;-webkit-backdrop-filter:blur(8px);backdrop-filter:blur(8px);border:1px solid rgba(255,255,255,.2);z-index:1;transition:transform .2s ease}:host:hover .c2g-kpi-card__orb{transform:scale(1.1) rotate(-4deg)}.c2g-kpi-card__orb-icon{font-size:1.375rem;line-height:1;filter:drop-shadow(0 1px 4px rgba(0,0,0,.25))}.c2g-kpi-card__label{margin:0;font-size:.72rem;font-weight:700;text-transform:uppercase;letter-spacing:.1em;opacity:.75;position:relative;z-index:1}.c2g-kpi-card__value-row{display:flex;align-items:baseline;gap:5px;position:relative;z-index:1;margin-top:4px}.c2g-kpi-card__value{font-size:2.6rem;font-weight:900;line-height:1;letter-spacing:-.02em;text-shadow:0 2px 12px rgba(0,0,0,.2)}.c2g-kpi-card__unit{font-size:1.1rem;font-weight:600;opacity:.7;margin-bottom:2px}.c2g-kpi-card__sparkline{position:relative;z-index:1;margin-top:auto;padding-top:8px}.c2g-kpi-card__sparkline svg{display:block;overflow:visible}.c2g-kpi-card__spark-line{stroke-width:1.5;stroke-linecap:round;stroke-linejoin:round}.c2g-kpi-card__spark-dot{filter:drop-shadow(0 0 3px rgba(255,255,255,.8))}.c2g-kpi-card__footer{display:flex;align-items:center;gap:4px;font-size:.75rem;font-weight:600;opacity:.85;position:relative;z-index:1;margin-top:6px}.c2g-kpi-card__footer--up,.c2g-kpi-card__footer--down{opacity:1}.c2g-kpi-card__arrow{font-size:.9rem}.c2g-kpi-card__change{font-weight:800}.c2g-kpi-card__change-label{opacity:.7;font-weight:500}\n"] }]
702
+ }], ctorParameters: () => [{ type: i0.ElementRef }], propDecorators: { data: [{ type: i0.Input, args: [{ isSignal: true, alias: "data", required: true }] }] } });
703
+
704
+ class FilterBarComponent {
705
+ groups = input.required(...(ngDevMode ? [{ debugName: "groups" }] : []));
706
+ searchPlaceholder = input('Suchen...', ...(ngDevMode ? [{ debugName: "searchPlaceholder" }] : []));
707
+ showSearch = input(true, ...(ngDevMode ? [{ debugName: "showSearch" }] : []));
708
+ search = model('', ...(ngDevMode ? [{ debugName: "search" }] : []));
709
+ activeFilters = model({}, ...(ngDevMode ? [{ debugName: "activeFilters" }] : []));
710
+ filterChanged = output();
711
+ searchChanged = output();
712
+ activeCount = computed(() => Object.values(this.activeFilters()).reduce((sum, v) => sum + v.length, 0), ...(ngDevMode ? [{ debugName: "activeCount" }] : []));
713
+ hasActiveFilters = computed(() => this.activeCount() > 0, ...(ngDevMode ? [{ debugName: "hasActiveFilters" }] : []));
714
+ isSelected(groupKey, optionKey) {
715
+ return (this.activeFilters()[groupKey] ?? []).includes(optionKey);
716
+ }
717
+ toggle(groupKey, optionKey, multiple) {
718
+ const current = { ...this.activeFilters() };
719
+ const selected = current[groupKey] ?? [];
720
+ if (multiple) {
721
+ current[groupKey] = selected.includes(optionKey)
722
+ ? selected.filter(k => k !== optionKey)
723
+ : [...selected, optionKey];
724
+ }
725
+ else {
726
+ current[groupKey] = selected.includes(optionKey) ? [] : [optionKey];
727
+ }
728
+ this.activeFilters.set(current);
729
+ this.filterChanged.emit(current);
730
+ }
731
+ clearAll() {
732
+ this.activeFilters.set({});
733
+ this.search.set('');
734
+ this.filterChanged.emit({});
735
+ this.searchChanged.emit('');
736
+ }
737
+ onSearch(value) {
738
+ this.search.set(value);
739
+ this.searchChanged.emit(value);
740
+ }
741
+ static ɵfac = i0.ɵɵngDeclareFactory({ minVersion: "12.0.0", version: "20.3.19", ngImport: i0, type: FilterBarComponent, deps: [], target: i0.ɵɵFactoryTarget.Component });
742
+ static ɵcmp = i0.ɵɵngDeclareComponent({ minVersion: "17.0.0", version: "20.3.19", type: FilterBarComponent, isStandalone: true, selector: "c2g-filter-bar", inputs: { groups: { classPropertyName: "groups", publicName: "groups", isSignal: true, isRequired: true, transformFunction: null }, searchPlaceholder: { classPropertyName: "searchPlaceholder", publicName: "searchPlaceholder", isSignal: true, isRequired: false, transformFunction: null }, showSearch: { classPropertyName: "showSearch", publicName: "showSearch", isSignal: true, isRequired: false, transformFunction: null }, search: { classPropertyName: "search", publicName: "search", isSignal: true, isRequired: false, transformFunction: null }, activeFilters: { classPropertyName: "activeFilters", publicName: "activeFilters", isSignal: true, isRequired: false, transformFunction: null } }, outputs: { search: "searchChange", activeFilters: "activeFiltersChange", filterChanged: "filterChanged", searchChanged: "searchChanged" }, ngImport: i0, template: "<div class=\"c2g-filter-bar\">\n @if (showSearch()) {\n <div class=\"c2g-filter-bar__search\">\n <input\n class=\"c2g-filter-bar__search-input\"\n type=\"search\"\n [placeholder]=\"searchPlaceholder()\"\n [value]=\"search()\"\n (input)=\"onSearch($any($event.target).value)\"\n aria-label=\"Suchen\"\n />\n <span class=\"c2g-filter-bar__search-icon\" aria-hidden=\"true\">\uD83D\uDD0D</span>\n </div>\n }\n\n <div class=\"c2g-filter-bar__groups\">\n @for (group of groups(); track group.key) {\n <div class=\"c2g-filter-bar__group\">\n @if (group.label) {\n <span class=\"c2g-filter-bar__group-label\">{{ group.label }}</span>\n }\n <div class=\"c2g-filter-bar__options\" role=\"group\" [attr.aria-label]=\"group.label\">\n @for (option of group.options; track option.key) {\n <button\n class=\"c2g-filter-bar__option\"\n type=\"button\"\n [class.c2g-filter-bar__option--active]=\"isSelected(group.key, option.key)\"\n [attr.aria-pressed]=\"isSelected(group.key, option.key)\"\n (click)=\"toggle(group.key, option.key, group.multiple ?? true)\"\n >\n @if (option.icon) {\n <span class=\"c2g-filter-bar__option-icon\" aria-hidden=\"true\">{{ option.icon }}</span>\n }\n {{ option.label }}\n @if (option.count !== undefined) {\n <span class=\"c2g-filter-bar__option-count\">{{ option.count }}</span>\n }\n </button>\n }\n </div>\n </div>\n }\n </div>\n\n @if (hasActiveFilters()) {\n <button\n class=\"c2g-filter-bar__clear\"\n type=\"button\"\n (click)=\"clearAll()\"\n >\n Filter zur\u00FCcksetzen\n <span class=\"c2g-filter-bar__clear-badge\">{{ activeCount() }}</span>\n </button>\n }\n</div>\n", styles: [":host{display:block;transition:background-color var(--c2g-transition-medium, .25s ease),color var(--c2g-transition-medium, .25s ease),border-color var(--c2g-transition-medium, .25s ease)}.c2g-filter-bar{display:flex;flex-wrap:wrap;align-items:center;gap:16px;padding:12px 16px;background:var(--c2g-theme-surface-container, var(--c2g-color-bg-secondary));border:1px solid var(--c2g-theme-outline-variant, var(--c2g-color-outline));border-radius:var(--c2g-radius-md, 8px);font-family:var(--c2g-font-family-base, \"Quicksand\", sans-serif)}.c2g-filter-bar__search{position:relative;flex:0 0 auto;min-width:200px}.c2g-filter-bar__search-input{width:100%;padding:8px 36px 8px 12px;border:1px solid var(--c2g-theme-outline-variant, var(--c2g-color-outline));border-radius:var(--c2g-radius-sm, 6px);font-family:inherit;font-size:var(--c2g-font-size-sm, .875rem);background:var(--c2g-theme-surface, var(--c2g-color-surface));color:var(--c2g-theme-on-surface, var(--c2g-color-text-primary));outline:none;transition:border-color .15s ease;box-sizing:border-box}.c2g-filter-bar__search-input:focus{border-color:var(--c2g-theme-primary, var(--c2g-color-primary));box-shadow:0 0 0 3px color-mix(in srgb,var(--c2g-theme-primary, var(--c2g-color-primary)) 12%,transparent)}.c2g-filter-bar__search-input::placeholder{color:var(--c2g-theme-on-surface-variant, var(--c2g-color-text-muted))}.c2g-filter-bar__search-icon{position:absolute;right:10px;top:50%;transform:translateY(-50%);pointer-events:none;font-size:.875rem;opacity:.6}.c2g-filter-bar__groups{display:flex;flex-wrap:wrap;gap:12px;flex:1}.c2g-filter-bar__group{display:flex;align-items:center;gap:8px}.c2g-filter-bar__group-label{font-size:var(--c2g-font-size-xs, .75rem);font-weight:600;color:var(--c2g-theme-on-surface-variant, var(--c2g-color-text-muted));text-transform:uppercase;letter-spacing:.05em;white-space:nowrap}.c2g-filter-bar__options{display:flex;flex-wrap:wrap;gap:6px}.c2g-filter-bar__option{display:inline-flex;align-items:center;gap:4px;padding:5px 12px;border:1px solid var(--c2g-theme-outline-variant, var(--c2g-color-outline));border-radius:20px;background:var(--c2g-theme-surface, var(--c2g-color-surface));cursor:pointer;font-family:inherit;font-size:var(--c2g-font-size-sm, .875rem);color:var(--c2g-theme-on-surface-variant, var(--c2g-color-text-secondary));transition:border-color .15s ease,background .15s ease,color .15s ease;white-space:nowrap}.c2g-filter-bar__option:hover{border-color:var(--c2g-theme-primary, var(--c2g-color-primary));color:var(--c2g-theme-primary, var(--c2g-color-primary))}.c2g-filter-bar__option--active{border-color:var(--c2g-theme-primary, var(--c2g-color-primary));background:var(--c2g-theme-primary-container, var(--c2g-color-primary-container));color:var(--c2g-theme-primary, var(--c2g-color-primary));font-weight:600}.c2g-filter-bar__option:focus-visible{outline:2px solid var(--c2g-theme-primary, var(--c2g-color-primary));outline-offset:2px}.c2g-filter-bar__option-icon{font-size:.875rem;line-height:1}.c2g-filter-bar__option-count{font-size:.75rem;opacity:.7}.c2g-filter-bar__clear{display:inline-flex;align-items:center;gap:6px;padding:5px 12px;border:1px solid var(--c2g-theme-error, var(--c2g-color-error));border-radius:20px;background:none;cursor:pointer;font-family:inherit;font-size:var(--c2g-font-size-sm, .875rem);color:var(--c2g-theme-error, var(--c2g-color-error));transition:background .15s ease;white-space:nowrap}.c2g-filter-bar__clear:hover{background:var(--c2g-theme-error-container, #fff5f5)}.c2g-filter-bar__clear:focus-visible{outline:2px solid var(--c2g-theme-error, var(--c2g-color-error));outline-offset:2px}.c2g-filter-bar__clear-badge{display:inline-flex;align-items:center;justify-content:center;min-width:18px;height:18px;padding:0 4px;border-radius:9px;background:var(--c2g-theme-error, var(--c2g-color-error));color:var(--c2g-theme-surface, var(--c2g-color-surface));font-size:.7rem;font-weight:700}\n"], changeDetection: i0.ChangeDetectionStrategy.OnPush });
743
+ }
744
+ i0.ɵɵngDeclareClassMetadata({ minVersion: "12.0.0", version: "20.3.19", ngImport: i0, type: FilterBarComponent, decorators: [{
745
+ type: Component,
746
+ args: [{ selector: 'c2g-filter-bar', standalone: true, imports: [], changeDetection: ChangeDetectionStrategy.OnPush, template: "<div class=\"c2g-filter-bar\">\n @if (showSearch()) {\n <div class=\"c2g-filter-bar__search\">\n <input\n class=\"c2g-filter-bar__search-input\"\n type=\"search\"\n [placeholder]=\"searchPlaceholder()\"\n [value]=\"search()\"\n (input)=\"onSearch($any($event.target).value)\"\n aria-label=\"Suchen\"\n />\n <span class=\"c2g-filter-bar__search-icon\" aria-hidden=\"true\">\uD83D\uDD0D</span>\n </div>\n }\n\n <div class=\"c2g-filter-bar__groups\">\n @for (group of groups(); track group.key) {\n <div class=\"c2g-filter-bar__group\">\n @if (group.label) {\n <span class=\"c2g-filter-bar__group-label\">{{ group.label }}</span>\n }\n <div class=\"c2g-filter-bar__options\" role=\"group\" [attr.aria-label]=\"group.label\">\n @for (option of group.options; track option.key) {\n <button\n class=\"c2g-filter-bar__option\"\n type=\"button\"\n [class.c2g-filter-bar__option--active]=\"isSelected(group.key, option.key)\"\n [attr.aria-pressed]=\"isSelected(group.key, option.key)\"\n (click)=\"toggle(group.key, option.key, group.multiple ?? true)\"\n >\n @if (option.icon) {\n <span class=\"c2g-filter-bar__option-icon\" aria-hidden=\"true\">{{ option.icon }}</span>\n }\n {{ option.label }}\n @if (option.count !== undefined) {\n <span class=\"c2g-filter-bar__option-count\">{{ option.count }}</span>\n }\n </button>\n }\n </div>\n </div>\n }\n </div>\n\n @if (hasActiveFilters()) {\n <button\n class=\"c2g-filter-bar__clear\"\n type=\"button\"\n (click)=\"clearAll()\"\n >\n Filter zur\u00FCcksetzen\n <span class=\"c2g-filter-bar__clear-badge\">{{ activeCount() }}</span>\n </button>\n }\n</div>\n", styles: [":host{display:block;transition:background-color var(--c2g-transition-medium, .25s ease),color var(--c2g-transition-medium, .25s ease),border-color var(--c2g-transition-medium, .25s ease)}.c2g-filter-bar{display:flex;flex-wrap:wrap;align-items:center;gap:16px;padding:12px 16px;background:var(--c2g-theme-surface-container, var(--c2g-color-bg-secondary));border:1px solid var(--c2g-theme-outline-variant, var(--c2g-color-outline));border-radius:var(--c2g-radius-md, 8px);font-family:var(--c2g-font-family-base, \"Quicksand\", sans-serif)}.c2g-filter-bar__search{position:relative;flex:0 0 auto;min-width:200px}.c2g-filter-bar__search-input{width:100%;padding:8px 36px 8px 12px;border:1px solid var(--c2g-theme-outline-variant, var(--c2g-color-outline));border-radius:var(--c2g-radius-sm, 6px);font-family:inherit;font-size:var(--c2g-font-size-sm, .875rem);background:var(--c2g-theme-surface, var(--c2g-color-surface));color:var(--c2g-theme-on-surface, var(--c2g-color-text-primary));outline:none;transition:border-color .15s ease;box-sizing:border-box}.c2g-filter-bar__search-input:focus{border-color:var(--c2g-theme-primary, var(--c2g-color-primary));box-shadow:0 0 0 3px color-mix(in srgb,var(--c2g-theme-primary, var(--c2g-color-primary)) 12%,transparent)}.c2g-filter-bar__search-input::placeholder{color:var(--c2g-theme-on-surface-variant, var(--c2g-color-text-muted))}.c2g-filter-bar__search-icon{position:absolute;right:10px;top:50%;transform:translateY(-50%);pointer-events:none;font-size:.875rem;opacity:.6}.c2g-filter-bar__groups{display:flex;flex-wrap:wrap;gap:12px;flex:1}.c2g-filter-bar__group{display:flex;align-items:center;gap:8px}.c2g-filter-bar__group-label{font-size:var(--c2g-font-size-xs, .75rem);font-weight:600;color:var(--c2g-theme-on-surface-variant, var(--c2g-color-text-muted));text-transform:uppercase;letter-spacing:.05em;white-space:nowrap}.c2g-filter-bar__options{display:flex;flex-wrap:wrap;gap:6px}.c2g-filter-bar__option{display:inline-flex;align-items:center;gap:4px;padding:5px 12px;border:1px solid var(--c2g-theme-outline-variant, var(--c2g-color-outline));border-radius:20px;background:var(--c2g-theme-surface, var(--c2g-color-surface));cursor:pointer;font-family:inherit;font-size:var(--c2g-font-size-sm, .875rem);color:var(--c2g-theme-on-surface-variant, var(--c2g-color-text-secondary));transition:border-color .15s ease,background .15s ease,color .15s ease;white-space:nowrap}.c2g-filter-bar__option:hover{border-color:var(--c2g-theme-primary, var(--c2g-color-primary));color:var(--c2g-theme-primary, var(--c2g-color-primary))}.c2g-filter-bar__option--active{border-color:var(--c2g-theme-primary, var(--c2g-color-primary));background:var(--c2g-theme-primary-container, var(--c2g-color-primary-container));color:var(--c2g-theme-primary, var(--c2g-color-primary));font-weight:600}.c2g-filter-bar__option:focus-visible{outline:2px solid var(--c2g-theme-primary, var(--c2g-color-primary));outline-offset:2px}.c2g-filter-bar__option-icon{font-size:.875rem;line-height:1}.c2g-filter-bar__option-count{font-size:.75rem;opacity:.7}.c2g-filter-bar__clear{display:inline-flex;align-items:center;gap:6px;padding:5px 12px;border:1px solid var(--c2g-theme-error, var(--c2g-color-error));border-radius:20px;background:none;cursor:pointer;font-family:inherit;font-size:var(--c2g-font-size-sm, .875rem);color:var(--c2g-theme-error, var(--c2g-color-error));transition:background .15s ease;white-space:nowrap}.c2g-filter-bar__clear:hover{background:var(--c2g-theme-error-container, #fff5f5)}.c2g-filter-bar__clear:focus-visible{outline:2px solid var(--c2g-theme-error, var(--c2g-color-error));outline-offset:2px}.c2g-filter-bar__clear-badge{display:inline-flex;align-items:center;justify-content:center;min-width:18px;height:18px;padding:0 4px;border-radius:9px;background:var(--c2g-theme-error, var(--c2g-color-error));color:var(--c2g-theme-surface, var(--c2g-color-surface));font-size:.7rem;font-weight:700}\n"] }]
747
+ }], propDecorators: { groups: [{ type: i0.Input, args: [{ isSignal: true, alias: "groups", required: true }] }], searchPlaceholder: [{ type: i0.Input, args: [{ isSignal: true, alias: "searchPlaceholder", required: false }] }], showSearch: [{ type: i0.Input, args: [{ isSignal: true, alias: "showSearch", required: false }] }], search: [{ type: i0.Input, args: [{ isSignal: true, alias: "search", required: false }] }, { type: i0.Output, args: ["searchChange"] }], activeFilters: [{ type: i0.Input, args: [{ isSignal: true, alias: "activeFilters", required: false }] }, { type: i0.Output, args: ["activeFiltersChange"] }], filterChanged: [{ type: i0.Output, args: ["filterChanged"] }], searchChanged: [{ type: i0.Output, args: ["searchChanged"] }] } });
748
+
749
+ class SkeletonTableComponent {
750
+ rows = input(5, ...(ngDevMode ? [{ debugName: "rows" }] : []));
751
+ columns = input(4, ...(ngDevMode ? [{ debugName: "columns" }] : []));
752
+ showHeader = input(true, ...(ngDevMode ? [{ debugName: "showHeader" }] : []));
753
+ rowIndices = Array.from({ length: 10 }).map((_, i) => i);
754
+ colIndices = Array.from({ length: 10 }).map((_, i) => i);
755
+ static ɵfac = i0.ɵɵngDeclareFactory({ minVersion: "12.0.0", version: "20.3.19", ngImport: i0, type: SkeletonTableComponent, deps: [], target: i0.ɵɵFactoryTarget.Component });
756
+ static ɵcmp = i0.ɵɵngDeclareComponent({ minVersion: "17.0.0", version: "20.3.19", type: SkeletonTableComponent, isStandalone: true, selector: "c2g-skeleton-table", inputs: { rows: { classPropertyName: "rows", publicName: "rows", isSignal: true, isRequired: false, transformFunction: null }, columns: { classPropertyName: "columns", publicName: "columns", isSignal: true, isRequired: false, transformFunction: null }, showHeader: { classPropertyName: "showHeader", publicName: "showHeader", isSignal: true, isRequired: false, transformFunction: null } }, ngImport: i0, template: "<div class=\"c2g-skeleton-table\">\n <table class=\"c2g-skeleton-table__table\" aria-busy=\"true\" aria-label=\"Wird geladen...\">\n @if (showHeader()) {\n <thead class=\"c2g-skeleton-table__head\">\n <tr>\n @for (c of colIndices.slice(0, columns()); track c) {\n <th class=\"c2g-skeleton-table__th\">\n <span class=\"c2g-skeleton c2g-skeleton--header\"></span>\n </th>\n }\n </tr>\n </thead>\n }\n <tbody>\n @for (r of rowIndices.slice(0, rows()); track r) {\n <tr class=\"c2g-skeleton-table__row\">\n @for (c of colIndices.slice(0, columns()); track c; let first = $first) {\n <td class=\"c2g-skeleton-table__td\">\n <span\n class=\"c2g-skeleton\"\n [class.c2g-skeleton--wide]=\"first\"\n ></span>\n </td>\n }\n </tr>\n }\n </tbody>\n </table>\n</div>\n", styles: ["@keyframes c2g-shimmer{0%{background-position:-200% 0}to{background-position:200% 0}}:host{display:block;transition:background-color var(--c2g-transition-medium, .25s ease),color var(--c2g-transition-medium, .25s ease),border-color var(--c2g-transition-medium, .25s ease)}.c2g-skeleton-table{border:1px solid var(--c2g-theme-outline-variant, var(--c2g-color-outline));border-radius:var(--c2g-radius-md, 8px);overflow:hidden}.c2g-skeleton-table__table{width:100%;border-collapse:collapse}.c2g-skeleton-table__head{background:var(--c2g-theme-surface-container, var(--c2g-color-bg-secondary))}.c2g-skeleton-table__th,.c2g-skeleton-table__td{padding:12px 16px;border-bottom:1px solid var(--c2g-theme-outline-variant, var(--c2g-color-outline))}.c2g-skeleton-table__row:last-child .c2g-skeleton-table__td{border-bottom:none}.c2g-skeleton{display:block;height:12px;border-radius:6px;background:linear-gradient(90deg,var(--c2g-theme-surface-container-high, var(--c2g-color-bg-secondary)) 25%,var(--c2g-theme-surface-container-highest, var(--c2g-color-bg-base)) 50%,var(--c2g-theme-surface-container-high, var(--c2g-color-bg-secondary)) 75%);background-size:200% 100%;animation:c2g-shimmer 1.5s infinite linear;width:60%}.c2g-skeleton--header{height:14px;width:40%}.c2g-skeleton--wide{width:85%}\n"], changeDetection: i0.ChangeDetectionStrategy.OnPush });
757
+ }
758
+ i0.ɵɵngDeclareClassMetadata({ minVersion: "12.0.0", version: "20.3.19", ngImport: i0, type: SkeletonTableComponent, decorators: [{
759
+ type: Component,
760
+ args: [{ selector: 'c2g-skeleton-table', standalone: true, imports: [], changeDetection: ChangeDetectionStrategy.OnPush, template: "<div class=\"c2g-skeleton-table\">\n <table class=\"c2g-skeleton-table__table\" aria-busy=\"true\" aria-label=\"Wird geladen...\">\n @if (showHeader()) {\n <thead class=\"c2g-skeleton-table__head\">\n <tr>\n @for (c of colIndices.slice(0, columns()); track c) {\n <th class=\"c2g-skeleton-table__th\">\n <span class=\"c2g-skeleton c2g-skeleton--header\"></span>\n </th>\n }\n </tr>\n </thead>\n }\n <tbody>\n @for (r of rowIndices.slice(0, rows()); track r) {\n <tr class=\"c2g-skeleton-table__row\">\n @for (c of colIndices.slice(0, columns()); track c; let first = $first) {\n <td class=\"c2g-skeleton-table__td\">\n <span\n class=\"c2g-skeleton\"\n [class.c2g-skeleton--wide]=\"first\"\n ></span>\n </td>\n }\n </tr>\n }\n </tbody>\n </table>\n</div>\n", styles: ["@keyframes c2g-shimmer{0%{background-position:-200% 0}to{background-position:200% 0}}:host{display:block;transition:background-color var(--c2g-transition-medium, .25s ease),color var(--c2g-transition-medium, .25s ease),border-color var(--c2g-transition-medium, .25s ease)}.c2g-skeleton-table{border:1px solid var(--c2g-theme-outline-variant, var(--c2g-color-outline));border-radius:var(--c2g-radius-md, 8px);overflow:hidden}.c2g-skeleton-table__table{width:100%;border-collapse:collapse}.c2g-skeleton-table__head{background:var(--c2g-theme-surface-container, var(--c2g-color-bg-secondary))}.c2g-skeleton-table__th,.c2g-skeleton-table__td{padding:12px 16px;border-bottom:1px solid var(--c2g-theme-outline-variant, var(--c2g-color-outline))}.c2g-skeleton-table__row:last-child .c2g-skeleton-table__td{border-bottom:none}.c2g-skeleton{display:block;height:12px;border-radius:6px;background:linear-gradient(90deg,var(--c2g-theme-surface-container-high, var(--c2g-color-bg-secondary)) 25%,var(--c2g-theme-surface-container-highest, var(--c2g-color-bg-base)) 50%,var(--c2g-theme-surface-container-high, var(--c2g-color-bg-secondary)) 75%);background-size:200% 100%;animation:c2g-shimmer 1.5s infinite linear;width:60%}.c2g-skeleton--header{height:14px;width:40%}.c2g-skeleton--wide{width:85%}\n"] }]
761
+ }], propDecorators: { rows: [{ type: i0.Input, args: [{ isSignal: true, alias: "rows", required: false }] }], columns: [{ type: i0.Input, args: [{ isSignal: true, alias: "columns", required: false }] }], showHeader: [{ type: i0.Input, args: [{ isSignal: true, alias: "showHeader", required: false }] }] } });
762
+
763
+ /**
764
+ * Generated bundle index. Do not edit.
765
+ */
766
+
767
+ export { ActionCardComponent, BreadcrumbComponent, C2gKpiCardComponent, ContentPanelComponent, CoverageKpiComponent, DangerZoneComponent, DangerZoneItemComponent, EmptyStateComponent, FilterBarComponent, HeroComponent, KpiCardComponent, ListItemComponent, PaginationComponent, SearchInputComponent, SegmentedToggleComponent, SkeletonTableComponent, StatCardComponent, StepperComponent, TableComponent, TabsComponent, ViewToggleComponent };
768
+ //# sourceMappingURL=camp2gether-c2g-ui-layout.mjs.map