@compsych-ui-components/angular 7.0.37 → 7.0.39
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.
- package/esm2022/index.js.map +1 -1
- package/esm2022/lib/card-base/card.js +44 -16
- package/esm2022/lib/card-base/card.js.map +1 -1
- package/index.d.ts +1 -1
- package/lib/card-base/card.d.ts +46 -12
- package/package.json +1 -1
package/esm2022/index.js.map
CHANGED
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"index.js","sourceRoot":"","sources":["../../../../packages/angular/src/index.ts"],"names":[],"mappings":"AAAA,OAAO,EAAE,QAAQ,EAAE,MAAM,eAAe,CAAC;AACzC,OAAO,EAAE,eAAe,EAAE,MAAM,qBAAqB,CAAC;AACtD,OAAO,EAAE,kBAAkB,EAAE,MAAM,2BAA2B,CAAC;AAC/D,OAAO,EAAE,eAAe,EAAE,MAAM,qBAAqB,CAAC;AACtD,OAAO,EAAE,kBAAkB,EAAE,MAAM,6BAA6B,CAAC;AACjE,OAAO,EAAE,gBAAgB,EAAE,MAAM,uBAAuB,CAAC;AACzD,OAAO,EAAE,aAAa,EAAE,MAAM,sBAAsB,CAAC;AACrD,OAAO,EAAE,kBAAkB,EAAE,MAAM,6BAA6B,CAAC;AACjE,OAAO,EAAE,eAAe,EAAE,MAAM,qBAAqB,CAAC;AACtD,OAAO,EAAE,iBAAiB,EAAE,MAAM,yBAAyB,CAAC;;AAE5D,OAAO,EAAE,eAAe,EAAE,MAAM,qBAAqB,CAAC;AAEtD,OAAO,EAAE,kBAAkB,EAAE,MAAM,2BAA2B,CAAC;AAE/D,OAAO,EAAE,eAAe,EAAE,MAAM,qBAAqB,CAAC;AAEtD,OAAO,EAAE,kBAAkB,EAAE,MAAM,6BAA6B,CAAC;AAEjE,OAAO,EAAE,gBAAgB,EAAE,MAAM,uBAAuB,CAAC;AAEzD,OAAO,EAAE,aAAa,EAAE,MAAM,sBAAsB,CAAC;AAErD,OAAO,EAAE,eAAe,EAAE,MAAM,kCAAkC,CAAC;AACnE,OAAO,EAAE,kBAAkB,EAAE,MAAM,6BAA6B,CAAC;AAEjE,OAAO,EAAE,eAAe,EAAE,MAAM,qBAAqB,CAAC;AAGtD,OAAO,EAAE,aAAa,EAAE,MAAM,6BAA6B,CAAC;AAE5D,OAAO,EAAE,iBAAiB,EAAE,MAAM,yBAAyB,CAAC;AAC5D,+EAA+E;AAC/E,OAAO,EAAE,WAAW,EAAE,MAAM,qBAAqB,CAAC;AAClD,OAAO,EAAE,iBAAiB,EAAE,MAAM,yBAAyB,CAAC;AA2B5D,MAAM,OAAO,qBAAqB;wGAArB,qBAAqB;yGAArB,qBAAqB,YAtB9B,eAAe;YACf,kBAAkB;YAClB,eAAe;YACf,kBAAkB;YAClB,gBAAgB;YAChB,aAAa;YACb,kBAAkB;YAClB,eAAe;YACf,iBAAiB,aAGjB,eAAe;YACf,kBAAkB;YAClB,eAAe;YACf,kBAAkB;YAClB,gBAAgB;YAChB,aAAa;YACb,kBAAkB;YAClB,eAAe;YACf,iBAAiB;yGAGR,qBAAqB;;4FAArB,qBAAqB;kBAxBjC,QAAQ;mBAAC;oBACR,OAAO,EAAE;wBACP,eAAe;wBACf,kBAAkB;wBAClB,eAAe;wBACf,kBAAkB;wBAClB,gBAAgB;wBAChB,aAAa;wBACb,kBAAkB;wBAClB,eAAe;wBACf,iBAAiB;qBAClB;oBACD,OAAO,EAAE;wBACP,eAAe;wBACf,kBAAkB;wBAClB,eAAe;wBACf,kBAAkB;wBAClB,gBAAgB;wBAChB,aAAa;wBACb,kBAAkB;wBAClB,eAAe;wBACf,iBAAiB;qBAClB;iBACF","sourcesContent":["import { NgModule } from '@angular/core';\r\nimport { ButtonComponent } from './lib/button/button';\r\nimport { AccordionComponent } from './lib/accordion/accordion';\r\nimport { FooterComponent } from './lib/footer/footer';\r\nimport { HeaderNavComponent } from './lib/header-nav/header-nav';\r\nimport { SidebarComponent } from './lib/sidebar/sidebar';\r\nimport { CardComponent } from './lib/card-base/card';\r\nimport { TextInputComponent } from './lib/text-input/text-input';\r\nimport { DialogComponent } from './lib/dialog/dialog';\r\nimport { DropdownComponent } from './lib/dropdown/dropdown';\r\n\r\nexport { ButtonComponent } from './lib/button/button';\r\nexport type { ButtonVariant, ButtonSize, ButtonType } from './lib/button/button';\r\nexport { AccordionComponent } from './lib/accordion/accordion';\r\nexport type { AccordionItem, AccordionButton, AccordionVariant, NestedAccordionItem } from './lib/accordion/accordion-types';\r\nexport { FooterComponent } from './lib/footer/footer';\r\nexport type { FooterLink } from './lib/footer/footer';\r\nexport { HeaderNavComponent } from './lib/header-nav/header-nav';\r\nexport type { HeaderNavLevel, NavAction } from './lib/header-nav/header-nav';\r\nexport { SidebarComponent } from './lib/sidebar/sidebar';\r\nexport type { SidebarItem } from './lib/sidebar/sidebar';\r\nexport { CardComponent } from './lib/card-base/card';\r\nexport type { CardVariant, CardAppearance, CardRadius, CardPadding, CardOrientation, CardSize, CardHeadingLevel, CardCategoryStyle, CardIconStyle } from './lib/card-base/card';\r\nexport { RippleDirective } from './lib/card-base/ripple.directive';\r\nexport { TextInputComponent } from './lib/text-input/text-input';\r\nexport type { TextInputSize, TextInputType, TextInputLabelButton } from './lib/text-input/text-input';\r\nexport { DialogComponent } from './lib/dialog/dialog';\r\nexport type { DialogCloseReason } from './lib/dialog/dialog';\r\nexport type { DialogVariant } from './lib/dialog/dialog-types';\r\nexport { DialogService } from './lib/dialog/dialog.service';\r\nexport type { CompsychDialogConfig } from './lib/dialog/dialog.service';\r\nexport { CompsychDialogRef } from './lib/dialog/dialog-ref';\r\n// Re-exported from CDK so opened content components can inject the data token.\r\nexport { DIALOG_DATA } from '@angular/cdk/dialog';\r\nexport { DropdownComponent } from './lib/dropdown/dropdown';\r\nexport type { DropdownSize, DropdownOption } from './lib/dropdown/dropdown-types';\r\n\r\n@NgModule({\r\n imports: [\r\n ButtonComponent,\r\n AccordionComponent,\r\n FooterComponent,\r\n HeaderNavComponent,\r\n SidebarComponent,\r\n CardComponent,\r\n TextInputComponent,\r\n DialogComponent,\r\n DropdownComponent,\r\n ],\r\n exports: [\r\n ButtonComponent,\r\n AccordionComponent,\r\n FooterComponent,\r\n HeaderNavComponent,\r\n SidebarComponent,\r\n CardComponent,\r\n TextInputComponent,\r\n DialogComponent,\r\n DropdownComponent,\r\n ],\r\n})\r\nexport class CompsychAngularModule {}\r\n"]}
|
|
1
|
+
{"version":3,"file":"index.js","sourceRoot":"","sources":["../../../../packages/angular/src/index.ts"],"names":[],"mappings":"AAAA,OAAO,EAAE,QAAQ,EAAE,MAAM,eAAe,CAAC;AACzC,OAAO,EAAE,eAAe,EAAE,MAAM,qBAAqB,CAAC;AACtD,OAAO,EAAE,kBAAkB,EAAE,MAAM,2BAA2B,CAAC;AAC/D,OAAO,EAAE,eAAe,EAAE,MAAM,qBAAqB,CAAC;AACtD,OAAO,EAAE,kBAAkB,EAAE,MAAM,6BAA6B,CAAC;AACjE,OAAO,EAAE,gBAAgB,EAAE,MAAM,uBAAuB,CAAC;AACzD,OAAO,EAAE,aAAa,EAAE,MAAM,sBAAsB,CAAC;AACrD,OAAO,EAAE,kBAAkB,EAAE,MAAM,6BAA6B,CAAC;AACjE,OAAO,EAAE,eAAe,EAAE,MAAM,qBAAqB,CAAC;AACtD,OAAO,EAAE,iBAAiB,EAAE,MAAM,yBAAyB,CAAC;;AAE5D,OAAO,EAAE,eAAe,EAAE,MAAM,qBAAqB,CAAC;AAEtD,OAAO,EAAE,kBAAkB,EAAE,MAAM,2BAA2B,CAAC;AAE/D,OAAO,EAAE,eAAe,EAAE,MAAM,qBAAqB,CAAC;AAEtD,OAAO,EAAE,kBAAkB,EAAE,MAAM,6BAA6B,CAAC;AAEjE,OAAO,EAAE,gBAAgB,EAAE,MAAM,uBAAuB,CAAC;AAEzD,OAAO,EAAE,aAAa,EAAE,MAAM,sBAAsB,CAAC;AAErD,OAAO,EAAE,eAAe,EAAE,MAAM,kCAAkC,CAAC;AACnE,OAAO,EAAE,kBAAkB,EAAE,MAAM,6BAA6B,CAAC;AAEjE,OAAO,EAAE,eAAe,EAAE,MAAM,qBAAqB,CAAC;AAGtD,OAAO,EAAE,aAAa,EAAE,MAAM,6BAA6B,CAAC;AAE5D,OAAO,EAAE,iBAAiB,EAAE,MAAM,yBAAyB,CAAC;AAC5D,+EAA+E;AAC/E,OAAO,EAAE,WAAW,EAAE,MAAM,qBAAqB,CAAC;AAClD,OAAO,EAAE,iBAAiB,EAAE,MAAM,yBAAyB,CAAC;AA2B5D,MAAM,OAAO,qBAAqB;wGAArB,qBAAqB;yGAArB,qBAAqB,YAtB9B,eAAe;YACf,kBAAkB;YAClB,eAAe;YACf,kBAAkB;YAClB,gBAAgB;YAChB,aAAa;YACb,kBAAkB;YAClB,eAAe;YACf,iBAAiB,aAGjB,eAAe;YACf,kBAAkB;YAClB,eAAe;YACf,kBAAkB;YAClB,gBAAgB;YAChB,aAAa;YACb,kBAAkB;YAClB,eAAe;YACf,iBAAiB;yGAGR,qBAAqB;;4FAArB,qBAAqB;kBAxBjC,QAAQ;mBAAC;oBACR,OAAO,EAAE;wBACP,eAAe;wBACf,kBAAkB;wBAClB,eAAe;wBACf,kBAAkB;wBAClB,gBAAgB;wBAChB,aAAa;wBACb,kBAAkB;wBAClB,eAAe;wBACf,iBAAiB;qBAClB;oBACD,OAAO,EAAE;wBACP,eAAe;wBACf,kBAAkB;wBAClB,eAAe;wBACf,kBAAkB;wBAClB,gBAAgB;wBAChB,aAAa;wBACb,kBAAkB;wBAClB,eAAe;wBACf,iBAAiB;qBAClB;iBACF","sourcesContent":["import { NgModule } from '@angular/core';\r\nimport { ButtonComponent } from './lib/button/button';\r\nimport { AccordionComponent } from './lib/accordion/accordion';\r\nimport { FooterComponent } from './lib/footer/footer';\r\nimport { HeaderNavComponent } from './lib/header-nav/header-nav';\r\nimport { SidebarComponent } from './lib/sidebar/sidebar';\r\nimport { CardComponent } from './lib/card-base/card';\r\nimport { TextInputComponent } from './lib/text-input/text-input';\r\nimport { DialogComponent } from './lib/dialog/dialog';\r\nimport { DropdownComponent } from './lib/dropdown/dropdown';\r\n\r\nexport { ButtonComponent } from './lib/button/button';\r\nexport type { ButtonVariant, ButtonSize, ButtonType } from './lib/button/button';\r\nexport { AccordionComponent } from './lib/accordion/accordion';\r\nexport type { AccordionItem, AccordionButton, AccordionVariant, NestedAccordionItem } from './lib/accordion/accordion-types';\r\nexport { FooterComponent } from './lib/footer/footer';\r\nexport type { FooterLink } from './lib/footer/footer';\r\nexport { HeaderNavComponent } from './lib/header-nav/header-nav';\r\nexport type { HeaderNavLevel, NavAction } from './lib/header-nav/header-nav';\r\nexport { SidebarComponent } from './lib/sidebar/sidebar';\r\nexport type { SidebarItem } from './lib/sidebar/sidebar';\r\nexport { CardComponent } from './lib/card-base/card';\r\nexport type { CardVariant, CardAppearance, CardRadius, CardPadding, CardOrientation, CardSize, CardMetricSize, CardHeadingLevel, CardCategoryStyle, CardIconStyle, BannerMetric } from './lib/card-base/card';\r\nexport { RippleDirective } from './lib/card-base/ripple.directive';\r\nexport { TextInputComponent } from './lib/text-input/text-input';\r\nexport type { TextInputSize, TextInputType, TextInputLabelButton } from './lib/text-input/text-input';\r\nexport { DialogComponent } from './lib/dialog/dialog';\r\nexport type { DialogCloseReason } from './lib/dialog/dialog';\r\nexport type { DialogVariant } from './lib/dialog/dialog-types';\r\nexport { DialogService } from './lib/dialog/dialog.service';\r\nexport type { CompsychDialogConfig } from './lib/dialog/dialog.service';\r\nexport { CompsychDialogRef } from './lib/dialog/dialog-ref';\r\n// Re-exported from CDK so opened content components can inject the data token.\r\nexport { DIALOG_DATA } from '@angular/cdk/dialog';\r\nexport { DropdownComponent } from './lib/dropdown/dropdown';\r\nexport type { DropdownSize, DropdownOption } from './lib/dropdown/dropdown-types';\r\n\r\n@NgModule({\r\n imports: [\r\n ButtonComponent,\r\n AccordionComponent,\r\n FooterComponent,\r\n HeaderNavComponent,\r\n SidebarComponent,\r\n CardComponent,\r\n TextInputComponent,\r\n DialogComponent,\r\n DropdownComponent,\r\n ],\r\n exports: [\r\n ButtonComponent,\r\n AccordionComponent,\r\n FooterComponent,\r\n HeaderNavComponent,\r\n SidebarComponent,\r\n CardComponent,\r\n TextInputComponent,\r\n DialogComponent,\r\n DropdownComponent,\r\n ],\r\n})\r\nexport class CompsychAngularModule {}\r\n"]}
|
|
@@ -3,6 +3,7 @@ import { NgTemplateOutlet } from '@angular/common';
|
|
|
3
3
|
import { DomSanitizer } from '@angular/platform-browser';
|
|
4
4
|
import { LUCIDE_ICONS } from '@compsych-ui-components/shared/assets/lucide-icons.generated';
|
|
5
5
|
import { RippleDirective } from './ripple.directive';
|
|
6
|
+
import { ButtonComponent } from '../button/button';
|
|
6
7
|
import * as i0 from "@angular/core";
|
|
7
8
|
import * as i1 from "./ripple.directive";
|
|
8
9
|
/**
|
|
@@ -13,11 +14,11 @@ import * as i1 from "./ripple.directive";
|
|
|
13
14
|
* One component, switched by `variant` (like Accordion's `variant`):
|
|
14
15
|
* - `basic` — a bare surface; project your own content.
|
|
15
16
|
* - `content` — icon badge / image, category chip, title, subtitle, description,
|
|
16
|
-
* action pill, arrow;
|
|
17
|
+
* action pill, arrow; headline layout.
|
|
17
18
|
* - `action` — compact interactive row (icon · label/description · arrow); horizontal/vertical.
|
|
18
19
|
* - `metric` — centered value + label; `current` (selected) state.
|
|
19
20
|
*
|
|
20
|
-
* `appearance` is the orthogonal surface skin (outlined / filled / gradient /
|
|
21
|
+
* `appearance` is the orthogonal surface skin (outlined / filled / gradient / banner).
|
|
21
22
|
* When `interactive`, the whole card is a button (role/tabindex/keyboard) with the
|
|
22
23
|
* hover / focus / pressed ripple. All values are sys design tokens.
|
|
23
24
|
*
|
|
@@ -44,11 +45,16 @@ export class CardComponent {
|
|
|
44
45
|
disabled = input(false, ...(ngDevMode ? [{ debugName: "disabled" }] : /* istanbul ignore next */ []));
|
|
45
46
|
/** Applies the focused (blue outline) appearance. Useful for action cards to indicate selection. */
|
|
46
47
|
selected = input(false, ...(ngDevMode ? [{ debugName: "selected" }] : /* istanbul ignore next */ []));
|
|
47
|
-
/** Background image URL for `appearance="
|
|
48
|
+
/** Background image URL for `appearance="banner"`. */
|
|
48
49
|
imageSrc = input('', ...(ngDevMode ? [{ debugName: "imageSrc" }] : /* istanbul ignore next */ []));
|
|
49
50
|
/**
|
|
50
|
-
*
|
|
51
|
-
*
|
|
51
|
+
* Hides the background image on an `appearance="banner"` card and replaces it
|
|
52
|
+
* with a `--accent-primary-sys-primary-container` solid background.
|
|
53
|
+
*/
|
|
54
|
+
hideImage = input(false, ...(ngDevMode ? [{ debugName: "hideImage" }] : /* istanbul ignore next */ []));
|
|
55
|
+
/**
|
|
56
|
+
* `background-position` for the `banner` appearance media (e.g. `'85% 0'` for an
|
|
57
|
+
* off-center image). Defaults to `'center'`.
|
|
52
58
|
*/
|
|
53
59
|
imagePosition = input('center', ...(ngDevMode ? [{ debugName: "imagePosition" }] : /* istanbul ignore next */ []));
|
|
54
60
|
// ── Content variant ─────────────────────────────────────
|
|
@@ -73,16 +79,32 @@ export class CardComponent {
|
|
|
73
79
|
subtitle = input('', ...(ngDevMode ? [{ debugName: "subtitle" }] : /* istanbul ignore next */ []));
|
|
74
80
|
/** Content/action: supporting description. */
|
|
75
81
|
description = input('', ...(ngDevMode ? [{ debugName: "description" }] : /* istanbul ignore next */ []));
|
|
76
|
-
/** Content: large
|
|
82
|
+
/** Content: large display text for the headline layout. */
|
|
77
83
|
headline = input('', ...(ngDevMode ? [{ debugName: "headline" }] : /* istanbul ignore next */ []));
|
|
84
|
+
/** Content (`appearance="banner"`): supporting text rendered below the headline, in white-80. */
|
|
85
|
+
headlineDescription = input('', ...(ngDevMode ? [{ debugName: "headlineDescription" }] : /* istanbul ignore next */ []));
|
|
86
|
+
/** Content (`appearance="banner"`): metric cards rendered in a dark row below the headline description. */
|
|
87
|
+
metrics = input([], ...(ngDevMode ? [{ debugName: "metrics" }] : /* istanbul ignore next */ []));
|
|
78
88
|
/** Content: presentational action pill label. */
|
|
79
89
|
actionLabel = input('', ...(ngDevMode ? [{ debugName: "actionLabel" }] : /* istanbul ignore next */ []));
|
|
90
|
+
/** Content: leading Lucide icon name rendered inside the action pill. */
|
|
91
|
+
actionLeadingIcon = input('', ...(ngDevMode ? [{ debugName: "actionLeadingIcon" }] : /* istanbul ignore next */ []));
|
|
92
|
+
/** Content: trailing Lucide icon name rendered inside the action pill. */
|
|
93
|
+
actionTrailingIcon = input('', ...(ngDevMode ? [{ debugName: "actionTrailingIcon" }] : /* istanbul ignore next */ []));
|
|
94
|
+
/** Content (outlined/filled): when true, replaces the full-width banner with a plain icon in the top-left corner. */
|
|
95
|
+
inlineIcon = input(false, ...(ngDevMode ? [{ debugName: "inlineIcon" }] : /* istanbul ignore next */ []));
|
|
80
96
|
/** Content: show the trailing arrow-up-right affordance. */
|
|
81
97
|
showArrow = input(true, ...(ngDevMode ? [{ debugName: "showArrow" }] : /* istanbul ignore next */ []));
|
|
82
98
|
/** Content (gradient): show the inner gradient panel background. Set to `false` to render a flat surface. */
|
|
83
99
|
showGradient = input(true, ...(ngDevMode ? [{ debugName: "showGradient" }] : /* istanbul ignore next */ []));
|
|
84
100
|
/** Content: remove the fixed min-height so the card sizes to its content. */
|
|
85
101
|
compact = input(false, ...(ngDevMode ? [{ debugName: "compact" }] : /* istanbul ignore next */ []));
|
|
102
|
+
/**
|
|
103
|
+
* Renders the card on a dark surface: background becomes
|
|
104
|
+
* `--transparent-neutral-sys-white-20` (closest token to rgba(255,255,255,0.16))
|
|
105
|
+
* and text color becomes white.
|
|
106
|
+
*/
|
|
107
|
+
darkBackground = input(false, ...(ngDevMode ? [{ debugName: "darkBackground" }] : /* istanbul ignore next */ []));
|
|
86
108
|
// ── Action variant ──────────────────────────────────────
|
|
87
109
|
/** Action/metric: primary label. */
|
|
88
110
|
label = input('', ...(ngDevMode ? [{ debugName: "label" }] : /* istanbul ignore next */ []));
|
|
@@ -93,13 +115,15 @@ export class CardComponent {
|
|
|
93
115
|
/** Action: stretch the card to 100% of its container width. */
|
|
94
116
|
fullWidth = input(false, ...(ngDevMode ? [{ debugName: "fullWidth" }] : /* istanbul ignore next */ []));
|
|
95
117
|
// ── Metric variant ──────────────────────────────────────
|
|
118
|
+
/** Metric: size variant. Defaults to `medium`. */
|
|
119
|
+
metricSize = input('medium', ...(ngDevMode ? [{ debugName: "metricSize" }] : /* istanbul ignore next */ []));
|
|
96
120
|
/** Metric: the prominent value. */
|
|
97
121
|
value = input('', ...(ngDevMode ? [{ debugName: "value" }] : /* istanbul ignore next */ []));
|
|
98
122
|
/** Metric: selected/current state (primary border + text). */
|
|
99
123
|
current = input(false, ...(ngDevMode ? [{ debugName: "current" }] : /* istanbul ignore next */ []));
|
|
100
124
|
// ── Accessibility ───────────────────────────────────────
|
|
101
125
|
/**
|
|
102
|
-
* Opts the title /
|
|
126
|
+
* Opts the title / headline / action label into a heading in the
|
|
103
127
|
* accessibility tree via `role="heading"` + `aria-level`, so consumers that
|
|
104
128
|
* replace real headings keep heading semantics and screen-reader heading
|
|
105
129
|
* navigation (WCAG 1.3.1). Omit (default) to render as plain text — no visual
|
|
@@ -115,9 +139,11 @@ export class CardComponent {
|
|
|
115
139
|
ariaLabel = input(undefined, { ...(ngDevMode ? { debugName: "ariaLabel" } : /* istanbul ignore next */ {}), alias: 'aria-label' });
|
|
116
140
|
/** Emits on click / Enter / Space when interactive and not disabled. */
|
|
117
141
|
cardClick = output();
|
|
142
|
+
/** Emits when the banner card's action button is clicked. */
|
|
143
|
+
actionClick = output();
|
|
118
144
|
sanitizer = inject(DomSanitizer);
|
|
119
145
|
ripple = inject(RippleDirective);
|
|
120
|
-
|
|
146
|
+
isBanner = computed(() => this.appearance() === 'banner', ...(ngDevMode ? [{ debugName: "isBanner" }] : /* istanbul ignore next */ []));
|
|
121
147
|
/**
|
|
122
148
|
* Heading level actually applied. Suppressed when the whole card is interactive
|
|
123
149
|
* (`role="button"`), since a heading nested in a button isn't exposed as a
|
|
@@ -137,13 +163,13 @@ export class CardComponent {
|
|
|
137
163
|
effectivePadding = computed(() => {
|
|
138
164
|
switch (this.variant()) {
|
|
139
165
|
case 'content':
|
|
140
|
-
return this.
|
|
166
|
+
return this.isBanner() ? 'none' : 'sm';
|
|
141
167
|
case 'action':
|
|
142
168
|
return 'lg'; // 24px — Figma action card (60017:8036)
|
|
143
169
|
case 'basic':
|
|
144
170
|
return 'none'; // .bc controls its own padding per style (Figma Base Card Item)
|
|
145
171
|
case 'metric':
|
|
146
|
-
return '
|
|
172
|
+
return this.metricSize() === 'small' ? 'sm' : 'lg'; // sm=16px, lg=24px
|
|
147
173
|
default:
|
|
148
174
|
return this.padding();
|
|
149
175
|
}
|
|
@@ -178,20 +204,19 @@ export class CardComponent {
|
|
|
178
204
|
return this.sanitizer.bypassSecurityTrustHtml(svg);
|
|
179
205
|
}
|
|
180
206
|
static ɵfac = i0.ɵɵngDeclareFactory({ minVersion: "12.0.0", version: "21.2.14", ngImport: i0, type: CardComponent, deps: [], target: i0.ɵɵFactoryTarget.Component });
|
|
181
|
-
static ɵcmp = i0.ɵɵngDeclareComponent({ minVersion: "17.0.0", version: "21.2.14", type: CardComponent, isStandalone: true, selector: "compsych-card", inputs: { variant: { classPropertyName: "variant", publicName: "variant", isSignal: true, isRequired: false, transformFunction: null }, appearance: { classPropertyName: "appearance", publicName: "appearance", isSignal: true, isRequired: false, transformFunction: null }, radius: { classPropertyName: "radius", publicName: "radius", isSignal: true, isRequired: false, transformFunction: null }, padding: { classPropertyName: "padding", publicName: "padding", isSignal: true, isRequired: false, transformFunction: null }, size: { classPropertyName: "size", publicName: "size", isSignal: true, isRequired: false, transformFunction: null }, interactive: { classPropertyName: "interactive", publicName: "interactive", isSignal: true, isRequired: false, transformFunction: null }, disabled: { classPropertyName: "disabled", publicName: "disabled", isSignal: true, isRequired: false, transformFunction: null }, selected: { classPropertyName: "selected", publicName: "selected", isSignal: true, isRequired: false, transformFunction: null }, imageSrc: { classPropertyName: "imageSrc", publicName: "imageSrc", isSignal: true, isRequired: false, transformFunction: null }, imagePosition: { classPropertyName: "imagePosition", publicName: "imagePosition", isSignal: true, isRequired: false, transformFunction: null }, icon: { classPropertyName: "icon", publicName: "icon", isSignal: true, isRequired: false, transformFunction: null }, category: { classPropertyName: "category", publicName: "category", isSignal: true, isRequired: false, transformFunction: null }, categoryStyle: { classPropertyName: "categoryStyle", publicName: "categoryStyle", isSignal: true, isRequired: false, transformFunction: null }, iconStyle: { classPropertyName: "iconStyle", publicName: "iconStyle", isSignal: true, isRequired: false, transformFunction: null }, title: { classPropertyName: "title", publicName: "title", isSignal: true, isRequired: false, transformFunction: null }, subtitle: { classPropertyName: "subtitle", publicName: "subtitle", isSignal: true, isRequired: false, transformFunction: null }, description: { classPropertyName: "description", publicName: "description", isSignal: true, isRequired: false, transformFunction: null }, headline: { classPropertyName: "headline", publicName: "headline", isSignal: true, isRequired: false, transformFunction: null }, actionLabel: { classPropertyName: "actionLabel", publicName: "actionLabel", isSignal: true, isRequired: false, transformFunction: null }, showArrow: { classPropertyName: "showArrow", publicName: "showArrow", isSignal: true, isRequired: false, transformFunction: null }, showGradient: { classPropertyName: "showGradient", publicName: "showGradient", isSignal: true, isRequired: false, transformFunction: null }, compact: { classPropertyName: "compact", publicName: "compact", isSignal: true, isRequired: false, transformFunction: null }, label: { classPropertyName: "label", publicName: "label", isSignal: true, isRequired: false, transformFunction: null }, trailingIcon: { classPropertyName: "trailingIcon", publicName: "trailingIcon", isSignal: true, isRequired: false, transformFunction: null }, orientation: { classPropertyName: "orientation", publicName: "orientation", isSignal: true, isRequired: false, transformFunction: null }, fullWidth: { classPropertyName: "fullWidth", publicName: "fullWidth", isSignal: true, isRequired: false, transformFunction: null }, value: { classPropertyName: "value", publicName: "value", isSignal: true, isRequired: false, transformFunction: null }, current: { classPropertyName: "current", publicName: "current", isSignal: true, isRequired: false, transformFunction: null }, headingLevel: { classPropertyName: "headingLevel", publicName: "headingLevel", isSignal: true, isRequired: false, transformFunction: null }, ariaLabel: { classPropertyName: "ariaLabel", publicName: "aria-label", isSignal: true, isRequired: false, transformFunction: null } }, outputs: { cardClick: "cardClick" }, host: { listeners: { "click": "onActivate()", "keydown": "onKeyDown($event)" }, properties: { "class.cmp-card--outlined": "appearance() === 'outlined'", "class.cmp-card--filled": "appearance() === 'filled'", "class.cmp-card--gradient": "appearance() === 'gradient'", "class.cmp-card--image": "appearance() === 'image'", "class.cmp-card--content": "variant() === 'content'", "class.cmp-card--basic": "variant() === 'basic'", "attr.data-card-size": "variant() === 'basic' ? size() : null", "class.cmp-card--hero": "variant() === 'content' && !!headline()", "class.cmp-card--metric": "variant() === 'metric'", "class.cmp-card--current": "variant() === 'metric' && current()", "class.cmp-card--radius-md": "radius() === 'md'", "class.cmp-card--radius-lg": "radius() === 'lg'", "class.cmp-card--radius-xl": "radius() === 'xl'", "class.cmp-card--pad-none": "effectivePadding() === 'none'", "class.cmp-card--pad-sm": "effectivePadding() === 'sm'", "class.cmp-card--pad-md": "effectivePadding() === 'md'", "class.cmp-card--pad-lg": "effectivePadding() === 'lg'", "class.cmp-card--pad-xl": "effectivePadding() === 'xl'", "style.width": "fullWidth() ? '100%' : null", "class.cmp-card--interactive": "interactive()", "class.cmp-card--disabled": "disabled()", "class.cmp-card--selected": "selected()", "class.cmp-card--no-gradient": "!showGradient()", "class.cmp-card--compact": "compact()", "attr.role": "interactive() ? 'button' : null", "attr.tabindex": "interactive() && !disabled() ? 0 : null", "attr.aria-label": "ariaLabel() ?? null", "attr.aria-disabled": "disabled() || null", "attr.aria-pressed": "interactive() && variant() === 'metric' ? current() : null", "style.border-color": "variant() === 'metric' && current() ? 'var(--accent-primary-sys-primary)' : null", "style.border-width": "variant() === 'metric' && current() ? 'var(--border-width-sys-stroke-thick)' : null" }, classAttribute: "cmp-card" }, hostDirectives: [{ directive: i1.RippleDirective }], ngImport: i0, template: "@if (isImage() && mediaUrl()) {\r\n <div class=\"cmp-card__media\" [style.background-image]=\"mediaUrl()\" [style.background-position]=\"imagePosition()\"></div>\r\n <div class=\"cmp-card__scrim\" aria-hidden=\"true\"></div>\r\n}\r\n\r\n<div class=\"cmp-card__body\">\r\n @switch (variant()) {\r\n @case ('content') {\r\n @if (headline()) {\r\n <!-- Hero (image/filled): icon top-left, eyebrow + display headline + action bottom. -->\r\n <div class=\"cc cc--hero\" [class.cc--image]=\"isImage()\" [class.cc--filled]=\"appearance() === 'filled'\">\r\n @if (icon()) {\r\n @if (isImage()) {\r\n <div class=\"cc__media-icon\" [innerHTML]=\"iconSvg(icon(), 48)\" aria-hidden=\"true\"></div>\r\n } @else {\r\n <div class=\"cc__icon\" [class.cc__icon--neutral]=\"iconStyle() === 'neutral'\" [innerHTML]=\"iconSvg(icon(), 24)\" aria-hidden=\"true\"></div>\r\n }\r\n }\r\n <div class=\"cc__img-foot\">\r\n <div class=\"cc__hero-text\">\r\n @if (title()) { <p class=\"cc__eyebrow\">{{ title() }}</p> }\r\n <ng-container [ngTemplateOutlet]=\"headlineTpl\" />\r\n @if (description()) { <p class=\"cc__desc\">{{ description() }}</p> }\r\n </div>\r\n @if (actionLabel()) {\r\n <span class=\"cc__button cc__button--solid\">{{ actionLabel() }}</span>\r\n } @else if (showArrow()) {\r\n <span class=\"cc__arrow\" [innerHTML]=\"iconSvg('arrow-up-right', 24)\" aria-hidden=\"true\"></span>\r\n }\r\n </div>\r\n </div>\r\n } @else if (isImage()) {\r\n <div class=\"cc cc--image\">\r\n <div class=\"cc__img-top\">\r\n @if (icon()) {\r\n <div class=\"cc__media-icon\" [innerHTML]=\"iconSvg(icon(), 48)\" aria-hidden=\"true\"></div>\r\n }\r\n @if (category()) { <span class=\"cc__chip cc__chip--glass\">{{ category() }}</span> }\r\n </div>\r\n <div class=\"cc__img-foot\">\r\n @if (title() || subtitle() || description()) {\r\n <div class=\"cc__hero-text\">\r\n @if (title() || subtitle()) {\r\n <div class=\"cc__heading\">\r\n @if (title()) { <ng-container [ngTemplateOutlet]=\"titleTpl\" /> }\r\n @if (subtitle()) { <p class=\"cc__subtitle\">{{ subtitle() }}</p> }\r\n </div>\r\n }\r\n @if (description()) { <p class=\"cc__desc\">{{ description() }}</p> }\r\n </div>\r\n }\r\n @if (actionLabel()) {\r\n <span class=\"cc__button cc__button--solid\">{{ actionLabel() }}</span>\r\n } @else if (showArrow()) {\r\n <span class=\"cc__arrow\" [innerHTML]=\"iconSvg('arrow-up-right', 24)\" aria-hidden=\"true\"></span>\r\n }\r\n </div>\r\n </div>\r\n } @else if (appearance() === 'gradient') {\r\n <div class=\"cc\" [class.cc--filled]=\"appearance() === 'filled'\">\r\n <div class=\"cc__top\" [class.cc__top--label]=\"categoryStyle() === 'label'\">\r\n @if (icon()) {\r\n <div class=\"cc__icon\" [class.cc__icon--neutral]=\"iconStyle() === 'neutral'\" [innerHTML]=\"iconSvg(icon(), 24)\" aria-hidden=\"true\"></div>\r\n }\r\n @if (categoryStyle() === 'label' && category()) {\r\n <span class=\"cc__category-label\">{{ category() }}</span>\r\n }\r\n <div class=\"cc__top-end\">\r\n @if (categoryStyle() === 'chip' && category()) { <span class=\"cc__chip\">{{ category() }}</span> }\r\n @if (showArrow()) {\r\n <span class=\"cc__arrow\" [innerHTML]=\"iconSvg('arrow-up-right', 24)\" aria-hidden=\"true\"></span>\r\n }\r\n </div>\r\n </div>\r\n <div class=\"cc__text\">\r\n @if (title() || subtitle()) {\r\n <div class=\"cc__heading\">\r\n @if (title()) { <ng-container [ngTemplateOutlet]=\"titleTpl\" /> }\r\n @if (subtitle()) { <p class=\"cc__subtitle\">{{ subtitle() }}</p> }\r\n </div>\r\n }\r\n @if (description()) { <p class=\"cc__desc\">{{ description() }}</p> }\r\n </div>\r\n @if (actionLabel()) { <span class=\"cc__button\">{{ actionLabel() }}</span> }\r\n </div>\r\n } @else {\r\n <!-- With-icon content card (Figma 59444:2263): a full-width light-blue\r\n icon banner over a gray category eyebrow + title + body, with the\r\n text distributed top/bottom. Default for outlined/filled content. -->\r\n <div class=\"cc cc--with-icon\" [class.cc--filled]=\"appearance() === 'filled'\">\r\n <div class=\"cc__banner\">\r\n @if (icon()) {\r\n <span class=\"cc__banner-icon\" [innerHTML]=\"iconSvg(icon(), 48, 1.5)\" aria-hidden=\"true\"></span>\r\n }\r\n </div>\r\n <div class=\"cc__container\">\r\n <div class=\"cc__title-group\">\r\n @if (category()) { <p class=\"cc__category-eyebrow\">{{ category() }}</p> }\r\n @if (title()) { <ng-container [ngTemplateOutlet]=\"titleTpl\" /> }\r\n </div>\r\n @if (description()) { <p class=\"cc__desc\">{{ description() }}</p> }\r\n </div>\r\n </div>\r\n }\r\n }\r\n\r\n @case ('action') {\r\n @if (orientation() === 'vertical') {\r\n <div class=\"ac ac--vertical\" [class.ac--no-desc]=\"!description()\">\r\n @if (icon()) {\r\n <div class=\"ac__badge\" [innerHTML]=\"iconSvg(icon(), 24, 1.5)\" aria-hidden=\"true\"></div>\r\n }\r\n <div class=\"ac__text\">\r\n <ng-container [ngTemplateOutlet]=\"labelTpl\" />\r\n @if (description()) { <span class=\"ac__desc\">{{ description() }}</span> }\r\n </div>\r\n </div>\r\n } @else {\r\n <div class=\"ac\" [class.ac--no-desc]=\"!description()\">\r\n @if (icon()) {\r\n <div class=\"ac__icon\" [innerHTML]=\"iconSvg(icon(), 32)\" aria-hidden=\"true\"></div>\r\n }\r\n <div class=\"ac__text\">\r\n <ng-container [ngTemplateOutlet]=\"labelTpl\" />\r\n @if (description()) { <span class=\"ac__desc\">{{ description() }}</span> }\r\n </div>\r\n </div>\r\n }\r\n }\r\n\r\n @case ('metric') {\r\n <div class=\"mc\" [class.mc--current]=\"current()\">\r\n <span class=\"mc__value\">{{ value() }}</span>\r\n @if (label()) { <span class=\"mc__label\">{{ label() }}</span> }\r\n </div>\r\n }\r\n\r\n @case ('basic') {\r\n @if (size() === 'xs') {\r\n <!-- xs base card (Figma 243:3264): compact horizontal row \u2014 icon \u00B7 title \u00B7 arrow. -->\r\n <div class=\"bc bc--row\">\r\n @if (icon()) {\r\n <div class=\"bc__icon\" [innerHTML]=\"iconSvg(icon(), 24, 1.5)\" aria-hidden=\"true\"></div>\r\n }\r\n <div class=\"bc__row-text\">\r\n @if (title()) { <ng-container [ngTemplateOutlet]=\"bcTitleTpl\" /> }\r\n </div>\r\n @if (showArrow()) {\r\n <span class=\"bc__arrow\" [innerHTML]=\"iconSvg('arrow-up-right', 20)\" aria-hidden=\"true\"></span>\r\n }\r\n </div>\r\n } @else if (size() === 'lg') {\r\n <!-- lg base card (Figma 243:3205): text + optional chip, button bottom-right. -->\r\n <div class=\"bc bc--promo\" [class.bc--image]=\"isImage()\">\r\n <div class=\"bc__text\">\r\n @if (label()) { <p class=\"bc__eyebrow\">{{ label() }}</p> }\r\n @if (title() || subtitle()) {\r\n <div class=\"bc__heading\">\r\n @if (title()) { <ng-container [ngTemplateOutlet]=\"bcTitleTpl\" /> }\r\n @if (subtitle()) { <p class=\"bc__subtitle\">{{ subtitle() }}</p> }\r\n </div>\r\n }\r\n @if (description()) { <p class=\"bc__desc\">{{ description() }}</p> }\r\n @if (category()) { <span class=\"bc__chip\">{{ category() }}</span> }\r\n </div>\r\n @if (actionLabel()) { <span class=\"bc__button bc__button--end\">{{ actionLabel() }}</span> }\r\n </div>\r\n } @else if (isImage()) {\r\n <!-- md image base card (Figma 59442:12042): text over the image, arrow bottom-right. -->\r\n <div class=\"bc bc--image\">\r\n <div class=\"bc__text\">\r\n @if (title() || subtitle()) {\r\n <div class=\"bc__heading\">\r\n @if (title()) { <ng-container [ngTemplateOutlet]=\"bcTitleTpl\" /> }\r\n @if (subtitle()) { <p class=\"bc__subtitle\">{{ subtitle() }}</p> }\r\n </div>\r\n }\r\n @if (description()) { <p class=\"bc__desc\">{{ description() }}</p> }\r\n </div>\r\n @if (showArrow()) {\r\n <span class=\"bc__arrow\" [innerHTML]=\"iconSvg('arrow-up-right', basicArrowSize())\" aria-hidden=\"true\"></span>\r\n }\r\n </div>\r\n } @else {\r\n <!-- md / sm base card (Figma 243:3174, 243:3179, 947:8067):\r\n icon + arrow row, then eyebrow / title / subtitle / description / button. -->\r\n <div class=\"bc\">\r\n <div class=\"bc__top\">\r\n @if (icon()) {\r\n @if (appearance() === 'gradient') {\r\n <div class=\"bc__icon bc__icon--badge\" [innerHTML]=\"iconSvg(icon(), 32)\" aria-hidden=\"true\"></div>\r\n } @else {\r\n <div class=\"bc__icon\" [innerHTML]=\"iconSvg(icon(), basicIconSize(), 1.5)\" aria-hidden=\"true\"></div>\r\n }\r\n }\r\n <div class=\"bc__top-end\">\r\n @if (category()) { <span class=\"bc__chip\">{{ category() }}</span> }\r\n @if (showArrow()) {\r\n <span class=\"bc__arrow\" [innerHTML]=\"iconSvg('arrow-up-right', basicArrowSize())\" aria-hidden=\"true\"></span>\r\n }\r\n </div>\r\n </div>\r\n <div class=\"bc__body\">\r\n <div class=\"bc__text\">\r\n @if (label()) { <p class=\"bc__eyebrow\">{{ label() }}</p> }\r\n @if (title() || subtitle()) {\r\n <div class=\"bc__heading\">\r\n @if (title()) { <ng-container [ngTemplateOutlet]=\"bcTitleTpl\" /> }\r\n @if (subtitle()) { <p class=\"bc__subtitle\">{{ subtitle() }}</p> }\r\n </div>\r\n }\r\n @if (description()) { <p class=\"bc__desc\">{{ description() }}</p> }\r\n </div>\r\n @if (actionLabel()) { <span class=\"bc__button\">{{ actionLabel() }}</span> }\r\n </div>\r\n </div>\r\n }\r\n }\r\n\r\n @default {\r\n <ng-content />\r\n }\r\n }\r\n</div>\r\n\r\n<!-- Heading fragments: render a real <h2>\u2013<h6> when `headingLevel` is set, else the\r\n original <p>/<span>. Shared across layouts so semantics stay consistent and the\r\n cc__title / cc__headline / ac__label styling is unchanged. -->\r\n<ng-template #titleTpl>\r\n @switch (effectiveHeadingLevel()) {\r\n @case (2) { <h2 class=\"cc__title\">{{ title() }}</h2> }\r\n @case (3) { <h3 class=\"cc__title\">{{ title() }}</h3> }\r\n @case (4) { <h4 class=\"cc__title\">{{ title() }}</h4> }\r\n @case (5) { <h5 class=\"cc__title\">{{ title() }}</h5> }\r\n @case (6) { <h6 class=\"cc__title\">{{ title() }}</h6> }\r\n @default { <p class=\"cc__title\">{{ title() }}</p> }\r\n }\r\n</ng-template>\r\n\r\n<ng-template #headlineTpl>\r\n @switch (effectiveHeadingLevel()) {\r\n @case (2) { <h2 class=\"cc__headline\">{{ headline() }}</h2> }\r\n @case (3) { <h3 class=\"cc__headline\">{{ headline() }}</h3> }\r\n @case (4) { <h4 class=\"cc__headline\">{{ headline() }}</h4> }\r\n @case (5) { <h5 class=\"cc__headline\">{{ headline() }}</h5> }\r\n @case (6) { <h6 class=\"cc__headline\">{{ headline() }}</h6> }\r\n @default { <p class=\"cc__headline\">{{ headline() }}</p> }\r\n }\r\n</ng-template>\r\n\r\n<ng-template #labelTpl>\r\n @switch (effectiveHeadingLevel()) {\r\n @case (2) { <h2 class=\"ac__label\">{{ label() }}</h2> }\r\n @case (3) { <h3 class=\"ac__label\">{{ label() }}</h3> }\r\n @case (4) { <h4 class=\"ac__label\">{{ label() }}</h4> }\r\n @case (5) { <h5 class=\"ac__label\">{{ label() }}</h5> }\r\n @case (6) { <h6 class=\"ac__label\">{{ label() }}</h6> }\r\n @default { <span class=\"ac__label\">{{ label() }}</span> }\r\n }\r\n</ng-template>\r\n\r\n<ng-template #bcTitleTpl>\r\n @switch (effectiveHeadingLevel()) {\r\n @case (2) { <h2 class=\"bc__title\">{{ title() }}</h2> }\r\n @case (3) { <h3 class=\"bc__title\">{{ title() }}</h3> }\r\n @case (4) { <h4 class=\"bc__title\">{{ title() }}</h4> }\r\n @case (5) { <h5 class=\"bc__title\">{{ title() }}</h5> }\r\n @case (6) { <h6 class=\"bc__title\">{{ title() }}</h6> }\r\n @default { <p class=\"bc__title\">{{ title() }}</p> }\r\n }\r\n</ng-template>\r\n", styles: [":host{position:relative;display:flex;flex-direction:column;box-sizing:border-box;overflow:hidden;border-radius:var(--border-radius-sys-radius-lg);background-color:var(--surface-surface-container-sys-surface-container-lowest);color:var(--surface-surface-sys-on-surface);isolation:isolate;container-type:inline-size}:host.cmp-card--radius-md{border-radius:var(--border-radius-sys-radius-md)}:host.cmp-card--radius-lg{border-radius:var(--border-radius-sys-radius-lg)}:host.cmp-card--radius-xl{border-radius:var(--border-radius-sys-radius-xl)}.cmp-card__body{position:relative;z-index:1;display:flex;flex-direction:column;flex:1 1 auto;min-height:0}:host.cmp-card--pad-none .cmp-card__body{padding:0}:host.cmp-card--pad-sm .cmp-card__body{padding:var(--spacing-padding-sys-padding-16)}:host.cmp-card--pad-md .cmp-card__body{padding:var(--spacing-padding-sys-padding-20)}:host.cmp-card--pad-lg .cmp-card__body{padding:var(--spacing-padding-sys-padding-24)}:host.cmp-card--pad-xl .cmp-card__body{padding:var(--spacing-padding-sys-padding-32)}:host.cmp-card--outlined{background-color:var(--surface-surface-container-sys-surface-container-lowest);border:var(--border-width-sys-stroke-thin) solid var(--outline-sys-outline-variant)}:host.cmp-card--filled{background-color:var(--accent-primary-sys-primary-container);color:var(--accent-primary-sys-on-primary-container)}:host.cmp-card--gradient{background-image:linear-gradient(180deg,var(--transparent-primary-sys-primary-08) 0%,var(--transparent-neutral-sys-white-10) 100%);background-color:var(--surface-surface-container-sys-surface-container-lowest);border:var(--border-width-sys-stroke-thin) solid var(--outline-sys-outline-variant)}:host.cmp-card--gradient.cmp-card--content{background-image:none;border-radius:var(--border-radius-sys-radius-xl)}:host.cmp-card--gradient.cmp-card--content .cmp-card__body{padding:var(--spacing-padding-sys-padding-8)}:host.cmp-card--gradient.cmp-card--content .cc{gap:var(--spacing-padding-sys-padding-32);padding:var(--spacing-padding-sys-padding-16);border-radius:var(--border-radius-sys-radius-lg);background-image:linear-gradient(180deg,var(--transparent-primary-sys-primary-08) 0%,var(--transparent-neutral-sys-white-10) 100%)}:host.cmp-card--gradient.cmp-card--content.cmp-card--no-gradient .cc{background-image:none}:host.cmp-card--compact .cc:not(.cc--hero):not(.cc--image){min-height:0}:host.cmp-card--gradient.cmp-card--content .cc__title{font-family:var(--label-large-sys-font-family);font-size:var(--label-large-sys-font-size);line-height:var(--label-large-sys-line-height);letter-spacing:var(--label-large-sys-tracking);font-weight:var(--label-large-sys-font-weight-emphasized)}:host.cmp-card--gradient.cmp-card--content .cc__desc{font-family:var(--body-small-sys-font-family);font-size:var(--body-small-sys-font-size);line-height:var(--body-small-sys-line-height);letter-spacing:var(--body-small-sys-tracking);font-weight:var(--body-small-sys-font-weight)}:host.cmp-card--image{color:var(--accent-primary-sys-on-primary-container);background-color:var(--surface-surface-container-sys-surface-container-high)}.cmp-card__media{position:absolute;inset:0;z-index:0;background-size:cover;background-position:center}.cmp-card__scrim{position:absolute;inset:0;z-index:0;background-image:linear-gradient(180deg,var(--transparent-neutral-sys-black-40) 0%,var(--transparent-neutral-sys-black-10) 32%,var(--transparent-neutral-sys-black-10) 64%,var(--transparent-neutral-sys-black-50) 100%);mix-blend-mode:multiply}:host.cmp-card--interactive{cursor:pointer;transition:box-shadow .14s ease-out,border-color .14s ease-out,border-width .14s ease-out}:host.cmp-card--interactive:after{content:\"\";position:absolute;inset:0;z-index:0;pointer-events:none;border-radius:inherit;background-color:var(--surface-surface-sys-on-surface);opacity:0;transition:opacity .14s ease-out}:host.cmp-card--interactive.cmp-card--filled:after,:host.cmp-card--interactive.cmp-card--image:after{background-color:var(--accent-primary-sys-on-primary)}:host.cmp-card--interactive:hover{border-color:var(--outline-sys-outline-variant);border-width:var(--border-width-sys-stroke-medium);box-shadow:0 4px 16px #0000001a,0 2px 4px #00000014}:host.cmp-card--interactive:hover:after{opacity:.08}:host.cmp-card--interactive:active:after{opacity:.1}:host.cmp-card--selected,:host.cmp-card--interactive:focus-visible{outline:none;border-color:var(--add-on-primary-fixed-sys-on-primary-fixed-variant);border-width:var(--border-width-sys-stroke-medium);box-shadow:0 0 0 var(--spacing-padding-sys-padding-4) var(--transparent-primary-sys-primary-08)}:host.cmp-card--disabled{pointer-events:none;opacity:.38}@media(prefers-reduced-motion:reduce){:host.cmp-card--interactive{transition:none}}@media(forced-colors:active){:host{border:1px solid CanvasText;forced-color-adjust:none}:host.cmp-card--interactive:focus-visible{outline:2px solid Highlight;outline-offset:2px}}.cc{display:flex;flex-direction:column;flex:1 1 auto;gap:var(--spacing-padding-sys-padding-12);font-family:var(--body-medium-sys-font-family)}.cc:not(.cc--hero):not(.cc--image){min-height:18.125rem}.cc__top{display:flex;align-items:flex-start;justify-content:space-between;gap:var(--spacing-padding-sys-padding-8)}.cc__top--label{justify-content:flex-start;align-items:center;gap:var(--spacing-padding-sys-padding-16)}.cc__category-label{background:transparent;padding:0;color:var(--accent-primary-sys-primary);font-family:var(--label-large-sys-font-family);font-size:var(--label-large-sys-font-size);line-height:var(--label-large-sys-line-height);letter-spacing:var(--label-large-sys-tracking);font-weight:var(--label-large-sys-font-weight-emphasized)}.cc__icon{display:inline-flex;align-items:center;justify-content:center;width:var(--sys-size-xl);height:var(--sys-size-xl);flex-shrink:0;border-radius:var(--border-radius-sys-radius-full);background-color:var(--accent-primary-sys-primary);color:var(--accent-primary-sys-on-primary);line-height:0}.cc__icon--neutral{background-color:var(--surface-surface-container-sys-surface-container-lowest);color:var(--surface-surface-sys-on-surface);border:var(--border-width-sys-stroke-thin) solid var(--outline-sys-outline)}.cc__banner{display:flex;align-items:center;justify-content:center;width:100%;height:120px;flex-shrink:0;overflow:hidden;border-radius:var(--border-radius-sys-radius-sm);background-color:var(--add-on-primary-fixed-sys-primary-fixed-dim);color:var(--add-on-primary-fixed-sys-on-primary-fixed)}.cc__banner-icon{display:inline-flex;line-height:0}.cc__container{display:flex;flex-direction:column;justify-content:space-between;flex:1 1 auto;gap:var(--spacing-padding-sys-padding-8);padding:var(--spacing-padding-sys-padding-8)}.cc__title-group{display:flex;flex-direction:column;gap:var(--spacing-padding-sys-padding-8)}.cc__category-eyebrow{margin:0;font-family:var(--label-medium-sys-font-family);font-size:var(--label-medium-sys-font-size);line-height:var(--label-medium-sys-line-height);letter-spacing:var(--label-medium-sys-tracking);color:var(--surface-surface-sys-on-surface-variant)}.cc--with-icon .cc__title{font-family:var(--label-large-sys-font-family);font-size:var(--label-large-sys-font-size);line-height:var(--label-large-sys-line-height);letter-spacing:var(--label-large-sys-tracking);font-weight:var(--label-large-sys-font-weight-emphasized);color:var(--surface-surface-sys-on-surface)}.cc__top-end{display:inline-flex;align-items:center;gap:var(--spacing-padding-sys-padding-8)}.cc__arrow{display:inline-flex;color:var(--surface-surface-sys-on-surface-variant);flex-shrink:0;line-height:0}.cc__text{display:flex;flex-direction:column;gap:var(--spacing-padding-sys-padding-12)}.cc__heading{display:flex;flex-direction:column;gap:var(--spacing-padding-sys-padding-4)}.cc__title{margin:0;font-family:var(--title-small-sys-font-family);font-size:var(--title-small-sys-font-size);line-height:var(--title-small-sys-line-height);font-weight:var(--title-small-sys-font-weight-emphasized);letter-spacing:var(--title-small-sys-tracking);color:var(--surface-surface-sys-on-surface);display:-webkit-box;-webkit-box-orient:vertical;-webkit-line-clamp:4;overflow:hidden}.cc__subtitle{margin:0;font-family:var(--title-small-sys-font-family);font-size:var(--title-small-sys-font-size);line-height:var(--title-small-sys-line-height);font-weight:var(--title-small-sys-font-weight-emphasized);letter-spacing:var(--title-small-sys-tracking);color:var(--surface-surface-sys-on-surface-variant)}.cc__desc{margin:0;font-family:var(--body-medium-sys-font-family);font-size:var(--body-medium-sys-font-size);line-height:var(--body-medium-sys-line-height);letter-spacing:var(--body-medium-sys-tracking);color:var(--surface-surface-sys-on-surface-variant);display:-webkit-box;-webkit-box-orient:vertical;-webkit-line-clamp:3;overflow:hidden}.cc__chip{display:inline-flex;align-items:center;padding:var(--spacing-padding-sys-padding-2) var(--spacing-padding-sys-padding-12);border-radius:var(--border-radius-sys-radius-full);background-color:var(--custom-info-sys-info-container);color:var(--custom-info-sys-on-info-container);font-family:var(--label-medium-sys-font-family);font-size:var(--label-medium-sys-font-size);line-height:var(--label-medium-sys-line-height);white-space:nowrap}.cc__chip--glass{background-color:var(--transparent-neutral-sys-white-20);color:var(--accent-primary-sys-on-primary);-webkit-backdrop-filter:blur(.375rem);backdrop-filter:blur(.375rem)}.cc__button{align-self:flex-start;display:inline-flex;align-items:center;padding:var(--spacing-padding-sys-padding-8) var(--spacing-padding-sys-padding-32);border-radius:var(--border-radius-sys-radius-full);border:var(--border-width-sys-stroke-thin) solid var(--outline-sys-outline);background-color:var(--surface-surface-container-sys-surface-container-lowest);color:var(--surface-surface-sys-on-surface);font-family:var(--label-medium-sys-font-family);font-size:var(--label-medium-sys-font-size);font-weight:var(--label-medium-sys-font-weight-emphasized);line-height:var(--label-medium-sys-line-height);white-space:nowrap}.cc--filled .cc__icon{background-color:var(--surface-surface-container-sys-surface-container-lowest);color:var(--accent-primary-sys-primary)}.cc--filled .cc__title{color:var(--accent-primary-sys-on-primary-container)}.cc--filled .cc__subtitle,.cc--filled .cc__desc,.cc--filled .cc__arrow{color:var(--accent-primary-sys-on-primary-container-variant)}.cc--filled .cc__button{border-color:transparent}.cc--image{position:relative;display:flex;flex-direction:column;flex:1 1 auto;min-height:12.5rem;justify-content:space-between;gap:var(--spacing-padding-sys-padding-24);padding:var(--spacing-padding-sys-padding-24)}:host.cmp-card--hero{border-radius:var(--border-radius-sys-radius-xl)}.cc--hero{position:relative;display:flex;flex-direction:column;flex:1 1 auto;justify-content:flex-end;gap:var(--spacing-padding-sys-padding-24);min-height:22.5rem;padding:var(--spacing-padding-sys-padding-48)}.cc__media-icon{display:inline-flex;flex-shrink:0;color:var(--accent-primary-sys-on-primary);line-height:0}.cc--hero>.cc__media-icon{margin-bottom:auto}.cc__img-top{display:flex;flex-direction:column;align-items:flex-start;gap:var(--spacing-padding-sys-padding-12)}.cc__img-foot{display:flex;align-items:flex-end;justify-content:space-between;gap:var(--spacing-padding-sys-padding-16)}.cc__img-foot--end{justify-content:flex-end}.cc__hero-text{display:flex;flex-direction:column;gap:var(--spacing-padding-sys-padding-8);min-width:0}.cc__eyebrow{margin:0;font-family:var(--title-large-sys-font-family);font-size:var(--title-large-sys-font-size);line-height:var(--title-large-sys-line-height);letter-spacing:var(--title-large-sys-tracking);color:var(--accent-primary-sys-on-primary)}.cc__headline{margin:0;font-family:var(--display-large-sys-font-family);font-size:var(--display-large-sys-font-size);line-height:var(--display-large-sys-line-height);font-weight:var(--display-large-sys-font-weight);letter-spacing:var(--display-large-sys-tracking);color:var(--accent-primary-sys-on-primary)}.cc__button--solid{align-self:flex-end;flex-shrink:0;border-color:transparent;font-family:var(--label-large-sys-font-family);font-size:var(--label-large-sys-font-size);line-height:var(--label-large-sys-line-height);font-weight:var(--label-large-sys-font-weight-emphasized);box-shadow:0 .125rem .25rem #0000000f,0 .125rem .5rem #0000000a}@container (max-width: 36rem){.cc__img-foot{flex-direction:column;align-items:flex-start}.cc__button--solid{align-self:flex-start}}.cc--image .cc__title,.cc--image .cc__arrow{color:var(--accent-primary-sys-on-primary)}.cc--image .cc__subtitle,.cc--image .cc__desc{color:var(--transparent-neutral-sys-white-80)}.ac{display:flex;flex:1 1 auto;align-items:center;gap:var(--spacing-padding-sys-padding-16);font-family:var(--body-medium-sys-font-family)}.ac__icon{display:inline-flex;align-items:center;justify-content:center;flex-shrink:0;color:var(--surface-surface-sys-on-surface);line-height:0}.ac__text{display:flex;flex-direction:column;gap:var(--spacing-padding-sys-padding-4);flex:1 1 auto;min-width:0}.ac__label{margin:0;font-family:var(--label-large-sys-font-family);font-size:var(--label-large-sys-font-size);line-height:var(--label-large-sys-line-height);font-weight:var(--label-large-sys-font-weight-emphasized);letter-spacing:var(--label-large-sys-tracking);color:var(--surface-surface-sys-on-surface)}.ac__desc{font-family:var(--body-small-sys-font-family);font-size:var(--body-small-sys-font-size);line-height:var(--body-small-sys-line-height);letter-spacing:var(--body-small-sys-tracking);color:var(--surface-surface-sys-on-surface-variant)}.ac__arrow{display:inline-flex;flex-shrink:0;color:var(--surface-surface-sys-on-surface-variant);line-height:0}.ac--no-desc .ac__label{line-height:1}.ac--vertical{flex-direction:column;align-items:flex-start;justify-content:flex-start;gap:var(--spacing-padding-sys-padding-16)}.ac__badge{display:inline-flex;align-items:center;justify-content:center;width:var(--sys-size-xl);height:var(--sys-size-xl);flex-shrink:0;border-radius:var(--border-radius-sys-radius-full);background-color:var(--surface-surface-container-sys-surface-container);color:var(--surface-surface-sys-on-surface);transition:background-color .14s ease-out;line-height:0}:host(:hover) .ac__badge{background-color:var(--surface-surface-container-sys-surface-container-lowest)}.ac--vertical .ac__label{white-space:pre-line;overflow:visible;font-size:var(--title-small-sys-font-size);line-height:var(--title-small-sys-line-height);font-weight:var(--title-small-sys-font-weight)}@media(prefers-reduced-motion:reduce){.ac__badge{transition:none}}.mc{display:flex;flex:1 1 auto;flex-direction:column;align-items:center;justify-content:center;gap:var(--spacing-padding-sys-padding-8);text-align:center;font-family:var(--body-medium-sys-font-family)}.mc__value{font-family:var(--headline-medium-sys-font-family);font-size:var(--headline-medium-sys-font-size);line-height:var(--headline-medium-sys-line-height);font-weight:var(--headline-medium-sys-font-weight);letter-spacing:var(--headline-medium-sys-tracking);color:var(--surface-surface-sys-on-surface)}.mc__label{font-family:var(--label-large-sys-font-family);font-size:var(--label-large-sys-font-size);line-height:var(--label-large-sys-line-height);font-weight:var(--label-large-sys-font-weight);letter-spacing:var(--label-large-sys-tracking);color:var(--surface-surface-sys-on-surface)}.mc--current .mc__value,.mc--current .mc__label{color:var(--accent-primary-sys-primary)}.mc--current .mc__value{font-weight:var(--headline-medium-sys-font-weight-emphasized)}.mc--current .mc__label{font-weight:var(--label-large-sys-font-weight-emphasized)}:host.cmp-card--metric{box-shadow:0 2px 2px #0000000f,0 2px 4px #0000000a}:host.cmp-card--metric.cmp-card--current{box-shadow:0 0 0 var(--spacing-padding-sys-padding-4) var(--transparent-primary-sys-primary-08)}.bc{display:flex;flex-direction:column;flex:1 1 auto;gap:var(--spacing-padding-sys-padding-48);padding:var(--spacing-padding-sys-padding-32);font-family:var(--body-medium-sys-font-family)}.bc__top{display:flex;align-items:flex-start;justify-content:space-between;gap:var(--spacing-padding-sys-padding-8)}.bc__icon{display:inline-flex;flex-shrink:0;color:var(--surface-surface-sys-on-surface);line-height:0}.bc__icon--badge{align-items:center;justify-content:center;width:60px;height:60px;border-radius:var(--border-radius-sys-radius-full);background-color:var(--accent-primary-sys-primary);color:var(--accent-primary-sys-on-primary)}.bc__top-end{display:inline-flex;align-items:center;gap:var(--spacing-padding-sys-padding-8)}.bc__arrow{display:inline-flex;flex-shrink:0;color:var(--surface-surface-sys-on-surface-variant);line-height:0}.bc__chip{display:inline-flex;align-items:center;padding:var(--spacing-padding-sys-padding-4) var(--spacing-padding-sys-padding-12);border-radius:var(--border-radius-sys-radius-full);background-color:var(--custom-info-sys-info-container);color:var(--custom-info-sys-on-info-container);font-family:var(--label-medium-sys-font-family);font-size:var(--label-medium-sys-font-size);line-height:var(--label-medium-sys-line-height);white-space:nowrap}.bc__body{display:flex;flex-direction:column;gap:var(--spacing-padding-sys-padding-24)}.bc__text{display:flex;flex-direction:column;gap:var(--spacing-padding-sys-padding-12)}.bc__heading{display:flex;flex-direction:column;gap:var(--spacing-padding-sys-padding-4)}.bc__eyebrow{margin:0;font-family:var(--label-medium-sys-font-family);font-size:var(--label-medium-sys-font-size);line-height:var(--label-medium-sys-line-height);letter-spacing:var(--label-medium-sys-tracking);color:var(--surface-surface-sys-on-surface-variant)}.bc__title{margin:0;font-family:var(--title-medium-sys-font-family);font-size:var(--title-medium-sys-font-size);line-height:var(--title-medium-sys-line-height);letter-spacing:var(--title-medium-sys-tracking);font-weight:var(--title-medium-sys-font-weight);color:var(--surface-surface-sys-on-surface)}.bc__subtitle{margin:0;font-family:var(--title-medium-sys-font-family);font-size:var(--title-medium-sys-font-size);line-height:var(--title-medium-sys-line-height);letter-spacing:var(--title-medium-sys-tracking);font-weight:var(--title-medium-sys-font-weight);color:var(--surface-surface-sys-on-surface-variant)}.bc__desc{margin:0;font-family:var(--body-medium-sys-font-family);font-size:var(--body-medium-sys-font-size);line-height:var(--body-medium-sys-line-height);letter-spacing:var(--body-medium-sys-tracking);color:var(--surface-surface-sys-on-surface-variant)}.bc__button{align-self:flex-start;display:inline-flex;align-items:center;padding:var(--spacing-padding-sys-padding-8) var(--spacing-padding-sys-padding-32);border-radius:var(--border-radius-sys-radius-full);border:var(--border-width-sys-stroke-thin) solid var(--outline-sys-outline);background-color:var(--surface-surface-container-sys-surface-container-lowest);color:var(--surface-surface-sys-on-surface);font-family:var(--label-large-sys-font-family);font-size:var(--label-large-sys-font-size);line-height:var(--label-large-sys-line-height);font-weight:var(--label-large-sys-font-weight-emphasized);white-space:nowrap}:host.cmp-card--gradient.cmp-card--basic:not([data-card-size=xs]):not([data-card-size=lg]){background-image:none;border-radius:var(--border-radius-sys-radius-xl)}:host.cmp-card--gradient.cmp-card--basic:not([data-card-size=xs]):not([data-card-size=lg]) .cmp-card__body{padding:var(--spacing-padding-sys-padding-8)}:host.cmp-card--gradient.cmp-card--basic:not([data-card-size=xs]):not([data-card-size=lg]) .bc{gap:var(--spacing-padding-sys-padding-32);padding:var(--spacing-padding-sys-padding-24);border-radius:var(--border-radius-sys-radius-lg);background-image:linear-gradient(180deg,var(--transparent-primary-sys-primary-08) 0%,var(--transparent-neutral-sys-white-10) 100%)}.bc--image{justify-content:space-between;gap:var(--spacing-padding-sys-padding-12);min-height:15.25rem}.bc--image .bc__title{color:var(--accent-primary-sys-on-primary)}.bc--image .bc__subtitle{color:var(--transparent-neutral-sys-white-80)}.bc--image .bc__desc{color:var(--transparent-neutral-sys-white-50)}.bc--image .bc__arrow{align-self:flex-end;color:var(--accent-primary-sys-on-primary)}:host.cmp-card--image .bc--row .bc__title,:host.cmp-card--image .bc--row .bc__icon,:host.cmp-card--image .bc--row .bc__arrow{color:var(--accent-primary-sys-on-primary)}:host[data-card-size=sm] .bc{gap:var(--spacing-padding-sys-padding-40);padding:var(--spacing-padding-sys-padding-24)}:host[data-card-size=sm] .bc__title,:host[data-card-size=sm] .bc__subtitle{font-family:var(--title-small-sys-font-family);font-size:var(--title-small-sys-font-size);line-height:var(--title-small-sys-line-height);letter-spacing:var(--title-small-sys-tracking);font-weight:var(--title-small-sys-font-weight)}:host[data-card-size=sm] .bc__desc{font-family:var(--body-small-sys-font-family);font-size:var(--body-small-sys-font-size);line-height:var(--body-small-sys-line-height);letter-spacing:var(--body-small-sys-tracking)}:host[data-card-size=xs]{border-radius:var(--border-radius-sys-radius-md)}.bc--row{flex-direction:row;align-items:center;gap:var(--spacing-padding-sys-padding-12);padding:var(--spacing-padding-sys-padding-16)}.bc--row .bc__icon{color:var(--surface-surface-sys-on-surface)}.bc--row .bc__row-text{flex:1 1 auto;min-width:0}.bc--row .bc__title{font-family:var(--body-medium-sys-font-family);font-size:var(--body-medium-sys-font-size);line-height:var(--body-medium-sys-line-height);letter-spacing:var(--body-medium-sys-tracking);font-weight:var(--body-medium-sys-font-weight)}.bc--promo{justify-content:space-between;gap:var(--spacing-padding-sys-padding-24)}.bc--promo .bc__chip{align-self:flex-start}.bc__button--end{align-self:flex-end}.bc--promo.bc--image .bc__title{color:var(--accent-primary-sys-on-primary)}.bc--promo.bc--image .bc__subtitle{color:var(--transparent-neutral-sys-white-80)}.bc--promo.bc--image .bc__desc{color:var(--transparent-neutral-sys-white-50)}:host.cmp-card--filled .bc__title,:host.cmp-card--filled .bc__icon{color:var(--accent-primary-sys-on-primary-container)}:host.cmp-card--filled .bc__eyebrow,:host.cmp-card--filled .bc__subtitle,:host.cmp-card--filled .bc__desc,:host.cmp-card--filled .bc__arrow{color:var(--accent-primary-sys-on-primary-container-variant)}:host.cmp-card--filled .bc__button{border-color:transparent}\n"], dependencies: [{ kind: "directive", type: NgTemplateOutlet, selector: "[ngTemplateOutlet]", inputs: ["ngTemplateOutletContext", "ngTemplateOutlet", "ngTemplateOutletInjector"] }], changeDetection: i0.ChangeDetectionStrategy.OnPush });
|
|
207
|
+
static ɵcmp = i0.ɵɵngDeclareComponent({ minVersion: "17.0.0", version: "21.2.14", type: CardComponent, isStandalone: true, selector: "compsych-card", inputs: { variant: { classPropertyName: "variant", publicName: "variant", isSignal: true, isRequired: false, transformFunction: null }, appearance: { classPropertyName: "appearance", publicName: "appearance", isSignal: true, isRequired: false, transformFunction: null }, radius: { classPropertyName: "radius", publicName: "radius", isSignal: true, isRequired: false, transformFunction: null }, padding: { classPropertyName: "padding", publicName: "padding", isSignal: true, isRequired: false, transformFunction: null }, size: { classPropertyName: "size", publicName: "size", isSignal: true, isRequired: false, transformFunction: null }, interactive: { classPropertyName: "interactive", publicName: "interactive", isSignal: true, isRequired: false, transformFunction: null }, disabled: { classPropertyName: "disabled", publicName: "disabled", isSignal: true, isRequired: false, transformFunction: null }, selected: { classPropertyName: "selected", publicName: "selected", isSignal: true, isRequired: false, transformFunction: null }, imageSrc: { classPropertyName: "imageSrc", publicName: "imageSrc", isSignal: true, isRequired: false, transformFunction: null }, hideImage: { classPropertyName: "hideImage", publicName: "hideImage", isSignal: true, isRequired: false, transformFunction: null }, imagePosition: { classPropertyName: "imagePosition", publicName: "imagePosition", isSignal: true, isRequired: false, transformFunction: null }, icon: { classPropertyName: "icon", publicName: "icon", isSignal: true, isRequired: false, transformFunction: null }, category: { classPropertyName: "category", publicName: "category", isSignal: true, isRequired: false, transformFunction: null }, categoryStyle: { classPropertyName: "categoryStyle", publicName: "categoryStyle", isSignal: true, isRequired: false, transformFunction: null }, iconStyle: { classPropertyName: "iconStyle", publicName: "iconStyle", isSignal: true, isRequired: false, transformFunction: null }, title: { classPropertyName: "title", publicName: "title", isSignal: true, isRequired: false, transformFunction: null }, subtitle: { classPropertyName: "subtitle", publicName: "subtitle", isSignal: true, isRequired: false, transformFunction: null }, description: { classPropertyName: "description", publicName: "description", isSignal: true, isRequired: false, transformFunction: null }, headline: { classPropertyName: "headline", publicName: "headline", isSignal: true, isRequired: false, transformFunction: null }, headlineDescription: { classPropertyName: "headlineDescription", publicName: "headlineDescription", isSignal: true, isRequired: false, transformFunction: null }, metrics: { classPropertyName: "metrics", publicName: "metrics", isSignal: true, isRequired: false, transformFunction: null }, actionLabel: { classPropertyName: "actionLabel", publicName: "actionLabel", isSignal: true, isRequired: false, transformFunction: null }, actionLeadingIcon: { classPropertyName: "actionLeadingIcon", publicName: "actionLeadingIcon", isSignal: true, isRequired: false, transformFunction: null }, actionTrailingIcon: { classPropertyName: "actionTrailingIcon", publicName: "actionTrailingIcon", isSignal: true, isRequired: false, transformFunction: null }, inlineIcon: { classPropertyName: "inlineIcon", publicName: "inlineIcon", isSignal: true, isRequired: false, transformFunction: null }, showArrow: { classPropertyName: "showArrow", publicName: "showArrow", isSignal: true, isRequired: false, transformFunction: null }, showGradient: { classPropertyName: "showGradient", publicName: "showGradient", isSignal: true, isRequired: false, transformFunction: null }, compact: { classPropertyName: "compact", publicName: "compact", isSignal: true, isRequired: false, transformFunction: null }, darkBackground: { classPropertyName: "darkBackground", publicName: "darkBackground", isSignal: true, isRequired: false, transformFunction: null }, label: { classPropertyName: "label", publicName: "label", isSignal: true, isRequired: false, transformFunction: null }, trailingIcon: { classPropertyName: "trailingIcon", publicName: "trailingIcon", isSignal: true, isRequired: false, transformFunction: null }, orientation: { classPropertyName: "orientation", publicName: "orientation", isSignal: true, isRequired: false, transformFunction: null }, fullWidth: { classPropertyName: "fullWidth", publicName: "fullWidth", isSignal: true, isRequired: false, transformFunction: null }, metricSize: { classPropertyName: "metricSize", publicName: "metricSize", isSignal: true, isRequired: false, transformFunction: null }, value: { classPropertyName: "value", publicName: "value", isSignal: true, isRequired: false, transformFunction: null }, current: { classPropertyName: "current", publicName: "current", isSignal: true, isRequired: false, transformFunction: null }, headingLevel: { classPropertyName: "headingLevel", publicName: "headingLevel", isSignal: true, isRequired: false, transformFunction: null }, ariaLabel: { classPropertyName: "ariaLabel", publicName: "aria-label", isSignal: true, isRequired: false, transformFunction: null } }, outputs: { cardClick: "cardClick", actionClick: "actionClick" }, host: { listeners: { "click": "onActivate()", "keydown": "onKeyDown($event)" }, properties: { "class.cmp-card--outlined": "appearance() === 'outlined'", "class.cmp-card--filled": "appearance() === 'filled'", "class.cmp-card--gradient": "appearance() === 'gradient'", "class.cmp-card--banner": "appearance() === 'banner'", "class.cmp-card--content": "variant() === 'content'", "class.cmp-card--basic": "variant() === 'basic'", "attr.data-card-size": "variant() === 'basic' ? size() : null", "class.cmp-card--metric": "variant() === 'metric'", "class.cmp-card--current": "variant() === 'metric' && current()", "class.cmp-card--radius-md": "radius() === 'md'", "class.cmp-card--radius-lg": "radius() === 'lg'", "class.cmp-card--radius-xl": "radius() === 'xl'", "class.cmp-card--pad-none": "effectivePadding() === 'none'", "class.cmp-card--pad-sm": "effectivePadding() === 'sm'", "class.cmp-card--pad-md": "effectivePadding() === 'md'", "class.cmp-card--pad-lg": "effectivePadding() === 'lg'", "class.cmp-card--pad-xl": "effectivePadding() === 'xl'", "style.width": "fullWidth() ? '100%' : null", "class.cmp-card--interactive": "interactive()", "class.cmp-card--disabled": "disabled()", "class.cmp-card--selected": "selected()", "class.cmp-card--no-gradient": "!showGradient()", "class.cmp-card--compact": "compact()", "class.cmp-card--metric-sm": "variant() === 'metric' && metricSize() === 'small'", "class.cmp-card--dark-bg": "darkBackground()", "class.cmp-card--hide-image": "hideImage()", "attr.role": "interactive() ? 'button' : null", "attr.tabindex": "interactive() && !disabled() ? 0 : null", "attr.aria-label": "ariaLabel() ?? null", "attr.aria-disabled": "disabled() || null", "attr.aria-pressed": "interactive() && variant() === 'metric' ? current() : null", "style.border-color": "variant() === 'metric' && current() ? 'var(--accent-primary-sys-primary)' : null", "style.border-width": "variant() === 'metric' && current() ? 'var(--border-width-sys-stroke-thick)' : null" }, classAttribute: "cmp-card" }, hostDirectives: [{ directive: i1.RippleDirective }], ngImport: i0, template: "@if (isBanner() && mediaUrl() && !hideImage()) {\n <div class=\"cmp-card__media\" [style.background-image]=\"mediaUrl()\" [style.background-position]=\"imagePosition()\"></div>\n <div class=\"cmp-card__scrim\" aria-hidden=\"true\"></div>\n}\n\n<div class=\"cmp-card__body\">\n @switch (variant()) {\n @case ('content') {\n @if (isBanner()) {\n <div class=\"cc cc--banner\">\n <div class=\"cc__img-top\">\n @if (icon()) {\n <div class=\"cc__media-icon\" [innerHTML]=\"iconSvg(icon(), 48)\" aria-hidden=\"true\"></div>\n }\n @if (category()) { <span class=\"cc__chip cc__chip--glass\">{{ category() }}</span> }\n </div>\n <div class=\"cc__img-foot\">\n @if (title() || subtitle() || headline() || description() || headlineDescription() || metrics().length) {\n <div class=\"cc__banner-text\">\n @if (title() || subtitle()) {\n <div class=\"cc__heading\">\n @if (title()) { <ng-container [ngTemplateOutlet]=\"headingTpl\" [ngTemplateOutletContext]=\"{ $implicit: 'cc__title', text: title() }\" /> }\n @if (subtitle()) { <p class=\"cc__subtitle\">{{ subtitle() }}</p> }\n </div>\n }\n @if (description()) { <p class=\"cc__desc\">{{ description() }}</p> }\n @if (headline()) { <ng-container [ngTemplateOutlet]=\"headingTpl\" [ngTemplateOutletContext]=\"{ $implicit: 'cc__headline', text: headline() }\" /> }\n @if (headlineDescription()) { <p class=\"cc__headline-desc\">{{ headlineDescription() }}</p> }\n @if (metrics().length) {\n <div class=\"cc__metrics\">\n @for (m of metrics(); track $index) {\n <compsych-card variant=\"metric\" [value]=\"m.value\" [label]=\"m.label ?? ''\" [current]=\"m.current ?? false\" [darkBackground]=\"true\" metricSize=\"small\" />\n }\n </div>\n }\n </div>\n }\n @if (actionLabel()) {\n <compsych-button variant=\"elevated\" [label]=\"actionLabel()\" [leadingIcon]=\"actionLeadingIcon()\" [trailingIcon]=\"actionTrailingIcon()\" (click)=\"actionClick.emit(); $event.stopPropagation()\" />\n } @else if (showArrow()) {\n <span class=\"cc__arrow\" [innerHTML]=\"iconSvg('arrow-up-right', 24)\" aria-hidden=\"true\"></span>\n }\n </div>\n </div>\n } @else if (appearance() === 'gradient') {\n <div class=\"cc\">\n <div class=\"cc__top\" [class.cc__top--label]=\"categoryStyle() === 'label'\">\n @if (icon()) {\n <div class=\"cc__icon\" [class.cc__icon--neutral]=\"iconStyle() === 'neutral'\" [innerHTML]=\"iconSvg(icon(), 24)\" aria-hidden=\"true\"></div>\n }\n @if (categoryStyle() === 'label' && category()) {\n <span class=\"cc__category-label\">{{ category() }}</span>\n }\n <div class=\"cc__top-end\">\n @if (categoryStyle() === 'chip' && category()) { <span class=\"cc__chip\">{{ category() }}</span> }\n @if (showArrow()) {\n <span class=\"cc__arrow\" [innerHTML]=\"iconSvg('arrow-up-right', 24)\" aria-hidden=\"true\"></span>\n }\n </div>\n </div>\n <div class=\"cc__text\">\n @if (title() || subtitle()) {\n <div class=\"cc__heading\">\n @if (title()) { <ng-container [ngTemplateOutlet]=\"headingTpl\" [ngTemplateOutletContext]=\"{ $implicit: 'cc__title', text: title() }\" /> }\n @if (subtitle()) { <p class=\"cc__subtitle\">{{ subtitle() }}</p> }\n </div>\n }\n @if (description()) { <p class=\"cc__desc\">{{ description() }}</p> }\n </div>\n @if (actionLabel()) {\n <compsych-button variant=\"outlined\" [label]=\"actionLabel()\" [leadingIcon]=\"actionLeadingIcon()\" [trailingIcon]=\"actionTrailingIcon()\" />\n }\n </div>\n } @else {\n <div class=\"cc cc--with-icon\" [class.cc--filled]=\"appearance() === 'filled'\" [class.cc--inline-icon]=\"inlineIcon()\">\n @if (inlineIcon()) {\n @if (icon()) {\n <span class=\"cc__banner-icon\" [innerHTML]=\"iconSvg(icon(), 32, 1.5)\" aria-hidden=\"true\"></span>\n }\n } @else {\n <div class=\"cc__banner\">\n @if (icon()) {\n <span class=\"cc__banner-icon\" [innerHTML]=\"iconSvg(icon(), 48, 1.5)\" aria-hidden=\"true\"></span>\n }\n </div>\n }\n <div class=\"cc__container\">\n <div class=\"cc__title-group\">\n @if (category()) { <p class=\"cc__category-eyebrow\">{{ category() }}</p> }\n @if (title()) { <ng-container [ngTemplateOutlet]=\"headingTpl\" [ngTemplateOutletContext]=\"{ $implicit: 'cc__title', text: title() }\" /> }\n </div>\n @if (description()) { <p class=\"cc__desc\">{{ description() }}</p> }\n @if (headline()) { <ng-container [ngTemplateOutlet]=\"headingTpl\" [ngTemplateOutletContext]=\"{ $implicit: 'cc__headline', text: headline() }\" /> }\n </div>\n </div>\n }\n }\n\n @case ('action') {\n @if (orientation() === 'vertical') {\n <div class=\"ac ac--vertical\" [class.ac--no-desc]=\"!description()\">\n @if (icon()) {\n <div class=\"ac__badge\" [innerHTML]=\"iconSvg(icon(), 24, 1.5)\" aria-hidden=\"true\"></div>\n }\n <div class=\"ac__text\">\n <ng-container [ngTemplateOutlet]=\"labelTpl\" />\n @if (description()) { <span class=\"ac__desc\">{{ description() }}</span> }\n </div>\n </div>\n } @else {\n <div class=\"ac\" [class.ac--no-desc]=\"!description()\">\n @if (icon()) {\n <div class=\"ac__icon\" [innerHTML]=\"iconSvg(icon(), 32)\" aria-hidden=\"true\"></div>\n }\n <div class=\"ac__text\">\n <ng-container [ngTemplateOutlet]=\"labelTpl\" />\n @if (description()) { <span class=\"ac__desc\">{{ description() }}</span> }\n </div>\n </div>\n }\n }\n\n @case ('metric') {\n <div class=\"mc\" [class.mc--current]=\"current()\">\n <span class=\"mc__value\">{{ value() }}</span>\n @if (label()) { <span class=\"mc__label\">{{ label() }}</span> }\n </div>\n }\n\n @case ('basic') {\n @if (size() === 'xs') {\n <!-- xs base card (Figma 243:3264): compact horizontal row \u2014 icon \u00B7 title \u00B7 arrow. -->\n <div class=\"bc bc--row\">\n @if (icon()) {\n <div class=\"bc__icon\" [innerHTML]=\"iconSvg(icon(), 24, 1.5)\" aria-hidden=\"true\"></div>\n }\n <div class=\"bc__row-text\">\n @if (title()) { <ng-container [ngTemplateOutlet]=\"headingTpl\" [ngTemplateOutletContext]=\"{ $implicit: 'bc__title', text: title() }\" /> }\n </div>\n @if (showArrow()) {\n <span class=\"bc__arrow\" [innerHTML]=\"iconSvg('arrow-up-right', 20)\" aria-hidden=\"true\"></span>\n }\n </div>\n } @else if (size() === 'lg') {\n <!-- lg base card (Figma 243:3205): text + optional chip, button bottom-right. -->\n <div class=\"bc bc--promo\" [class.bc--banner]=\"isBanner()\">\n <div class=\"bc__text\">\n @if (label()) { <p class=\"bc__eyebrow\">{{ label() }}</p> }\n @if (title() || subtitle()) {\n <div class=\"bc__heading\">\n @if (title()) { <ng-container [ngTemplateOutlet]=\"headingTpl\" [ngTemplateOutletContext]=\"{ $implicit: 'bc__title', text: title() }\" /> }\n @if (subtitle()) { <p class=\"bc__subtitle\">{{ subtitle() }}</p> }\n </div>\n }\n @if (description()) { <p class=\"bc__desc\">{{ description() }}</p> }\n @if (category()) { <span class=\"bc__chip\">{{ category() }}</span> }\n </div>\n @if (actionLabel()) { <compsych-button variant=\"outlined\" [label]=\"actionLabel()\" /> }\n </div>\n } @else if (isBanner()) {\n <!-- md banner base card (Figma 59442:12042): text over the image, arrow bottom-right. -->\n <div class=\"bc bc--banner\">\n <div class=\"bc__text\">\n @if (title() || subtitle()) {\n <div class=\"bc__heading\">\n @if (title()) { <ng-container [ngTemplateOutlet]=\"headingTpl\" [ngTemplateOutletContext]=\"{ $implicit: 'bc__title', text: title() }\" /> }\n @if (subtitle()) { <p class=\"bc__subtitle\">{{ subtitle() }}</p> }\n </div>\n }\n @if (description()) { <p class=\"bc__desc\">{{ description() }}</p> }\n </div>\n @if (showArrow()) {\n <span class=\"bc__arrow\" [innerHTML]=\"iconSvg('arrow-up-right', basicArrowSize())\" aria-hidden=\"true\"></span>\n }\n </div>\n } @else {\n <!-- md / sm base card (Figma 243:3174, 243:3179, 947:8067):\n icon + arrow row, then eyebrow / title / subtitle / description / button. -->\n <div class=\"bc\">\n <div class=\"bc__top\">\n @if (icon()) {\n @if (appearance() === 'gradient') {\n <div class=\"bc__icon bc__icon--badge\" [innerHTML]=\"iconSvg(icon(), 32)\" aria-hidden=\"true\"></div>\n } @else {\n <div class=\"bc__icon\" [innerHTML]=\"iconSvg(icon(), basicIconSize(), 1.5)\" aria-hidden=\"true\"></div>\n }\n }\n <div class=\"bc__top-end\">\n @if (category()) { <span class=\"bc__chip\">{{ category() }}</span> }\n @if (showArrow()) {\n <span class=\"bc__arrow\" [innerHTML]=\"iconSvg('arrow-up-right', basicArrowSize())\" aria-hidden=\"true\"></span>\n }\n </div>\n </div>\n <div class=\"bc__body\">\n <div class=\"bc__text\">\n @if (label()) { <p class=\"bc__eyebrow\">{{ label() }}</p> }\n @if (title() || subtitle()) {\n <div class=\"bc__heading\">\n @if (title()) { <ng-container [ngTemplateOutlet]=\"headingTpl\" [ngTemplateOutletContext]=\"{ $implicit: 'bc__title', text: title() }\" /> }\n @if (subtitle()) { <p class=\"bc__subtitle\">{{ subtitle() }}</p> }\n </div>\n }\n @if (description()) { <p class=\"bc__desc\">{{ description() }}</p> }\n </div>\n @if (actionLabel()) { <compsych-button variant=\"outlined\" [label]=\"actionLabel()\" /> }\n </div>\n </div>\n }\n }\n\n @default {\n <ng-content />\n }\n }\n</div>\n\n<!-- Heading fragment: renders <h2>\u2013<h6> when headingLevel is set, else <p>.\n Pass $implicit = CSS class string, text = display text.\n Used by all title/headline slots across content and basic variants. -->\n<ng-template #headingTpl let-cls let-text=\"text\">\n @switch (effectiveHeadingLevel()) {\n @case (2) { <h2 [class]=\"cls\">{{ text }}</h2> }\n @case (3) { <h3 [class]=\"cls\">{{ text }}</h3> }\n @case (4) { <h4 [class]=\"cls\">{{ text }}</h4> }\n @case (5) { <h5 [class]=\"cls\">{{ text }}</h5> }\n @case (6) { <h6 [class]=\"cls\">{{ text }}</h6> }\n @default { <p [class]=\"cls\">{{ text }}</p> }\n }\n</ng-template>\n\n<!-- Action-card label: same heading-level logic but defaults to <span> (inline) not <p>. -->\n<ng-template #labelTpl>\n @switch (effectiveHeadingLevel()) {\n @case (2) { <h2 class=\"ac__label\">{{ label() }}</h2> }\n @case (3) { <h3 class=\"ac__label\">{{ label() }}</h3> }\n @case (4) { <h4 class=\"ac__label\">{{ label() }}</h4> }\n @case (5) { <h5 class=\"ac__label\">{{ label() }}</h5> }\n @case (6) { <h6 class=\"ac__label\">{{ label() }}</h6> }\n @default { <span class=\"ac__label\">{{ label() }}</span> }\n }\n</ng-template>\n", styles: [":host{position:relative;display:flex;flex-direction:column;box-sizing:border-box;overflow:hidden;border-radius:var(--border-radius-sys-radius-lg);background-color:var(--surface-surface-container-sys-surface-container-lowest);color:var(--surface-surface-sys-on-surface);isolation:isolate;container-type:inline-size}:host.cmp-card--radius-md{border-radius:var(--border-radius-sys-radius-md)}:host.cmp-card--radius-lg{border-radius:var(--border-radius-sys-radius-lg)}:host.cmp-card--radius-xl{border-radius:var(--border-radius-sys-radius-xl)}.cmp-card__body{position:relative;z-index:1;display:flex;flex-direction:column;flex:1 1 auto;min-height:0}:host.cmp-card--pad-none .cmp-card__body{padding:0}:host.cmp-card--pad-sm .cmp-card__body{padding:var(--spacing-padding-sys-padding-16)}:host.cmp-card--pad-md .cmp-card__body{padding:var(--spacing-padding-sys-padding-20)}:host.cmp-card--pad-lg .cmp-card__body{padding:var(--spacing-padding-sys-padding-24)}:host.cmp-card--pad-xl .cmp-card__body{padding:var(--spacing-padding-sys-padding-32)}:host.cmp-card--outlined{background-color:var(--surface-surface-container-sys-surface-container-lowest);border:var(--border-width-sys-stroke-thin) solid var(--outline-sys-outline-variant)}:host.cmp-card--filled{background-color:var(--accent-primary-sys-primary-container);color:var(--accent-primary-sys-on-primary-container)}:host.cmp-card--gradient{background-image:linear-gradient(180deg,var(--transparent-primary-sys-primary-08) 0%,var(--transparent-neutral-sys-white-10) 100%);background-color:var(--surface-surface-container-sys-surface-container-lowest);border:var(--border-width-sys-stroke-thin) solid var(--outline-sys-outline-variant)}:host.cmp-card--gradient.cmp-card--content{background-image:none;border-radius:var(--border-radius-sys-radius-xl)}:host.cmp-card--gradient.cmp-card--content .cmp-card__body{padding:var(--spacing-padding-sys-padding-8)}:host.cmp-card--gradient.cmp-card--content .cc{gap:var(--spacing-padding-sys-padding-32);padding:var(--spacing-padding-sys-padding-16);border-radius:var(--border-radius-sys-radius-lg);background-image:linear-gradient(180deg,var(--transparent-primary-sys-primary-08) 0%,var(--transparent-neutral-sys-white-10) 100%)}:host.cmp-card--gradient.cmp-card--content.cmp-card--no-gradient .cc{background-image:none}:host.cmp-card--compact .cc:not(.cc--banner){min-height:0}:host.cmp-card--gradient.cmp-card--content .cc__title{font-family:var(--label-large-sys-font-family);font-size:var(--label-large-sys-font-size);line-height:var(--label-large-sys-line-height);letter-spacing:var(--label-large-sys-tracking);font-weight:var(--label-large-sys-font-weight-emphasized)}:host.cmp-card--gradient.cmp-card--content .cc__desc{font-family:var(--body-small-sys-font-family);font-size:var(--body-small-sys-font-size);line-height:var(--body-small-sys-line-height);letter-spacing:var(--body-small-sys-tracking);font-weight:var(--body-small-sys-font-weight)}:host.cmp-card--banner{color:var(--accent-primary-sys-on-primary-container);background-color:var(--surface-surface-container-sys-surface-container-high)}:host.cmp-card--banner.cmp-card--hide-image{background-color:var(--accent-primary-sys-primary-container)}.cmp-card__media{position:absolute;inset:0;z-index:0;background-size:cover;background-position:center}.cmp-card__scrim{position:absolute;inset:0;z-index:0;background-image:linear-gradient(180deg,var(--transparent-neutral-sys-black-40) 0%,var(--transparent-neutral-sys-black-10) 32%,var(--transparent-neutral-sys-black-10) 64%,var(--transparent-neutral-sys-black-50) 100%);mix-blend-mode:multiply}:host.cmp-card--interactive{cursor:pointer;transition:box-shadow .14s ease-out,border-color .14s ease-out,border-width .14s ease-out}:host.cmp-card--interactive:after{content:\"\";position:absolute;inset:0;z-index:0;pointer-events:none;border-radius:inherit;background-color:var(--surface-surface-sys-on-surface);opacity:0;transition:opacity .14s ease-out}:host.cmp-card--interactive.cmp-card--filled:after,:host.cmp-card--interactive.cmp-card--banner:after{background-color:var(--accent-primary-sys-on-primary)}:host.cmp-card--interactive:hover{border-color:var(--outline-sys-outline-variant);border-width:var(--border-width-sys-stroke-medium);box-shadow:0 4px 16px #0000001a,0 2px 4px #00000014}:host.cmp-card--interactive:hover:after{opacity:.08}:host.cmp-card--interactive:active:after{opacity:.1}:host.cmp-card--selected,:host.cmp-card--interactive:focus-visible{outline:none;border-color:var(--add-on-primary-fixed-sys-on-primary-fixed-variant);border-width:var(--border-width-sys-stroke-medium);box-shadow:0 0 0 var(--spacing-padding-sys-padding-4) var(--transparent-primary-sys-primary-08)}:host.cmp-card--disabled{pointer-events:none;opacity:.38}:host.cmp-card--dark-bg{background-color:var(--transparent-neutral-sys-white-20);background-image:none;border-color:transparent;color:var(--accent-primary-sys-on-primary)}:host.cmp-card--dark-bg .mc__value,:host.cmp-card--dark-bg .mc__label{color:var(--accent-primary-sys-on-primary)}@media(prefers-reduced-motion:reduce){:host.cmp-card--interactive{transition:none}}@media(forced-colors:active){:host{border:1px solid CanvasText;forced-color-adjust:none}:host.cmp-card--interactive:focus-visible{outline:2px solid Highlight;outline-offset:2px}}.cc{display:flex;flex-direction:column;flex:1 1 auto;gap:var(--spacing-padding-sys-padding-12);font-family:var(--body-medium-sys-font-family)}.cc:not(.cc--banner){min-height:18.125rem}.cc__top{display:flex;align-items:flex-start;justify-content:space-between;gap:var(--spacing-padding-sys-padding-8)}.cc__top--label{justify-content:flex-start;align-items:center;gap:var(--spacing-padding-sys-padding-16)}.cc__category-label{background:transparent;padding:0;color:var(--accent-primary-sys-primary);font-family:var(--label-large-sys-font-family);font-size:var(--label-large-sys-font-size);line-height:var(--label-large-sys-line-height);letter-spacing:var(--label-large-sys-tracking);font-weight:var(--label-large-sys-font-weight-emphasized)}.cc__icon{display:inline-flex;align-items:center;justify-content:center;width:var(--sys-size-xl);height:var(--sys-size-xl);flex-shrink:0;border-radius:var(--border-radius-sys-radius-full);background-color:var(--accent-primary-sys-primary);color:var(--accent-primary-sys-on-primary);line-height:0}.cc__icon--neutral{background-color:var(--surface-surface-container-sys-surface-container-lowest);color:var(--surface-surface-sys-on-surface);border:var(--border-width-sys-stroke-thin) solid var(--outline-sys-outline)}.cc__banner{display:flex;align-items:center;justify-content:center;width:100%;height:120px;flex-shrink:0;overflow:hidden;border-radius:var(--border-radius-sys-radius-sm);background-color:var(--add-on-primary-fixed-sys-primary-fixed-dim);color:var(--add-on-primary-fixed-sys-on-primary-fixed)}.cc__banner-icon{display:inline-flex;line-height:0}.cc__container{display:flex;flex-direction:column;justify-content:space-between;flex:1 1 auto;gap:var(--spacing-padding-sys-padding-8);padding:var(--spacing-padding-sys-padding-8)}.cc__title-group{display:flex;flex-direction:column;gap:var(--spacing-padding-sys-padding-8)}.cc__category-eyebrow{margin:0;font-family:var(--label-medium-sys-font-family);font-size:var(--label-medium-sys-font-size);line-height:var(--label-medium-sys-line-height);letter-spacing:var(--label-medium-sys-tracking);color:var(--surface-surface-sys-on-surface-variant)}.cc--with-icon .cc__title{font-family:var(--label-large-sys-font-family);font-size:var(--label-large-sys-font-size);line-height:var(--label-large-sys-line-height);letter-spacing:var(--label-large-sys-tracking);font-weight:var(--label-large-sys-font-weight-emphasized);color:var(--surface-surface-sys-on-surface)}.cc--inline-icon .cc__container{flex:0 0 auto;margin-top:auto}.cc__top-end{display:inline-flex;align-items:center;gap:var(--spacing-padding-sys-padding-8)}.cc__arrow{display:inline-flex;color:var(--surface-surface-sys-on-surface-variant);flex-shrink:0;line-height:0}.cc__text{display:flex;flex-direction:column;gap:var(--spacing-padding-sys-padding-12)}.cc__heading{display:flex;flex-direction:column;gap:var(--spacing-padding-sys-padding-4)}.cc__title{margin:0;font-family:var(--title-small-sys-font-family);font-size:var(--title-small-sys-font-size);line-height:var(--title-small-sys-line-height);font-weight:var(--title-small-sys-font-weight-emphasized);letter-spacing:var(--title-small-sys-tracking);color:var(--surface-surface-sys-on-surface);display:-webkit-box;-webkit-box-orient:vertical;-webkit-line-clamp:4;overflow:hidden}.cc__subtitle{margin:0;font-family:var(--title-small-sys-font-family);font-size:var(--title-small-sys-font-size);line-height:var(--title-small-sys-line-height);font-weight:var(--title-small-sys-font-weight-emphasized);letter-spacing:var(--title-small-sys-tracking);color:var(--surface-surface-sys-on-surface-variant)}.cc__desc{margin:0;font-family:var(--body-medium-sys-font-family);font-size:var(--body-medium-sys-font-size);line-height:var(--body-medium-sys-line-height);letter-spacing:var(--body-medium-sys-tracking);color:var(--surface-surface-sys-on-surface-variant);display:-webkit-box;-webkit-box-orient:vertical;-webkit-line-clamp:3;overflow:hidden}.cc__chip{display:inline-flex;align-items:center;padding:var(--spacing-padding-sys-padding-2) var(--spacing-padding-sys-padding-12);border-radius:var(--border-radius-sys-radius-full);background-color:var(--custom-info-sys-info-container);color:var(--custom-info-sys-on-info-container);font-family:var(--label-medium-sys-font-family);font-size:var(--label-medium-sys-font-size);line-height:var(--label-medium-sys-line-height);white-space:nowrap}.cc__chip--glass{background-color:var(--transparent-neutral-sys-white-20);color:var(--accent-primary-sys-on-primary);-webkit-backdrop-filter:blur(.375rem);backdrop-filter:blur(.375rem)}.cc--filled .cc__icon{background-color:var(--surface-surface-container-sys-surface-container-lowest);color:var(--accent-primary-sys-primary)}.cc--filled .cc__title{color:var(--accent-primary-sys-on-primary-container)}.cc--filled .cc__subtitle,.cc--filled .cc__desc,.cc--filled .cc__arrow{color:var(--accent-primary-sys-on-primary-container-variant)}.cc--banner{position:relative;display:flex;flex-direction:column;flex:1 1 auto;min-height:12.5rem;justify-content:space-between;gap:var(--spacing-padding-sys-padding-24);padding:var(--spacing-padding-sys-padding-24)}.cc__media-icon{display:inline-flex;flex-shrink:0;color:var(--accent-primary-sys-on-primary);line-height:0}.cc__img-top{display:flex;flex-direction:column;align-items:flex-start;gap:var(--spacing-padding-sys-padding-12)}.cc__img-foot{display:flex;align-items:flex-end;justify-content:space-between;gap:var(--spacing-padding-sys-padding-16)}.cc__img-foot--end{justify-content:flex-end}.cc__banner-text{display:flex;flex-direction:column;gap:var(--spacing-padding-sys-padding-8);min-width:0}.cc__headline{margin:0;font-family:var(--headline-large-sys-font-family);font-size:var(--headline-large-sys-font-size);line-height:var(--headline-large-sys-line-height);font-weight:var(--headline-large-sys-font-weight);letter-spacing:var(--headline-large-sys-tracking);color:var(--accent-primary-sys-on-primary)}:host.cmp-card--outlined .cc__headline{color:var(--surface-surface-sys-on-surface)}.cc__img-foot compsych-button{align-self:flex-end;flex-shrink:0}@container (max-width: 36rem){.cc__img-foot{flex-direction:column;align-items:flex-start}.cc__img-foot compsych-button{align-self:flex-start}}.cc--banner .cc__title,.cc--banner .cc__arrow{color:var(--accent-primary-sys-on-primary)}.cc--banner .cc__subtitle{color:var(--transparent-neutral-sys-white-80)}.cc--banner .cc__desc{color:var(--accent-primary-sys-on-primary-container-variant)}.cc__metrics{display:flex;flex-wrap:wrap;gap:var(--spacing-padding-sys-padding-8)}.cc__metrics compsych-card{flex:0 0 auto;width:8rem}.cc__headline-desc{margin:0;font-family:var(--body-medium-sys-font-family);font-size:var(--body-medium-sys-font-size);line-height:var(--body-medium-sys-line-height);letter-spacing:var(--body-medium-sys-tracking);color:var(--transparent-neutral-sys-white-80)}.ac{display:flex;flex:1 1 auto;align-items:center;gap:var(--spacing-padding-sys-padding-16);font-family:var(--body-medium-sys-font-family)}.ac__icon{display:inline-flex;align-items:center;justify-content:center;flex-shrink:0;color:var(--surface-surface-sys-on-surface);line-height:0}.ac__text{display:flex;flex-direction:column;gap:var(--spacing-padding-sys-padding-4);flex:1 1 auto;min-width:0}.ac__label{margin:0;font-family:var(--label-large-sys-font-family);font-size:var(--label-large-sys-font-size);line-height:var(--label-large-sys-line-height);font-weight:var(--label-large-sys-font-weight-emphasized);letter-spacing:var(--label-large-sys-tracking);color:var(--surface-surface-sys-on-surface)}.ac__desc{font-family:var(--body-small-sys-font-family);font-size:var(--body-small-sys-font-size);line-height:var(--body-small-sys-line-height);letter-spacing:var(--body-small-sys-tracking);color:var(--surface-surface-sys-on-surface-variant)}.ac__arrow{display:inline-flex;flex-shrink:0;color:var(--surface-surface-sys-on-surface-variant);line-height:0}.ac--no-desc .ac__label{line-height:1}.ac--vertical{flex-direction:column;align-items:flex-start;justify-content:flex-start;gap:var(--spacing-padding-sys-padding-16)}.ac__badge{display:inline-flex;align-items:center;justify-content:center;width:var(--sys-size-xl);height:var(--sys-size-xl);flex-shrink:0;border-radius:var(--border-radius-sys-radius-full);background-color:var(--surface-surface-container-sys-surface-container);color:var(--surface-surface-sys-on-surface);transition:background-color .14s ease-out;line-height:0}:host(:hover) .ac__badge{background-color:var(--surface-surface-container-sys-surface-container-lowest)}.ac--vertical .ac__label{white-space:pre-line;overflow:visible;font-size:var(--title-small-sys-font-size);line-height:var(--title-small-sys-line-height);font-weight:var(--title-small-sys-font-weight)}@media(prefers-reduced-motion:reduce){.ac__badge{transition:none}}.mc{display:flex;flex:1 1 auto;flex-direction:column;align-items:center;justify-content:center;gap:var(--spacing-padding-sys-padding-8);text-align:center;font-family:var(--body-medium-sys-font-family)}.mc__value{font-family:var(--headline-medium-sys-font-family);font-size:var(--headline-medium-sys-font-size);line-height:var(--headline-medium-sys-line-height);font-weight:var(--headline-medium-sys-font-weight);letter-spacing:var(--headline-medium-sys-tracking);color:var(--surface-surface-sys-on-surface)}.mc__label{font-family:var(--label-large-sys-font-family);font-size:var(--label-large-sys-font-size);line-height:var(--label-large-sys-line-height);font-weight:var(--label-large-sys-font-weight);letter-spacing:var(--label-large-sys-tracking);color:var(--surface-surface-sys-on-surface)}.mc--current .mc__value,.mc--current .mc__label{color:var(--accent-primary-sys-primary)}.mc--current .mc__value{font-weight:var(--headline-medium-sys-font-weight-emphasized)}.mc--current .mc__label{font-weight:var(--label-large-sys-font-weight-emphasized)}:host.cmp-card--metric{box-shadow:0 2px 2px #0000000f,0 2px 4px #0000000a}:host.cmp-card--metric-sm .mc{gap:var(--spacing-padding-sys-padding-4)}:host.cmp-card--metric-sm .mc__value{font-size:var(--headline-small-sys-font-size);line-height:var(--headline-small-sys-line-height);letter-spacing:var(--headline-small-sys-tracking);font-weight:var(--headline-small-sys-font-weight)}:host.cmp-card--metric-sm .mc--current .mc__value{font-weight:var(--headline-small-sys-font-weight-emphasized)}:host.cmp-card--metric-sm .mc__label{font-size:var(--label-medium-sys-font-size);line-height:var(--label-medium-sys-line-height);letter-spacing:var(--label-medium-sys-tracking);font-weight:var(--label-medium-sys-font-weight)}:host.cmp-card--metric-sm .mc--current .mc__label{font-weight:var(--label-medium-sys-font-weight-emphasized)}:host.cmp-card--metric.cmp-card--current{box-shadow:0 0 0 var(--spacing-padding-sys-padding-4) var(--transparent-primary-sys-primary-08)}.bc{display:flex;flex-direction:column;flex:1 1 auto;gap:var(--spacing-padding-sys-padding-48);padding:var(--spacing-padding-sys-padding-32);font-family:var(--body-medium-sys-font-family)}.bc__top{display:flex;align-items:flex-start;justify-content:space-between;gap:var(--spacing-padding-sys-padding-8)}.bc__icon{display:inline-flex;flex-shrink:0;color:var(--surface-surface-sys-on-surface);line-height:0}.bc__icon--badge{align-items:center;justify-content:center;width:60px;height:60px;border-radius:var(--border-radius-sys-radius-full);background-color:var(--accent-primary-sys-primary);color:var(--accent-primary-sys-on-primary)}.bc__top-end{display:inline-flex;align-items:center;gap:var(--spacing-padding-sys-padding-8)}.bc__arrow{display:inline-flex;flex-shrink:0;color:var(--surface-surface-sys-on-surface-variant);line-height:0}.bc__chip{display:inline-flex;align-items:center;padding:var(--spacing-padding-sys-padding-4) var(--spacing-padding-sys-padding-12);border-radius:var(--border-radius-sys-radius-full);background-color:var(--custom-info-sys-info-container);color:var(--custom-info-sys-on-info-container);font-family:var(--label-medium-sys-font-family);font-size:var(--label-medium-sys-font-size);line-height:var(--label-medium-sys-line-height);white-space:nowrap}.bc__body{display:flex;flex-direction:column;gap:var(--spacing-padding-sys-padding-24)}.bc__text{display:flex;flex-direction:column;gap:var(--spacing-padding-sys-padding-12)}.bc__heading{display:flex;flex-direction:column;gap:var(--spacing-padding-sys-padding-4)}.bc__eyebrow{margin:0;font-family:var(--label-medium-sys-font-family);font-size:var(--label-medium-sys-font-size);line-height:var(--label-medium-sys-line-height);letter-spacing:var(--label-medium-sys-tracking);color:var(--surface-surface-sys-on-surface-variant)}.bc__title{margin:0;font-family:var(--title-medium-sys-font-family);font-size:var(--title-medium-sys-font-size);line-height:var(--title-medium-sys-line-height);letter-spacing:var(--title-medium-sys-tracking);font-weight:var(--title-medium-sys-font-weight);color:var(--surface-surface-sys-on-surface)}.bc__subtitle{margin:0;font-family:var(--title-medium-sys-font-family);font-size:var(--title-medium-sys-font-size);line-height:var(--title-medium-sys-line-height);letter-spacing:var(--title-medium-sys-tracking);font-weight:var(--title-medium-sys-font-weight);color:var(--surface-surface-sys-on-surface-variant)}.bc__desc{margin:0;font-family:var(--body-medium-sys-font-family);font-size:var(--body-medium-sys-font-size);line-height:var(--body-medium-sys-line-height);letter-spacing:var(--body-medium-sys-tracking);color:var(--surface-surface-sys-on-surface-variant)}:host.cmp-card--gradient.cmp-card--basic:not([data-card-size=xs]):not([data-card-size=lg]){background-image:none;border-radius:var(--border-radius-sys-radius-xl)}:host.cmp-card--gradient.cmp-card--basic:not([data-card-size=xs]):not([data-card-size=lg]) .cmp-card__body{padding:var(--spacing-padding-sys-padding-8)}:host.cmp-card--gradient.cmp-card--basic:not([data-card-size=xs]):not([data-card-size=lg]) .bc{gap:var(--spacing-padding-sys-padding-32);padding:var(--spacing-padding-sys-padding-24);border-radius:var(--border-radius-sys-radius-lg);background-image:linear-gradient(180deg,var(--transparent-primary-sys-primary-08) 0%,var(--transparent-neutral-sys-white-10) 100%)}.bc--banner{justify-content:space-between;gap:var(--spacing-padding-sys-padding-12);min-height:15.25rem}.bc--banner .bc__title{color:var(--accent-primary-sys-on-primary)}.bc--banner .bc__subtitle{color:var(--transparent-neutral-sys-white-80)}.bc--banner .bc__desc{color:var(--transparent-neutral-sys-white-50)}.bc--banner .bc__arrow{align-self:flex-end;color:var(--accent-primary-sys-on-primary)}:host.cmp-card--banner .bc--row .bc__title,:host.cmp-card--banner .bc--row .bc__icon,:host.cmp-card--banner .bc--row .bc__arrow{color:var(--accent-primary-sys-on-primary)}:host[data-card-size=sm] .bc{gap:var(--spacing-padding-sys-padding-40);padding:var(--spacing-padding-sys-padding-24)}:host[data-card-size=sm] .bc__title,:host[data-card-size=sm] .bc__subtitle{font-family:var(--title-small-sys-font-family);font-size:var(--title-small-sys-font-size);line-height:var(--title-small-sys-line-height);letter-spacing:var(--title-small-sys-tracking);font-weight:var(--title-small-sys-font-weight)}:host[data-card-size=sm] .bc__desc{font-family:var(--body-small-sys-font-family);font-size:var(--body-small-sys-font-size);line-height:var(--body-small-sys-line-height);letter-spacing:var(--body-small-sys-tracking)}:host[data-card-size=xs]{border-radius:var(--border-radius-sys-radius-md)}.bc--row{flex-direction:row;align-items:center;gap:var(--spacing-padding-sys-padding-12);padding:var(--spacing-padding-sys-padding-16)}.bc--row .bc__icon{color:var(--surface-surface-sys-on-surface)}.bc--row .bc__row-text{flex:1 1 auto;min-width:0}.bc--row .bc__title{font-family:var(--body-medium-sys-font-family);font-size:var(--body-medium-sys-font-size);line-height:var(--body-medium-sys-line-height);letter-spacing:var(--body-medium-sys-tracking);font-weight:var(--body-medium-sys-font-weight)}.bc--promo{justify-content:space-between;gap:var(--spacing-padding-sys-padding-24)}.bc--promo .bc__chip{align-self:flex-start}.bc--promo compsych-button{align-self:flex-end}.bc--promo.bc--banner .bc__title{color:var(--accent-primary-sys-on-primary)}.bc--promo.bc--banner .bc__subtitle{color:var(--transparent-neutral-sys-white-80)}.bc--promo.bc--banner .bc__desc{color:var(--transparent-neutral-sys-white-50)}:host.cmp-card--filled .bc__title,:host.cmp-card--filled .bc__icon{color:var(--accent-primary-sys-on-primary-container)}:host.cmp-card--filled .bc__eyebrow,:host.cmp-card--filled .bc__subtitle,:host.cmp-card--filled .bc__desc,:host.cmp-card--filled .bc__arrow{color:var(--accent-primary-sys-on-primary-container-variant)}\n"], dependencies: [{ kind: "component", type: CardComponent, selector: "compsych-card", inputs: ["variant", "appearance", "radius", "padding", "size", "interactive", "disabled", "selected", "imageSrc", "hideImage", "imagePosition", "icon", "category", "categoryStyle", "iconStyle", "title", "subtitle", "description", "headline", "headlineDescription", "metrics", "actionLabel", "actionLeadingIcon", "actionTrailingIcon", "inlineIcon", "showArrow", "showGradient", "compact", "darkBackground", "label", "trailingIcon", "orientation", "fullWidth", "metricSize", "value", "current", "headingLevel", "aria-label"], outputs: ["cardClick", "actionClick"] }, { kind: "directive", type: NgTemplateOutlet, selector: "[ngTemplateOutlet]", inputs: ["ngTemplateOutletContext", "ngTemplateOutlet", "ngTemplateOutletInjector"] }, { kind: "component", type: ButtonComponent, selector: "compsych-button", inputs: ["label", "variant", "size", "leadingIcon", "trailingIcon", "type", "ariaLabel", "iconOnly", "disabled", "loading", "fullWidth"] }], changeDetection: i0.ChangeDetectionStrategy.OnPush });
|
|
182
208
|
}
|
|
183
209
|
i0.ɵɵngDeclareClassMetadata({ minVersion: "12.0.0", version: "21.2.14", ngImport: i0, type: CardComponent, decorators: [{
|
|
184
210
|
type: Component,
|
|
185
|
-
args: [{ selector: 'compsych-card', standalone: true, changeDetection: ChangeDetectionStrategy.OnPush, imports: [NgTemplateOutlet], hostDirectives: [RippleDirective], host: {
|
|
211
|
+
args: [{ selector: 'compsych-card', standalone: true, changeDetection: ChangeDetectionStrategy.OnPush, imports: [NgTemplateOutlet, ButtonComponent, CardComponent], hostDirectives: [RippleDirective], host: {
|
|
186
212
|
class: 'cmp-card',
|
|
187
213
|
'[class.cmp-card--outlined]': "appearance() === 'outlined'",
|
|
188
214
|
'[class.cmp-card--filled]': "appearance() === 'filled'",
|
|
189
215
|
'[class.cmp-card--gradient]': "appearance() === 'gradient'",
|
|
190
|
-
'[class.cmp-card--
|
|
216
|
+
'[class.cmp-card--banner]': "appearance() === 'banner'",
|
|
191
217
|
'[class.cmp-card--content]': "variant() === 'content'",
|
|
192
218
|
'[class.cmp-card--basic]': "variant() === 'basic'",
|
|
193
219
|
'[attr.data-card-size]': "variant() === 'basic' ? size() : null",
|
|
194
|
-
'[class.cmp-card--hero]': "variant() === 'content' && !!headline()",
|
|
195
220
|
'[class.cmp-card--metric]': "variant() === 'metric'",
|
|
196
221
|
'[class.cmp-card--current]': "variant() === 'metric' && current()",
|
|
197
222
|
'[class.cmp-card--radius-md]': "radius() === 'md'",
|
|
@@ -208,6 +233,9 @@ i0.ɵɵngDeclareClassMetadata({ minVersion: "12.0.0", version: "21.2.14", ngImpo
|
|
|
208
233
|
'[class.cmp-card--selected]': 'selected()',
|
|
209
234
|
'[class.cmp-card--no-gradient]': '!showGradient()',
|
|
210
235
|
'[class.cmp-card--compact]': 'compact()',
|
|
236
|
+
'[class.cmp-card--metric-sm]': "variant() === 'metric' && metricSize() === 'small'",
|
|
237
|
+
'[class.cmp-card--dark-bg]': 'darkBackground()',
|
|
238
|
+
'[class.cmp-card--hide-image]': 'hideImage()',
|
|
211
239
|
'[attr.role]': "interactive() ? 'button' : null",
|
|
212
240
|
'[attr.tabindex]': 'interactive() && !disabled() ? 0 : null',
|
|
213
241
|
'[attr.aria-label]': 'ariaLabel() ?? null',
|
|
@@ -217,6 +245,6 @@ i0.ɵɵngDeclareClassMetadata({ minVersion: "12.0.0", version: "21.2.14", ngImpo
|
|
|
217
245
|
'[style.border-width]': "variant() === 'metric' && current() ? 'var(--border-width-sys-stroke-thick)' : null",
|
|
218
246
|
'(click)': 'onActivate()',
|
|
219
247
|
'(keydown)': 'onKeyDown($event)',
|
|
220
|
-
}, template: "@if (isImage() && mediaUrl()) {\r\n <div class=\"cmp-card__media\" [style.background-image]=\"mediaUrl()\" [style.background-position]=\"imagePosition()\"></div>\r\n <div class=\"cmp-card__scrim\" aria-hidden=\"true\"></div>\r\n}\r\n\r\n<div class=\"cmp-card__body\">\r\n @switch (variant()) {\r\n @case ('content') {\r\n @if (headline()) {\r\n <!-- Hero (image/filled): icon top-left, eyebrow + display headline + action bottom. -->\r\n <div class=\"cc cc--hero\" [class.cc--image]=\"isImage()\" [class.cc--filled]=\"appearance() === 'filled'\">\r\n @if (icon()) {\r\n @if (isImage()) {\r\n <div class=\"cc__media-icon\" [innerHTML]=\"iconSvg(icon(), 48)\" aria-hidden=\"true\"></div>\r\n } @else {\r\n <div class=\"cc__icon\" [class.cc__icon--neutral]=\"iconStyle() === 'neutral'\" [innerHTML]=\"iconSvg(icon(), 24)\" aria-hidden=\"true\"></div>\r\n }\r\n }\r\n <div class=\"cc__img-foot\">\r\n <div class=\"cc__hero-text\">\r\n @if (title()) { <p class=\"cc__eyebrow\">{{ title() }}</p> }\r\n <ng-container [ngTemplateOutlet]=\"headlineTpl\" />\r\n @if (description()) { <p class=\"cc__desc\">{{ description() }}</p> }\r\n </div>\r\n @if (actionLabel()) {\r\n <span class=\"cc__button cc__button--solid\">{{ actionLabel() }}</span>\r\n } @else if (showArrow()) {\r\n <span class=\"cc__arrow\" [innerHTML]=\"iconSvg('arrow-up-right', 24)\" aria-hidden=\"true\"></span>\r\n }\r\n </div>\r\n </div>\r\n } @else if (isImage()) {\r\n <div class=\"cc cc--image\">\r\n <div class=\"cc__img-top\">\r\n @if (icon()) {\r\n <div class=\"cc__media-icon\" [innerHTML]=\"iconSvg(icon(), 48)\" aria-hidden=\"true\"></div>\r\n }\r\n @if (category()) { <span class=\"cc__chip cc__chip--glass\">{{ category() }}</span> }\r\n </div>\r\n <div class=\"cc__img-foot\">\r\n @if (title() || subtitle() || description()) {\r\n <div class=\"cc__hero-text\">\r\n @if (title() || subtitle()) {\r\n <div class=\"cc__heading\">\r\n @if (title()) { <ng-container [ngTemplateOutlet]=\"titleTpl\" /> }\r\n @if (subtitle()) { <p class=\"cc__subtitle\">{{ subtitle() }}</p> }\r\n </div>\r\n }\r\n @if (description()) { <p class=\"cc__desc\">{{ description() }}</p> }\r\n </div>\r\n }\r\n @if (actionLabel()) {\r\n <span class=\"cc__button cc__button--solid\">{{ actionLabel() }}</span>\r\n } @else if (showArrow()) {\r\n <span class=\"cc__arrow\" [innerHTML]=\"iconSvg('arrow-up-right', 24)\" aria-hidden=\"true\"></span>\r\n }\r\n </div>\r\n </div>\r\n } @else if (appearance() === 'gradient') {\r\n <div class=\"cc\" [class.cc--filled]=\"appearance() === 'filled'\">\r\n <div class=\"cc__top\" [class.cc__top--label]=\"categoryStyle() === 'label'\">\r\n @if (icon()) {\r\n <div class=\"cc__icon\" [class.cc__icon--neutral]=\"iconStyle() === 'neutral'\" [innerHTML]=\"iconSvg(icon(), 24)\" aria-hidden=\"true\"></div>\r\n }\r\n @if (categoryStyle() === 'label' && category()) {\r\n <span class=\"cc__category-label\">{{ category() }}</span>\r\n }\r\n <div class=\"cc__top-end\">\r\n @if (categoryStyle() === 'chip' && category()) { <span class=\"cc__chip\">{{ category() }}</span> }\r\n @if (showArrow()) {\r\n <span class=\"cc__arrow\" [innerHTML]=\"iconSvg('arrow-up-right', 24)\" aria-hidden=\"true\"></span>\r\n }\r\n </div>\r\n </div>\r\n <div class=\"cc__text\">\r\n @if (title() || subtitle()) {\r\n <div class=\"cc__heading\">\r\n @if (title()) { <ng-container [ngTemplateOutlet]=\"titleTpl\" /> }\r\n @if (subtitle()) { <p class=\"cc__subtitle\">{{ subtitle() }}</p> }\r\n </div>\r\n }\r\n @if (description()) { <p class=\"cc__desc\">{{ description() }}</p> }\r\n </div>\r\n @if (actionLabel()) { <span class=\"cc__button\">{{ actionLabel() }}</span> }\r\n </div>\r\n } @else {\r\n <!-- With-icon content card (Figma 59444:2263): a full-width light-blue\r\n icon banner over a gray category eyebrow + title + body, with the\r\n text distributed top/bottom. Default for outlined/filled content. -->\r\n <div class=\"cc cc--with-icon\" [class.cc--filled]=\"appearance() === 'filled'\">\r\n <div class=\"cc__banner\">\r\n @if (icon()) {\r\n <span class=\"cc__banner-icon\" [innerHTML]=\"iconSvg(icon(), 48, 1.5)\" aria-hidden=\"true\"></span>\r\n }\r\n </div>\r\n <div class=\"cc__container\">\r\n <div class=\"cc__title-group\">\r\n @if (category()) { <p class=\"cc__category-eyebrow\">{{ category() }}</p> }\r\n @if (title()) { <ng-container [ngTemplateOutlet]=\"titleTpl\" /> }\r\n </div>\r\n @if (description()) { <p class=\"cc__desc\">{{ description() }}</p> }\r\n </div>\r\n </div>\r\n }\r\n }\r\n\r\n @case ('action') {\r\n @if (orientation() === 'vertical') {\r\n <div class=\"ac ac--vertical\" [class.ac--no-desc]=\"!description()\">\r\n @if (icon()) {\r\n <div class=\"ac__badge\" [innerHTML]=\"iconSvg(icon(), 24, 1.5)\" aria-hidden=\"true\"></div>\r\n }\r\n <div class=\"ac__text\">\r\n <ng-container [ngTemplateOutlet]=\"labelTpl\" />\r\n @if (description()) { <span class=\"ac__desc\">{{ description() }}</span> }\r\n </div>\r\n </div>\r\n } @else {\r\n <div class=\"ac\" [class.ac--no-desc]=\"!description()\">\r\n @if (icon()) {\r\n <div class=\"ac__icon\" [innerHTML]=\"iconSvg(icon(), 32)\" aria-hidden=\"true\"></div>\r\n }\r\n <div class=\"ac__text\">\r\n <ng-container [ngTemplateOutlet]=\"labelTpl\" />\r\n @if (description()) { <span class=\"ac__desc\">{{ description() }}</span> }\r\n </div>\r\n </div>\r\n }\r\n }\r\n\r\n @case ('metric') {\r\n <div class=\"mc\" [class.mc--current]=\"current()\">\r\n <span class=\"mc__value\">{{ value() }}</span>\r\n @if (label()) { <span class=\"mc__label\">{{ label() }}</span> }\r\n </div>\r\n }\r\n\r\n @case ('basic') {\r\n @if (size() === 'xs') {\r\n <!-- xs base card (Figma 243:3264): compact horizontal row \u2014 icon \u00B7 title \u00B7 arrow. -->\r\n <div class=\"bc bc--row\">\r\n @if (icon()) {\r\n <div class=\"bc__icon\" [innerHTML]=\"iconSvg(icon(), 24, 1.5)\" aria-hidden=\"true\"></div>\r\n }\r\n <div class=\"bc__row-text\">\r\n @if (title()) { <ng-container [ngTemplateOutlet]=\"bcTitleTpl\" /> }\r\n </div>\r\n @if (showArrow()) {\r\n <span class=\"bc__arrow\" [innerHTML]=\"iconSvg('arrow-up-right', 20)\" aria-hidden=\"true\"></span>\r\n }\r\n </div>\r\n } @else if (size() === 'lg') {\r\n <!-- lg base card (Figma 243:3205): text + optional chip, button bottom-right. -->\r\n <div class=\"bc bc--promo\" [class.bc--image]=\"isImage()\">\r\n <div class=\"bc__text\">\r\n @if (label()) { <p class=\"bc__eyebrow\">{{ label() }}</p> }\r\n @if (title() || subtitle()) {\r\n <div class=\"bc__heading\">\r\n @if (title()) { <ng-container [ngTemplateOutlet]=\"bcTitleTpl\" /> }\r\n @if (subtitle()) { <p class=\"bc__subtitle\">{{ subtitle() }}</p> }\r\n </div>\r\n }\r\n @if (description()) { <p class=\"bc__desc\">{{ description() }}</p> }\r\n @if (category()) { <span class=\"bc__chip\">{{ category() }}</span> }\r\n </div>\r\n @if (actionLabel()) { <span class=\"bc__button bc__button--end\">{{ actionLabel() }}</span> }\r\n </div>\r\n } @else if (isImage()) {\r\n <!-- md image base card (Figma 59442:12042): text over the image, arrow bottom-right. -->\r\n <div class=\"bc bc--image\">\r\n <div class=\"bc__text\">\r\n @if (title() || subtitle()) {\r\n <div class=\"bc__heading\">\r\n @if (title()) { <ng-container [ngTemplateOutlet]=\"bcTitleTpl\" /> }\r\n @if (subtitle()) { <p class=\"bc__subtitle\">{{ subtitle() }}</p> }\r\n </div>\r\n }\r\n @if (description()) { <p class=\"bc__desc\">{{ description() }}</p> }\r\n </div>\r\n @if (showArrow()) {\r\n <span class=\"bc__arrow\" [innerHTML]=\"iconSvg('arrow-up-right', basicArrowSize())\" aria-hidden=\"true\"></span>\r\n }\r\n </div>\r\n } @else {\r\n <!-- md / sm base card (Figma 243:3174, 243:3179, 947:8067):\r\n icon + arrow row, then eyebrow / title / subtitle / description / button. -->\r\n <div class=\"bc\">\r\n <div class=\"bc__top\">\r\n @if (icon()) {\r\n @if (appearance() === 'gradient') {\r\n <div class=\"bc__icon bc__icon--badge\" [innerHTML]=\"iconSvg(icon(), 32)\" aria-hidden=\"true\"></div>\r\n } @else {\r\n <div class=\"bc__icon\" [innerHTML]=\"iconSvg(icon(), basicIconSize(), 1.5)\" aria-hidden=\"true\"></div>\r\n }\r\n }\r\n <div class=\"bc__top-end\">\r\n @if (category()) { <span class=\"bc__chip\">{{ category() }}</span> }\r\n @if (showArrow()) {\r\n <span class=\"bc__arrow\" [innerHTML]=\"iconSvg('arrow-up-right', basicArrowSize())\" aria-hidden=\"true\"></span>\r\n }\r\n </div>\r\n </div>\r\n <div class=\"bc__body\">\r\n <div class=\"bc__text\">\r\n @if (label()) { <p class=\"bc__eyebrow\">{{ label() }}</p> }\r\n @if (title() || subtitle()) {\r\n <div class=\"bc__heading\">\r\n @if (title()) { <ng-container [ngTemplateOutlet]=\"bcTitleTpl\" /> }\r\n @if (subtitle()) { <p class=\"bc__subtitle\">{{ subtitle() }}</p> }\r\n </div>\r\n }\r\n @if (description()) { <p class=\"bc__desc\">{{ description() }}</p> }\r\n </div>\r\n @if (actionLabel()) { <span class=\"bc__button\">{{ actionLabel() }}</span> }\r\n </div>\r\n </div>\r\n }\r\n }\r\n\r\n @default {\r\n <ng-content />\r\n }\r\n }\r\n</div>\r\n\r\n<!-- Heading fragments: render a real <h2>\u2013<h6> when `headingLevel` is set, else the\r\n original <p>/<span>. Shared across layouts so semantics stay consistent and the\r\n cc__title / cc__headline / ac__label styling is unchanged. -->\r\n<ng-template #titleTpl>\r\n @switch (effectiveHeadingLevel()) {\r\n @case (2) { <h2 class=\"cc__title\">{{ title() }}</h2> }\r\n @case (3) { <h3 class=\"cc__title\">{{ title() }}</h3> }\r\n @case (4) { <h4 class=\"cc__title\">{{ title() }}</h4> }\r\n @case (5) { <h5 class=\"cc__title\">{{ title() }}</h5> }\r\n @case (6) { <h6 class=\"cc__title\">{{ title() }}</h6> }\r\n @default { <p class=\"cc__title\">{{ title() }}</p> }\r\n }\r\n</ng-template>\r\n\r\n<ng-template #headlineTpl>\r\n @switch (effectiveHeadingLevel()) {\r\n @case (2) { <h2 class=\"cc__headline\">{{ headline() }}</h2> }\r\n @case (3) { <h3 class=\"cc__headline\">{{ headline() }}</h3> }\r\n @case (4) { <h4 class=\"cc__headline\">{{ headline() }}</h4> }\r\n @case (5) { <h5 class=\"cc__headline\">{{ headline() }}</h5> }\r\n @case (6) { <h6 class=\"cc__headline\">{{ headline() }}</h6> }\r\n @default { <p class=\"cc__headline\">{{ headline() }}</p> }\r\n }\r\n</ng-template>\r\n\r\n<ng-template #labelTpl>\r\n @switch (effectiveHeadingLevel()) {\r\n @case (2) { <h2 class=\"ac__label\">{{ label() }}</h2> }\r\n @case (3) { <h3 class=\"ac__label\">{{ label() }}</h3> }\r\n @case (4) { <h4 class=\"ac__label\">{{ label() }}</h4> }\r\n @case (5) { <h5 class=\"ac__label\">{{ label() }}</h5> }\r\n @case (6) { <h6 class=\"ac__label\">{{ label() }}</h6> }\r\n @default { <span class=\"ac__label\">{{ label() }}</span> }\r\n }\r\n</ng-template>\r\n\r\n<ng-template #bcTitleTpl>\r\n @switch (effectiveHeadingLevel()) {\r\n @case (2) { <h2 class=\"bc__title\">{{ title() }}</h2> }\r\n @case (3) { <h3 class=\"bc__title\">{{ title() }}</h3> }\r\n @case (4) { <h4 class=\"bc__title\">{{ title() }}</h4> }\r\n @case (5) { <h5 class=\"bc__title\">{{ title() }}</h5> }\r\n @case (6) { <h6 class=\"bc__title\">{{ title() }}</h6> }\r\n @default { <p class=\"bc__title\">{{ title() }}</p> }\r\n }\r\n</ng-template>\r\n", styles: [":host{position:relative;display:flex;flex-direction:column;box-sizing:border-box;overflow:hidden;border-radius:var(--border-radius-sys-radius-lg);background-color:var(--surface-surface-container-sys-surface-container-lowest);color:var(--surface-surface-sys-on-surface);isolation:isolate;container-type:inline-size}:host.cmp-card--radius-md{border-radius:var(--border-radius-sys-radius-md)}:host.cmp-card--radius-lg{border-radius:var(--border-radius-sys-radius-lg)}:host.cmp-card--radius-xl{border-radius:var(--border-radius-sys-radius-xl)}.cmp-card__body{position:relative;z-index:1;display:flex;flex-direction:column;flex:1 1 auto;min-height:0}:host.cmp-card--pad-none .cmp-card__body{padding:0}:host.cmp-card--pad-sm .cmp-card__body{padding:var(--spacing-padding-sys-padding-16)}:host.cmp-card--pad-md .cmp-card__body{padding:var(--spacing-padding-sys-padding-20)}:host.cmp-card--pad-lg .cmp-card__body{padding:var(--spacing-padding-sys-padding-24)}:host.cmp-card--pad-xl .cmp-card__body{padding:var(--spacing-padding-sys-padding-32)}:host.cmp-card--outlined{background-color:var(--surface-surface-container-sys-surface-container-lowest);border:var(--border-width-sys-stroke-thin) solid var(--outline-sys-outline-variant)}:host.cmp-card--filled{background-color:var(--accent-primary-sys-primary-container);color:var(--accent-primary-sys-on-primary-container)}:host.cmp-card--gradient{background-image:linear-gradient(180deg,var(--transparent-primary-sys-primary-08) 0%,var(--transparent-neutral-sys-white-10) 100%);background-color:var(--surface-surface-container-sys-surface-container-lowest);border:var(--border-width-sys-stroke-thin) solid var(--outline-sys-outline-variant)}:host.cmp-card--gradient.cmp-card--content{background-image:none;border-radius:var(--border-radius-sys-radius-xl)}:host.cmp-card--gradient.cmp-card--content .cmp-card__body{padding:var(--spacing-padding-sys-padding-8)}:host.cmp-card--gradient.cmp-card--content .cc{gap:var(--spacing-padding-sys-padding-32);padding:var(--spacing-padding-sys-padding-16);border-radius:var(--border-radius-sys-radius-lg);background-image:linear-gradient(180deg,var(--transparent-primary-sys-primary-08) 0%,var(--transparent-neutral-sys-white-10) 100%)}:host.cmp-card--gradient.cmp-card--content.cmp-card--no-gradient .cc{background-image:none}:host.cmp-card--compact .cc:not(.cc--hero):not(.cc--image){min-height:0}:host.cmp-card--gradient.cmp-card--content .cc__title{font-family:var(--label-large-sys-font-family);font-size:var(--label-large-sys-font-size);line-height:var(--label-large-sys-line-height);letter-spacing:var(--label-large-sys-tracking);font-weight:var(--label-large-sys-font-weight-emphasized)}:host.cmp-card--gradient.cmp-card--content .cc__desc{font-family:var(--body-small-sys-font-family);font-size:var(--body-small-sys-font-size);line-height:var(--body-small-sys-line-height);letter-spacing:var(--body-small-sys-tracking);font-weight:var(--body-small-sys-font-weight)}:host.cmp-card--image{color:var(--accent-primary-sys-on-primary-container);background-color:var(--surface-surface-container-sys-surface-container-high)}.cmp-card__media{position:absolute;inset:0;z-index:0;background-size:cover;background-position:center}.cmp-card__scrim{position:absolute;inset:0;z-index:0;background-image:linear-gradient(180deg,var(--transparent-neutral-sys-black-40) 0%,var(--transparent-neutral-sys-black-10) 32%,var(--transparent-neutral-sys-black-10) 64%,var(--transparent-neutral-sys-black-50) 100%);mix-blend-mode:multiply}:host.cmp-card--interactive{cursor:pointer;transition:box-shadow .14s ease-out,border-color .14s ease-out,border-width .14s ease-out}:host.cmp-card--interactive:after{content:\"\";position:absolute;inset:0;z-index:0;pointer-events:none;border-radius:inherit;background-color:var(--surface-surface-sys-on-surface);opacity:0;transition:opacity .14s ease-out}:host.cmp-card--interactive.cmp-card--filled:after,:host.cmp-card--interactive.cmp-card--image:after{background-color:var(--accent-primary-sys-on-primary)}:host.cmp-card--interactive:hover{border-color:var(--outline-sys-outline-variant);border-width:var(--border-width-sys-stroke-medium);box-shadow:0 4px 16px #0000001a,0 2px 4px #00000014}:host.cmp-card--interactive:hover:after{opacity:.08}:host.cmp-card--interactive:active:after{opacity:.1}:host.cmp-card--selected,:host.cmp-card--interactive:focus-visible{outline:none;border-color:var(--add-on-primary-fixed-sys-on-primary-fixed-variant);border-width:var(--border-width-sys-stroke-medium);box-shadow:0 0 0 var(--spacing-padding-sys-padding-4) var(--transparent-primary-sys-primary-08)}:host.cmp-card--disabled{pointer-events:none;opacity:.38}@media(prefers-reduced-motion:reduce){:host.cmp-card--interactive{transition:none}}@media(forced-colors:active){:host{border:1px solid CanvasText;forced-color-adjust:none}:host.cmp-card--interactive:focus-visible{outline:2px solid Highlight;outline-offset:2px}}.cc{display:flex;flex-direction:column;flex:1 1 auto;gap:var(--spacing-padding-sys-padding-12);font-family:var(--body-medium-sys-font-family)}.cc:not(.cc--hero):not(.cc--image){min-height:18.125rem}.cc__top{display:flex;align-items:flex-start;justify-content:space-between;gap:var(--spacing-padding-sys-padding-8)}.cc__top--label{justify-content:flex-start;align-items:center;gap:var(--spacing-padding-sys-padding-16)}.cc__category-label{background:transparent;padding:0;color:var(--accent-primary-sys-primary);font-family:var(--label-large-sys-font-family);font-size:var(--label-large-sys-font-size);line-height:var(--label-large-sys-line-height);letter-spacing:var(--label-large-sys-tracking);font-weight:var(--label-large-sys-font-weight-emphasized)}.cc__icon{display:inline-flex;align-items:center;justify-content:center;width:var(--sys-size-xl);height:var(--sys-size-xl);flex-shrink:0;border-radius:var(--border-radius-sys-radius-full);background-color:var(--accent-primary-sys-primary);color:var(--accent-primary-sys-on-primary);line-height:0}.cc__icon--neutral{background-color:var(--surface-surface-container-sys-surface-container-lowest);color:var(--surface-surface-sys-on-surface);border:var(--border-width-sys-stroke-thin) solid var(--outline-sys-outline)}.cc__banner{display:flex;align-items:center;justify-content:center;width:100%;height:120px;flex-shrink:0;overflow:hidden;border-radius:var(--border-radius-sys-radius-sm);background-color:var(--add-on-primary-fixed-sys-primary-fixed-dim);color:var(--add-on-primary-fixed-sys-on-primary-fixed)}.cc__banner-icon{display:inline-flex;line-height:0}.cc__container{display:flex;flex-direction:column;justify-content:space-between;flex:1 1 auto;gap:var(--spacing-padding-sys-padding-8);padding:var(--spacing-padding-sys-padding-8)}.cc__title-group{display:flex;flex-direction:column;gap:var(--spacing-padding-sys-padding-8)}.cc__category-eyebrow{margin:0;font-family:var(--label-medium-sys-font-family);font-size:var(--label-medium-sys-font-size);line-height:var(--label-medium-sys-line-height);letter-spacing:var(--label-medium-sys-tracking);color:var(--surface-surface-sys-on-surface-variant)}.cc--with-icon .cc__title{font-family:var(--label-large-sys-font-family);font-size:var(--label-large-sys-font-size);line-height:var(--label-large-sys-line-height);letter-spacing:var(--label-large-sys-tracking);font-weight:var(--label-large-sys-font-weight-emphasized);color:var(--surface-surface-sys-on-surface)}.cc__top-end{display:inline-flex;align-items:center;gap:var(--spacing-padding-sys-padding-8)}.cc__arrow{display:inline-flex;color:var(--surface-surface-sys-on-surface-variant);flex-shrink:0;line-height:0}.cc__text{display:flex;flex-direction:column;gap:var(--spacing-padding-sys-padding-12)}.cc__heading{display:flex;flex-direction:column;gap:var(--spacing-padding-sys-padding-4)}.cc__title{margin:0;font-family:var(--title-small-sys-font-family);font-size:var(--title-small-sys-font-size);line-height:var(--title-small-sys-line-height);font-weight:var(--title-small-sys-font-weight-emphasized);letter-spacing:var(--title-small-sys-tracking);color:var(--surface-surface-sys-on-surface);display:-webkit-box;-webkit-box-orient:vertical;-webkit-line-clamp:4;overflow:hidden}.cc__subtitle{margin:0;font-family:var(--title-small-sys-font-family);font-size:var(--title-small-sys-font-size);line-height:var(--title-small-sys-line-height);font-weight:var(--title-small-sys-font-weight-emphasized);letter-spacing:var(--title-small-sys-tracking);color:var(--surface-surface-sys-on-surface-variant)}.cc__desc{margin:0;font-family:var(--body-medium-sys-font-family);font-size:var(--body-medium-sys-font-size);line-height:var(--body-medium-sys-line-height);letter-spacing:var(--body-medium-sys-tracking);color:var(--surface-surface-sys-on-surface-variant);display:-webkit-box;-webkit-box-orient:vertical;-webkit-line-clamp:3;overflow:hidden}.cc__chip{display:inline-flex;align-items:center;padding:var(--spacing-padding-sys-padding-2) var(--spacing-padding-sys-padding-12);border-radius:var(--border-radius-sys-radius-full);background-color:var(--custom-info-sys-info-container);color:var(--custom-info-sys-on-info-container);font-family:var(--label-medium-sys-font-family);font-size:var(--label-medium-sys-font-size);line-height:var(--label-medium-sys-line-height);white-space:nowrap}.cc__chip--glass{background-color:var(--transparent-neutral-sys-white-20);color:var(--accent-primary-sys-on-primary);-webkit-backdrop-filter:blur(.375rem);backdrop-filter:blur(.375rem)}.cc__button{align-self:flex-start;display:inline-flex;align-items:center;padding:var(--spacing-padding-sys-padding-8) var(--spacing-padding-sys-padding-32);border-radius:var(--border-radius-sys-radius-full);border:var(--border-width-sys-stroke-thin) solid var(--outline-sys-outline);background-color:var(--surface-surface-container-sys-surface-container-lowest);color:var(--surface-surface-sys-on-surface);font-family:var(--label-medium-sys-font-family);font-size:var(--label-medium-sys-font-size);font-weight:var(--label-medium-sys-font-weight-emphasized);line-height:var(--label-medium-sys-line-height);white-space:nowrap}.cc--filled .cc__icon{background-color:var(--surface-surface-container-sys-surface-container-lowest);color:var(--accent-primary-sys-primary)}.cc--filled .cc__title{color:var(--accent-primary-sys-on-primary-container)}.cc--filled .cc__subtitle,.cc--filled .cc__desc,.cc--filled .cc__arrow{color:var(--accent-primary-sys-on-primary-container-variant)}.cc--filled .cc__button{border-color:transparent}.cc--image{position:relative;display:flex;flex-direction:column;flex:1 1 auto;min-height:12.5rem;justify-content:space-between;gap:var(--spacing-padding-sys-padding-24);padding:var(--spacing-padding-sys-padding-24)}:host.cmp-card--hero{border-radius:var(--border-radius-sys-radius-xl)}.cc--hero{position:relative;display:flex;flex-direction:column;flex:1 1 auto;justify-content:flex-end;gap:var(--spacing-padding-sys-padding-24);min-height:22.5rem;padding:var(--spacing-padding-sys-padding-48)}.cc__media-icon{display:inline-flex;flex-shrink:0;color:var(--accent-primary-sys-on-primary);line-height:0}.cc--hero>.cc__media-icon{margin-bottom:auto}.cc__img-top{display:flex;flex-direction:column;align-items:flex-start;gap:var(--spacing-padding-sys-padding-12)}.cc__img-foot{display:flex;align-items:flex-end;justify-content:space-between;gap:var(--spacing-padding-sys-padding-16)}.cc__img-foot--end{justify-content:flex-end}.cc__hero-text{display:flex;flex-direction:column;gap:var(--spacing-padding-sys-padding-8);min-width:0}.cc__eyebrow{margin:0;font-family:var(--title-large-sys-font-family);font-size:var(--title-large-sys-font-size);line-height:var(--title-large-sys-line-height);letter-spacing:var(--title-large-sys-tracking);color:var(--accent-primary-sys-on-primary)}.cc__headline{margin:0;font-family:var(--display-large-sys-font-family);font-size:var(--display-large-sys-font-size);line-height:var(--display-large-sys-line-height);font-weight:var(--display-large-sys-font-weight);letter-spacing:var(--display-large-sys-tracking);color:var(--accent-primary-sys-on-primary)}.cc__button--solid{align-self:flex-end;flex-shrink:0;border-color:transparent;font-family:var(--label-large-sys-font-family);font-size:var(--label-large-sys-font-size);line-height:var(--label-large-sys-line-height);font-weight:var(--label-large-sys-font-weight-emphasized);box-shadow:0 .125rem .25rem #0000000f,0 .125rem .5rem #0000000a}@container (max-width: 36rem){.cc__img-foot{flex-direction:column;align-items:flex-start}.cc__button--solid{align-self:flex-start}}.cc--image .cc__title,.cc--image .cc__arrow{color:var(--accent-primary-sys-on-primary)}.cc--image .cc__subtitle,.cc--image .cc__desc{color:var(--transparent-neutral-sys-white-80)}.ac{display:flex;flex:1 1 auto;align-items:center;gap:var(--spacing-padding-sys-padding-16);font-family:var(--body-medium-sys-font-family)}.ac__icon{display:inline-flex;align-items:center;justify-content:center;flex-shrink:0;color:var(--surface-surface-sys-on-surface);line-height:0}.ac__text{display:flex;flex-direction:column;gap:var(--spacing-padding-sys-padding-4);flex:1 1 auto;min-width:0}.ac__label{margin:0;font-family:var(--label-large-sys-font-family);font-size:var(--label-large-sys-font-size);line-height:var(--label-large-sys-line-height);font-weight:var(--label-large-sys-font-weight-emphasized);letter-spacing:var(--label-large-sys-tracking);color:var(--surface-surface-sys-on-surface)}.ac__desc{font-family:var(--body-small-sys-font-family);font-size:var(--body-small-sys-font-size);line-height:var(--body-small-sys-line-height);letter-spacing:var(--body-small-sys-tracking);color:var(--surface-surface-sys-on-surface-variant)}.ac__arrow{display:inline-flex;flex-shrink:0;color:var(--surface-surface-sys-on-surface-variant);line-height:0}.ac--no-desc .ac__label{line-height:1}.ac--vertical{flex-direction:column;align-items:flex-start;justify-content:flex-start;gap:var(--spacing-padding-sys-padding-16)}.ac__badge{display:inline-flex;align-items:center;justify-content:center;width:var(--sys-size-xl);height:var(--sys-size-xl);flex-shrink:0;border-radius:var(--border-radius-sys-radius-full);background-color:var(--surface-surface-container-sys-surface-container);color:var(--surface-surface-sys-on-surface);transition:background-color .14s ease-out;line-height:0}:host(:hover) .ac__badge{background-color:var(--surface-surface-container-sys-surface-container-lowest)}.ac--vertical .ac__label{white-space:pre-line;overflow:visible;font-size:var(--title-small-sys-font-size);line-height:var(--title-small-sys-line-height);font-weight:var(--title-small-sys-font-weight)}@media(prefers-reduced-motion:reduce){.ac__badge{transition:none}}.mc{display:flex;flex:1 1 auto;flex-direction:column;align-items:center;justify-content:center;gap:var(--spacing-padding-sys-padding-8);text-align:center;font-family:var(--body-medium-sys-font-family)}.mc__value{font-family:var(--headline-medium-sys-font-family);font-size:var(--headline-medium-sys-font-size);line-height:var(--headline-medium-sys-line-height);font-weight:var(--headline-medium-sys-font-weight);letter-spacing:var(--headline-medium-sys-tracking);color:var(--surface-surface-sys-on-surface)}.mc__label{font-family:var(--label-large-sys-font-family);font-size:var(--label-large-sys-font-size);line-height:var(--label-large-sys-line-height);font-weight:var(--label-large-sys-font-weight);letter-spacing:var(--label-large-sys-tracking);color:var(--surface-surface-sys-on-surface)}.mc--current .mc__value,.mc--current .mc__label{color:var(--accent-primary-sys-primary)}.mc--current .mc__value{font-weight:var(--headline-medium-sys-font-weight-emphasized)}.mc--current .mc__label{font-weight:var(--label-large-sys-font-weight-emphasized)}:host.cmp-card--metric{box-shadow:0 2px 2px #0000000f,0 2px 4px #0000000a}:host.cmp-card--metric.cmp-card--current{box-shadow:0 0 0 var(--spacing-padding-sys-padding-4) var(--transparent-primary-sys-primary-08)}.bc{display:flex;flex-direction:column;flex:1 1 auto;gap:var(--spacing-padding-sys-padding-48);padding:var(--spacing-padding-sys-padding-32);font-family:var(--body-medium-sys-font-family)}.bc__top{display:flex;align-items:flex-start;justify-content:space-between;gap:var(--spacing-padding-sys-padding-8)}.bc__icon{display:inline-flex;flex-shrink:0;color:var(--surface-surface-sys-on-surface);line-height:0}.bc__icon--badge{align-items:center;justify-content:center;width:60px;height:60px;border-radius:var(--border-radius-sys-radius-full);background-color:var(--accent-primary-sys-primary);color:var(--accent-primary-sys-on-primary)}.bc__top-end{display:inline-flex;align-items:center;gap:var(--spacing-padding-sys-padding-8)}.bc__arrow{display:inline-flex;flex-shrink:0;color:var(--surface-surface-sys-on-surface-variant);line-height:0}.bc__chip{display:inline-flex;align-items:center;padding:var(--spacing-padding-sys-padding-4) var(--spacing-padding-sys-padding-12);border-radius:var(--border-radius-sys-radius-full);background-color:var(--custom-info-sys-info-container);color:var(--custom-info-sys-on-info-container);font-family:var(--label-medium-sys-font-family);font-size:var(--label-medium-sys-font-size);line-height:var(--label-medium-sys-line-height);white-space:nowrap}.bc__body{display:flex;flex-direction:column;gap:var(--spacing-padding-sys-padding-24)}.bc__text{display:flex;flex-direction:column;gap:var(--spacing-padding-sys-padding-12)}.bc__heading{display:flex;flex-direction:column;gap:var(--spacing-padding-sys-padding-4)}.bc__eyebrow{margin:0;font-family:var(--label-medium-sys-font-family);font-size:var(--label-medium-sys-font-size);line-height:var(--label-medium-sys-line-height);letter-spacing:var(--label-medium-sys-tracking);color:var(--surface-surface-sys-on-surface-variant)}.bc__title{margin:0;font-family:var(--title-medium-sys-font-family);font-size:var(--title-medium-sys-font-size);line-height:var(--title-medium-sys-line-height);letter-spacing:var(--title-medium-sys-tracking);font-weight:var(--title-medium-sys-font-weight);color:var(--surface-surface-sys-on-surface)}.bc__subtitle{margin:0;font-family:var(--title-medium-sys-font-family);font-size:var(--title-medium-sys-font-size);line-height:var(--title-medium-sys-line-height);letter-spacing:var(--title-medium-sys-tracking);font-weight:var(--title-medium-sys-font-weight);color:var(--surface-surface-sys-on-surface-variant)}.bc__desc{margin:0;font-family:var(--body-medium-sys-font-family);font-size:var(--body-medium-sys-font-size);line-height:var(--body-medium-sys-line-height);letter-spacing:var(--body-medium-sys-tracking);color:var(--surface-surface-sys-on-surface-variant)}.bc__button{align-self:flex-start;display:inline-flex;align-items:center;padding:var(--spacing-padding-sys-padding-8) var(--spacing-padding-sys-padding-32);border-radius:var(--border-radius-sys-radius-full);border:var(--border-width-sys-stroke-thin) solid var(--outline-sys-outline);background-color:var(--surface-surface-container-sys-surface-container-lowest);color:var(--surface-surface-sys-on-surface);font-family:var(--label-large-sys-font-family);font-size:var(--label-large-sys-font-size);line-height:var(--label-large-sys-line-height);font-weight:var(--label-large-sys-font-weight-emphasized);white-space:nowrap}:host.cmp-card--gradient.cmp-card--basic:not([data-card-size=xs]):not([data-card-size=lg]){background-image:none;border-radius:var(--border-radius-sys-radius-xl)}:host.cmp-card--gradient.cmp-card--basic:not([data-card-size=xs]):not([data-card-size=lg]) .cmp-card__body{padding:var(--spacing-padding-sys-padding-8)}:host.cmp-card--gradient.cmp-card--basic:not([data-card-size=xs]):not([data-card-size=lg]) .bc{gap:var(--spacing-padding-sys-padding-32);padding:var(--spacing-padding-sys-padding-24);border-radius:var(--border-radius-sys-radius-lg);background-image:linear-gradient(180deg,var(--transparent-primary-sys-primary-08) 0%,var(--transparent-neutral-sys-white-10) 100%)}.bc--image{justify-content:space-between;gap:var(--spacing-padding-sys-padding-12);min-height:15.25rem}.bc--image .bc__title{color:var(--accent-primary-sys-on-primary)}.bc--image .bc__subtitle{color:var(--transparent-neutral-sys-white-80)}.bc--image .bc__desc{color:var(--transparent-neutral-sys-white-50)}.bc--image .bc__arrow{align-self:flex-end;color:var(--accent-primary-sys-on-primary)}:host.cmp-card--image .bc--row .bc__title,:host.cmp-card--image .bc--row .bc__icon,:host.cmp-card--image .bc--row .bc__arrow{color:var(--accent-primary-sys-on-primary)}:host[data-card-size=sm] .bc{gap:var(--spacing-padding-sys-padding-40);padding:var(--spacing-padding-sys-padding-24)}:host[data-card-size=sm] .bc__title,:host[data-card-size=sm] .bc__subtitle{font-family:var(--title-small-sys-font-family);font-size:var(--title-small-sys-font-size);line-height:var(--title-small-sys-line-height);letter-spacing:var(--title-small-sys-tracking);font-weight:var(--title-small-sys-font-weight)}:host[data-card-size=sm] .bc__desc{font-family:var(--body-small-sys-font-family);font-size:var(--body-small-sys-font-size);line-height:var(--body-small-sys-line-height);letter-spacing:var(--body-small-sys-tracking)}:host[data-card-size=xs]{border-radius:var(--border-radius-sys-radius-md)}.bc--row{flex-direction:row;align-items:center;gap:var(--spacing-padding-sys-padding-12);padding:var(--spacing-padding-sys-padding-16)}.bc--row .bc__icon{color:var(--surface-surface-sys-on-surface)}.bc--row .bc__row-text{flex:1 1 auto;min-width:0}.bc--row .bc__title{font-family:var(--body-medium-sys-font-family);font-size:var(--body-medium-sys-font-size);line-height:var(--body-medium-sys-line-height);letter-spacing:var(--body-medium-sys-tracking);font-weight:var(--body-medium-sys-font-weight)}.bc--promo{justify-content:space-between;gap:var(--spacing-padding-sys-padding-24)}.bc--promo .bc__chip{align-self:flex-start}.bc__button--end{align-self:flex-end}.bc--promo.bc--image .bc__title{color:var(--accent-primary-sys-on-primary)}.bc--promo.bc--image .bc__subtitle{color:var(--transparent-neutral-sys-white-80)}.bc--promo.bc--image .bc__desc{color:var(--transparent-neutral-sys-white-50)}:host.cmp-card--filled .bc__title,:host.cmp-card--filled .bc__icon{color:var(--accent-primary-sys-on-primary-container)}:host.cmp-card--filled .bc__eyebrow,:host.cmp-card--filled .bc__subtitle,:host.cmp-card--filled .bc__desc,:host.cmp-card--filled .bc__arrow{color:var(--accent-primary-sys-on-primary-container-variant)}:host.cmp-card--filled .bc__button{border-color:transparent}\n"] }]
|
|
221
|
-
}], ctorParameters: () => [], propDecorators: { variant: [{ type: i0.Input, args: [{ isSignal: true, alias: "variant", required: false }] }], appearance: [{ type: i0.Input, args: [{ isSignal: true, alias: "appearance", required: false }] }], radius: [{ type: i0.Input, args: [{ isSignal: true, alias: "radius", required: false }] }], padding: [{ type: i0.Input, args: [{ isSignal: true, alias: "padding", required: false }] }], size: [{ type: i0.Input, args: [{ isSignal: true, alias: "size", required: false }] }], interactive: [{ type: i0.Input, args: [{ isSignal: true, alias: "interactive", required: false }] }], disabled: [{ type: i0.Input, args: [{ isSignal: true, alias: "disabled", required: false }] }], selected: [{ type: i0.Input, args: [{ isSignal: true, alias: "selected", required: false }] }], imageSrc: [{ type: i0.Input, args: [{ isSignal: true, alias: "imageSrc", required: false }] }], imagePosition: [{ type: i0.Input, args: [{ isSignal: true, alias: "imagePosition", required: false }] }], icon: [{ type: i0.Input, args: [{ isSignal: true, alias: "icon", required: false }] }], category: [{ type: i0.Input, args: [{ isSignal: true, alias: "category", required: false }] }], categoryStyle: [{ type: i0.Input, args: [{ isSignal: true, alias: "categoryStyle", required: false }] }], iconStyle: [{ type: i0.Input, args: [{ isSignal: true, alias: "iconStyle", required: false }] }], title: [{ type: i0.Input, args: [{ isSignal: true, alias: "title", required: false }] }], subtitle: [{ type: i0.Input, args: [{ isSignal: true, alias: "subtitle", required: false }] }], description: [{ type: i0.Input, args: [{ isSignal: true, alias: "description", required: false }] }], headline: [{ type: i0.Input, args: [{ isSignal: true, alias: "headline", required: false }] }], actionLabel: [{ type: i0.Input, args: [{ isSignal: true, alias: "actionLabel", required: false }] }], showArrow: [{ type: i0.Input, args: [{ isSignal: true, alias: "showArrow", required: false }] }], showGradient: [{ type: i0.Input, args: [{ isSignal: true, alias: "showGradient", required: false }] }], compact: [{ type: i0.Input, args: [{ isSignal: true, alias: "compact", required: false }] }], label: [{ type: i0.Input, args: [{ isSignal: true, alias: "label", required: false }] }], trailingIcon: [{ type: i0.Input, args: [{ isSignal: true, alias: "trailingIcon", required: false }] }], orientation: [{ type: i0.Input, args: [{ isSignal: true, alias: "orientation", required: false }] }], fullWidth: [{ type: i0.Input, args: [{ isSignal: true, alias: "fullWidth", required: false }] }], value: [{ type: i0.Input, args: [{ isSignal: true, alias: "value", required: false }] }], current: [{ type: i0.Input, args: [{ isSignal: true, alias: "current", required: false }] }], headingLevel: [{ type: i0.Input, args: [{ isSignal: true, alias: "headingLevel", required: false }] }], ariaLabel: [{ type: i0.Input, args: [{ isSignal: true, alias: "aria-label", required: false }] }], cardClick: [{ type: i0.Output, args: ["cardClick"] }] } });
|
|
248
|
+
}, template: "@if (isBanner() && mediaUrl() && !hideImage()) {\n <div class=\"cmp-card__media\" [style.background-image]=\"mediaUrl()\" [style.background-position]=\"imagePosition()\"></div>\n <div class=\"cmp-card__scrim\" aria-hidden=\"true\"></div>\n}\n\n<div class=\"cmp-card__body\">\n @switch (variant()) {\n @case ('content') {\n @if (isBanner()) {\n <div class=\"cc cc--banner\">\n <div class=\"cc__img-top\">\n @if (icon()) {\n <div class=\"cc__media-icon\" [innerHTML]=\"iconSvg(icon(), 48)\" aria-hidden=\"true\"></div>\n }\n @if (category()) { <span class=\"cc__chip cc__chip--glass\">{{ category() }}</span> }\n </div>\n <div class=\"cc__img-foot\">\n @if (title() || subtitle() || headline() || description() || headlineDescription() || metrics().length) {\n <div class=\"cc__banner-text\">\n @if (title() || subtitle()) {\n <div class=\"cc__heading\">\n @if (title()) { <ng-container [ngTemplateOutlet]=\"headingTpl\" [ngTemplateOutletContext]=\"{ $implicit: 'cc__title', text: title() }\" /> }\n @if (subtitle()) { <p class=\"cc__subtitle\">{{ subtitle() }}</p> }\n </div>\n }\n @if (description()) { <p class=\"cc__desc\">{{ description() }}</p> }\n @if (headline()) { <ng-container [ngTemplateOutlet]=\"headingTpl\" [ngTemplateOutletContext]=\"{ $implicit: 'cc__headline', text: headline() }\" /> }\n @if (headlineDescription()) { <p class=\"cc__headline-desc\">{{ headlineDescription() }}</p> }\n @if (metrics().length) {\n <div class=\"cc__metrics\">\n @for (m of metrics(); track $index) {\n <compsych-card variant=\"metric\" [value]=\"m.value\" [label]=\"m.label ?? ''\" [current]=\"m.current ?? false\" [darkBackground]=\"true\" metricSize=\"small\" />\n }\n </div>\n }\n </div>\n }\n @if (actionLabel()) {\n <compsych-button variant=\"elevated\" [label]=\"actionLabel()\" [leadingIcon]=\"actionLeadingIcon()\" [trailingIcon]=\"actionTrailingIcon()\" (click)=\"actionClick.emit(); $event.stopPropagation()\" />\n } @else if (showArrow()) {\n <span class=\"cc__arrow\" [innerHTML]=\"iconSvg('arrow-up-right', 24)\" aria-hidden=\"true\"></span>\n }\n </div>\n </div>\n } @else if (appearance() === 'gradient') {\n <div class=\"cc\">\n <div class=\"cc__top\" [class.cc__top--label]=\"categoryStyle() === 'label'\">\n @if (icon()) {\n <div class=\"cc__icon\" [class.cc__icon--neutral]=\"iconStyle() === 'neutral'\" [innerHTML]=\"iconSvg(icon(), 24)\" aria-hidden=\"true\"></div>\n }\n @if (categoryStyle() === 'label' && category()) {\n <span class=\"cc__category-label\">{{ category() }}</span>\n }\n <div class=\"cc__top-end\">\n @if (categoryStyle() === 'chip' && category()) { <span class=\"cc__chip\">{{ category() }}</span> }\n @if (showArrow()) {\n <span class=\"cc__arrow\" [innerHTML]=\"iconSvg('arrow-up-right', 24)\" aria-hidden=\"true\"></span>\n }\n </div>\n </div>\n <div class=\"cc__text\">\n @if (title() || subtitle()) {\n <div class=\"cc__heading\">\n @if (title()) { <ng-container [ngTemplateOutlet]=\"headingTpl\" [ngTemplateOutletContext]=\"{ $implicit: 'cc__title', text: title() }\" /> }\n @if (subtitle()) { <p class=\"cc__subtitle\">{{ subtitle() }}</p> }\n </div>\n }\n @if (description()) { <p class=\"cc__desc\">{{ description() }}</p> }\n </div>\n @if (actionLabel()) {\n <compsych-button variant=\"outlined\" [label]=\"actionLabel()\" [leadingIcon]=\"actionLeadingIcon()\" [trailingIcon]=\"actionTrailingIcon()\" />\n }\n </div>\n } @else {\n <div class=\"cc cc--with-icon\" [class.cc--filled]=\"appearance() === 'filled'\" [class.cc--inline-icon]=\"inlineIcon()\">\n @if (inlineIcon()) {\n @if (icon()) {\n <span class=\"cc__banner-icon\" [innerHTML]=\"iconSvg(icon(), 32, 1.5)\" aria-hidden=\"true\"></span>\n }\n } @else {\n <div class=\"cc__banner\">\n @if (icon()) {\n <span class=\"cc__banner-icon\" [innerHTML]=\"iconSvg(icon(), 48, 1.5)\" aria-hidden=\"true\"></span>\n }\n </div>\n }\n <div class=\"cc__container\">\n <div class=\"cc__title-group\">\n @if (category()) { <p class=\"cc__category-eyebrow\">{{ category() }}</p> }\n @if (title()) { <ng-container [ngTemplateOutlet]=\"headingTpl\" [ngTemplateOutletContext]=\"{ $implicit: 'cc__title', text: title() }\" /> }\n </div>\n @if (description()) { <p class=\"cc__desc\">{{ description() }}</p> }\n @if (headline()) { <ng-container [ngTemplateOutlet]=\"headingTpl\" [ngTemplateOutletContext]=\"{ $implicit: 'cc__headline', text: headline() }\" /> }\n </div>\n </div>\n }\n }\n\n @case ('action') {\n @if (orientation() === 'vertical') {\n <div class=\"ac ac--vertical\" [class.ac--no-desc]=\"!description()\">\n @if (icon()) {\n <div class=\"ac__badge\" [innerHTML]=\"iconSvg(icon(), 24, 1.5)\" aria-hidden=\"true\"></div>\n }\n <div class=\"ac__text\">\n <ng-container [ngTemplateOutlet]=\"labelTpl\" />\n @if (description()) { <span class=\"ac__desc\">{{ description() }}</span> }\n </div>\n </div>\n } @else {\n <div class=\"ac\" [class.ac--no-desc]=\"!description()\">\n @if (icon()) {\n <div class=\"ac__icon\" [innerHTML]=\"iconSvg(icon(), 32)\" aria-hidden=\"true\"></div>\n }\n <div class=\"ac__text\">\n <ng-container [ngTemplateOutlet]=\"labelTpl\" />\n @if (description()) { <span class=\"ac__desc\">{{ description() }}</span> }\n </div>\n </div>\n }\n }\n\n @case ('metric') {\n <div class=\"mc\" [class.mc--current]=\"current()\">\n <span class=\"mc__value\">{{ value() }}</span>\n @if (label()) { <span class=\"mc__label\">{{ label() }}</span> }\n </div>\n }\n\n @case ('basic') {\n @if (size() === 'xs') {\n <!-- xs base card (Figma 243:3264): compact horizontal row \u2014 icon \u00B7 title \u00B7 arrow. -->\n <div class=\"bc bc--row\">\n @if (icon()) {\n <div class=\"bc__icon\" [innerHTML]=\"iconSvg(icon(), 24, 1.5)\" aria-hidden=\"true\"></div>\n }\n <div class=\"bc__row-text\">\n @if (title()) { <ng-container [ngTemplateOutlet]=\"headingTpl\" [ngTemplateOutletContext]=\"{ $implicit: 'bc__title', text: title() }\" /> }\n </div>\n @if (showArrow()) {\n <span class=\"bc__arrow\" [innerHTML]=\"iconSvg('arrow-up-right', 20)\" aria-hidden=\"true\"></span>\n }\n </div>\n } @else if (size() === 'lg') {\n <!-- lg base card (Figma 243:3205): text + optional chip, button bottom-right. -->\n <div class=\"bc bc--promo\" [class.bc--banner]=\"isBanner()\">\n <div class=\"bc__text\">\n @if (label()) { <p class=\"bc__eyebrow\">{{ label() }}</p> }\n @if (title() || subtitle()) {\n <div class=\"bc__heading\">\n @if (title()) { <ng-container [ngTemplateOutlet]=\"headingTpl\" [ngTemplateOutletContext]=\"{ $implicit: 'bc__title', text: title() }\" /> }\n @if (subtitle()) { <p class=\"bc__subtitle\">{{ subtitle() }}</p> }\n </div>\n }\n @if (description()) { <p class=\"bc__desc\">{{ description() }}</p> }\n @if (category()) { <span class=\"bc__chip\">{{ category() }}</span> }\n </div>\n @if (actionLabel()) { <compsych-button variant=\"outlined\" [label]=\"actionLabel()\" /> }\n </div>\n } @else if (isBanner()) {\n <!-- md banner base card (Figma 59442:12042): text over the image, arrow bottom-right. -->\n <div class=\"bc bc--banner\">\n <div class=\"bc__text\">\n @if (title() || subtitle()) {\n <div class=\"bc__heading\">\n @if (title()) { <ng-container [ngTemplateOutlet]=\"headingTpl\" [ngTemplateOutletContext]=\"{ $implicit: 'bc__title', text: title() }\" /> }\n @if (subtitle()) { <p class=\"bc__subtitle\">{{ subtitle() }}</p> }\n </div>\n }\n @if (description()) { <p class=\"bc__desc\">{{ description() }}</p> }\n </div>\n @if (showArrow()) {\n <span class=\"bc__arrow\" [innerHTML]=\"iconSvg('arrow-up-right', basicArrowSize())\" aria-hidden=\"true\"></span>\n }\n </div>\n } @else {\n <!-- md / sm base card (Figma 243:3174, 243:3179, 947:8067):\n icon + arrow row, then eyebrow / title / subtitle / description / button. -->\n <div class=\"bc\">\n <div class=\"bc__top\">\n @if (icon()) {\n @if (appearance() === 'gradient') {\n <div class=\"bc__icon bc__icon--badge\" [innerHTML]=\"iconSvg(icon(), 32)\" aria-hidden=\"true\"></div>\n } @else {\n <div class=\"bc__icon\" [innerHTML]=\"iconSvg(icon(), basicIconSize(), 1.5)\" aria-hidden=\"true\"></div>\n }\n }\n <div class=\"bc__top-end\">\n @if (category()) { <span class=\"bc__chip\">{{ category() }}</span> }\n @if (showArrow()) {\n <span class=\"bc__arrow\" [innerHTML]=\"iconSvg('arrow-up-right', basicArrowSize())\" aria-hidden=\"true\"></span>\n }\n </div>\n </div>\n <div class=\"bc__body\">\n <div class=\"bc__text\">\n @if (label()) { <p class=\"bc__eyebrow\">{{ label() }}</p> }\n @if (title() || subtitle()) {\n <div class=\"bc__heading\">\n @if (title()) { <ng-container [ngTemplateOutlet]=\"headingTpl\" [ngTemplateOutletContext]=\"{ $implicit: 'bc__title', text: title() }\" /> }\n @if (subtitle()) { <p class=\"bc__subtitle\">{{ subtitle() }}</p> }\n </div>\n }\n @if (description()) { <p class=\"bc__desc\">{{ description() }}</p> }\n </div>\n @if (actionLabel()) { <compsych-button variant=\"outlined\" [label]=\"actionLabel()\" /> }\n </div>\n </div>\n }\n }\n\n @default {\n <ng-content />\n }\n }\n</div>\n\n<!-- Heading fragment: renders <h2>\u2013<h6> when headingLevel is set, else <p>.\n Pass $implicit = CSS class string, text = display text.\n Used by all title/headline slots across content and basic variants. -->\n<ng-template #headingTpl let-cls let-text=\"text\">\n @switch (effectiveHeadingLevel()) {\n @case (2) { <h2 [class]=\"cls\">{{ text }}</h2> }\n @case (3) { <h3 [class]=\"cls\">{{ text }}</h3> }\n @case (4) { <h4 [class]=\"cls\">{{ text }}</h4> }\n @case (5) { <h5 [class]=\"cls\">{{ text }}</h5> }\n @case (6) { <h6 [class]=\"cls\">{{ text }}</h6> }\n @default { <p [class]=\"cls\">{{ text }}</p> }\n }\n</ng-template>\n\n<!-- Action-card label: same heading-level logic but defaults to <span> (inline) not <p>. -->\n<ng-template #labelTpl>\n @switch (effectiveHeadingLevel()) {\n @case (2) { <h2 class=\"ac__label\">{{ label() }}</h2> }\n @case (3) { <h3 class=\"ac__label\">{{ label() }}</h3> }\n @case (4) { <h4 class=\"ac__label\">{{ label() }}</h4> }\n @case (5) { <h5 class=\"ac__label\">{{ label() }}</h5> }\n @case (6) { <h6 class=\"ac__label\">{{ label() }}</h6> }\n @default { <span class=\"ac__label\">{{ label() }}</span> }\n }\n</ng-template>\n", styles: [":host{position:relative;display:flex;flex-direction:column;box-sizing:border-box;overflow:hidden;border-radius:var(--border-radius-sys-radius-lg);background-color:var(--surface-surface-container-sys-surface-container-lowest);color:var(--surface-surface-sys-on-surface);isolation:isolate;container-type:inline-size}:host.cmp-card--radius-md{border-radius:var(--border-radius-sys-radius-md)}:host.cmp-card--radius-lg{border-radius:var(--border-radius-sys-radius-lg)}:host.cmp-card--radius-xl{border-radius:var(--border-radius-sys-radius-xl)}.cmp-card__body{position:relative;z-index:1;display:flex;flex-direction:column;flex:1 1 auto;min-height:0}:host.cmp-card--pad-none .cmp-card__body{padding:0}:host.cmp-card--pad-sm .cmp-card__body{padding:var(--spacing-padding-sys-padding-16)}:host.cmp-card--pad-md .cmp-card__body{padding:var(--spacing-padding-sys-padding-20)}:host.cmp-card--pad-lg .cmp-card__body{padding:var(--spacing-padding-sys-padding-24)}:host.cmp-card--pad-xl .cmp-card__body{padding:var(--spacing-padding-sys-padding-32)}:host.cmp-card--outlined{background-color:var(--surface-surface-container-sys-surface-container-lowest);border:var(--border-width-sys-stroke-thin) solid var(--outline-sys-outline-variant)}:host.cmp-card--filled{background-color:var(--accent-primary-sys-primary-container);color:var(--accent-primary-sys-on-primary-container)}:host.cmp-card--gradient{background-image:linear-gradient(180deg,var(--transparent-primary-sys-primary-08) 0%,var(--transparent-neutral-sys-white-10) 100%);background-color:var(--surface-surface-container-sys-surface-container-lowest);border:var(--border-width-sys-stroke-thin) solid var(--outline-sys-outline-variant)}:host.cmp-card--gradient.cmp-card--content{background-image:none;border-radius:var(--border-radius-sys-radius-xl)}:host.cmp-card--gradient.cmp-card--content .cmp-card__body{padding:var(--spacing-padding-sys-padding-8)}:host.cmp-card--gradient.cmp-card--content .cc{gap:var(--spacing-padding-sys-padding-32);padding:var(--spacing-padding-sys-padding-16);border-radius:var(--border-radius-sys-radius-lg);background-image:linear-gradient(180deg,var(--transparent-primary-sys-primary-08) 0%,var(--transparent-neutral-sys-white-10) 100%)}:host.cmp-card--gradient.cmp-card--content.cmp-card--no-gradient .cc{background-image:none}:host.cmp-card--compact .cc:not(.cc--banner){min-height:0}:host.cmp-card--gradient.cmp-card--content .cc__title{font-family:var(--label-large-sys-font-family);font-size:var(--label-large-sys-font-size);line-height:var(--label-large-sys-line-height);letter-spacing:var(--label-large-sys-tracking);font-weight:var(--label-large-sys-font-weight-emphasized)}:host.cmp-card--gradient.cmp-card--content .cc__desc{font-family:var(--body-small-sys-font-family);font-size:var(--body-small-sys-font-size);line-height:var(--body-small-sys-line-height);letter-spacing:var(--body-small-sys-tracking);font-weight:var(--body-small-sys-font-weight)}:host.cmp-card--banner{color:var(--accent-primary-sys-on-primary-container);background-color:var(--surface-surface-container-sys-surface-container-high)}:host.cmp-card--banner.cmp-card--hide-image{background-color:var(--accent-primary-sys-primary-container)}.cmp-card__media{position:absolute;inset:0;z-index:0;background-size:cover;background-position:center}.cmp-card__scrim{position:absolute;inset:0;z-index:0;background-image:linear-gradient(180deg,var(--transparent-neutral-sys-black-40) 0%,var(--transparent-neutral-sys-black-10) 32%,var(--transparent-neutral-sys-black-10) 64%,var(--transparent-neutral-sys-black-50) 100%);mix-blend-mode:multiply}:host.cmp-card--interactive{cursor:pointer;transition:box-shadow .14s ease-out,border-color .14s ease-out,border-width .14s ease-out}:host.cmp-card--interactive:after{content:\"\";position:absolute;inset:0;z-index:0;pointer-events:none;border-radius:inherit;background-color:var(--surface-surface-sys-on-surface);opacity:0;transition:opacity .14s ease-out}:host.cmp-card--interactive.cmp-card--filled:after,:host.cmp-card--interactive.cmp-card--banner:after{background-color:var(--accent-primary-sys-on-primary)}:host.cmp-card--interactive:hover{border-color:var(--outline-sys-outline-variant);border-width:var(--border-width-sys-stroke-medium);box-shadow:0 4px 16px #0000001a,0 2px 4px #00000014}:host.cmp-card--interactive:hover:after{opacity:.08}:host.cmp-card--interactive:active:after{opacity:.1}:host.cmp-card--selected,:host.cmp-card--interactive:focus-visible{outline:none;border-color:var(--add-on-primary-fixed-sys-on-primary-fixed-variant);border-width:var(--border-width-sys-stroke-medium);box-shadow:0 0 0 var(--spacing-padding-sys-padding-4) var(--transparent-primary-sys-primary-08)}:host.cmp-card--disabled{pointer-events:none;opacity:.38}:host.cmp-card--dark-bg{background-color:var(--transparent-neutral-sys-white-20);background-image:none;border-color:transparent;color:var(--accent-primary-sys-on-primary)}:host.cmp-card--dark-bg .mc__value,:host.cmp-card--dark-bg .mc__label{color:var(--accent-primary-sys-on-primary)}@media(prefers-reduced-motion:reduce){:host.cmp-card--interactive{transition:none}}@media(forced-colors:active){:host{border:1px solid CanvasText;forced-color-adjust:none}:host.cmp-card--interactive:focus-visible{outline:2px solid Highlight;outline-offset:2px}}.cc{display:flex;flex-direction:column;flex:1 1 auto;gap:var(--spacing-padding-sys-padding-12);font-family:var(--body-medium-sys-font-family)}.cc:not(.cc--banner){min-height:18.125rem}.cc__top{display:flex;align-items:flex-start;justify-content:space-between;gap:var(--spacing-padding-sys-padding-8)}.cc__top--label{justify-content:flex-start;align-items:center;gap:var(--spacing-padding-sys-padding-16)}.cc__category-label{background:transparent;padding:0;color:var(--accent-primary-sys-primary);font-family:var(--label-large-sys-font-family);font-size:var(--label-large-sys-font-size);line-height:var(--label-large-sys-line-height);letter-spacing:var(--label-large-sys-tracking);font-weight:var(--label-large-sys-font-weight-emphasized)}.cc__icon{display:inline-flex;align-items:center;justify-content:center;width:var(--sys-size-xl);height:var(--sys-size-xl);flex-shrink:0;border-radius:var(--border-radius-sys-radius-full);background-color:var(--accent-primary-sys-primary);color:var(--accent-primary-sys-on-primary);line-height:0}.cc__icon--neutral{background-color:var(--surface-surface-container-sys-surface-container-lowest);color:var(--surface-surface-sys-on-surface);border:var(--border-width-sys-stroke-thin) solid var(--outline-sys-outline)}.cc__banner{display:flex;align-items:center;justify-content:center;width:100%;height:120px;flex-shrink:0;overflow:hidden;border-radius:var(--border-radius-sys-radius-sm);background-color:var(--add-on-primary-fixed-sys-primary-fixed-dim);color:var(--add-on-primary-fixed-sys-on-primary-fixed)}.cc__banner-icon{display:inline-flex;line-height:0}.cc__container{display:flex;flex-direction:column;justify-content:space-between;flex:1 1 auto;gap:var(--spacing-padding-sys-padding-8);padding:var(--spacing-padding-sys-padding-8)}.cc__title-group{display:flex;flex-direction:column;gap:var(--spacing-padding-sys-padding-8)}.cc__category-eyebrow{margin:0;font-family:var(--label-medium-sys-font-family);font-size:var(--label-medium-sys-font-size);line-height:var(--label-medium-sys-line-height);letter-spacing:var(--label-medium-sys-tracking);color:var(--surface-surface-sys-on-surface-variant)}.cc--with-icon .cc__title{font-family:var(--label-large-sys-font-family);font-size:var(--label-large-sys-font-size);line-height:var(--label-large-sys-line-height);letter-spacing:var(--label-large-sys-tracking);font-weight:var(--label-large-sys-font-weight-emphasized);color:var(--surface-surface-sys-on-surface)}.cc--inline-icon .cc__container{flex:0 0 auto;margin-top:auto}.cc__top-end{display:inline-flex;align-items:center;gap:var(--spacing-padding-sys-padding-8)}.cc__arrow{display:inline-flex;color:var(--surface-surface-sys-on-surface-variant);flex-shrink:0;line-height:0}.cc__text{display:flex;flex-direction:column;gap:var(--spacing-padding-sys-padding-12)}.cc__heading{display:flex;flex-direction:column;gap:var(--spacing-padding-sys-padding-4)}.cc__title{margin:0;font-family:var(--title-small-sys-font-family);font-size:var(--title-small-sys-font-size);line-height:var(--title-small-sys-line-height);font-weight:var(--title-small-sys-font-weight-emphasized);letter-spacing:var(--title-small-sys-tracking);color:var(--surface-surface-sys-on-surface);display:-webkit-box;-webkit-box-orient:vertical;-webkit-line-clamp:4;overflow:hidden}.cc__subtitle{margin:0;font-family:var(--title-small-sys-font-family);font-size:var(--title-small-sys-font-size);line-height:var(--title-small-sys-line-height);font-weight:var(--title-small-sys-font-weight-emphasized);letter-spacing:var(--title-small-sys-tracking);color:var(--surface-surface-sys-on-surface-variant)}.cc__desc{margin:0;font-family:var(--body-medium-sys-font-family);font-size:var(--body-medium-sys-font-size);line-height:var(--body-medium-sys-line-height);letter-spacing:var(--body-medium-sys-tracking);color:var(--surface-surface-sys-on-surface-variant);display:-webkit-box;-webkit-box-orient:vertical;-webkit-line-clamp:3;overflow:hidden}.cc__chip{display:inline-flex;align-items:center;padding:var(--spacing-padding-sys-padding-2) var(--spacing-padding-sys-padding-12);border-radius:var(--border-radius-sys-radius-full);background-color:var(--custom-info-sys-info-container);color:var(--custom-info-sys-on-info-container);font-family:var(--label-medium-sys-font-family);font-size:var(--label-medium-sys-font-size);line-height:var(--label-medium-sys-line-height);white-space:nowrap}.cc__chip--glass{background-color:var(--transparent-neutral-sys-white-20);color:var(--accent-primary-sys-on-primary);-webkit-backdrop-filter:blur(.375rem);backdrop-filter:blur(.375rem)}.cc--filled .cc__icon{background-color:var(--surface-surface-container-sys-surface-container-lowest);color:var(--accent-primary-sys-primary)}.cc--filled .cc__title{color:var(--accent-primary-sys-on-primary-container)}.cc--filled .cc__subtitle,.cc--filled .cc__desc,.cc--filled .cc__arrow{color:var(--accent-primary-sys-on-primary-container-variant)}.cc--banner{position:relative;display:flex;flex-direction:column;flex:1 1 auto;min-height:12.5rem;justify-content:space-between;gap:var(--spacing-padding-sys-padding-24);padding:var(--spacing-padding-sys-padding-24)}.cc__media-icon{display:inline-flex;flex-shrink:0;color:var(--accent-primary-sys-on-primary);line-height:0}.cc__img-top{display:flex;flex-direction:column;align-items:flex-start;gap:var(--spacing-padding-sys-padding-12)}.cc__img-foot{display:flex;align-items:flex-end;justify-content:space-between;gap:var(--spacing-padding-sys-padding-16)}.cc__img-foot--end{justify-content:flex-end}.cc__banner-text{display:flex;flex-direction:column;gap:var(--spacing-padding-sys-padding-8);min-width:0}.cc__headline{margin:0;font-family:var(--headline-large-sys-font-family);font-size:var(--headline-large-sys-font-size);line-height:var(--headline-large-sys-line-height);font-weight:var(--headline-large-sys-font-weight);letter-spacing:var(--headline-large-sys-tracking);color:var(--accent-primary-sys-on-primary)}:host.cmp-card--outlined .cc__headline{color:var(--surface-surface-sys-on-surface)}.cc__img-foot compsych-button{align-self:flex-end;flex-shrink:0}@container (max-width: 36rem){.cc__img-foot{flex-direction:column;align-items:flex-start}.cc__img-foot compsych-button{align-self:flex-start}}.cc--banner .cc__title,.cc--banner .cc__arrow{color:var(--accent-primary-sys-on-primary)}.cc--banner .cc__subtitle{color:var(--transparent-neutral-sys-white-80)}.cc--banner .cc__desc{color:var(--accent-primary-sys-on-primary-container-variant)}.cc__metrics{display:flex;flex-wrap:wrap;gap:var(--spacing-padding-sys-padding-8)}.cc__metrics compsych-card{flex:0 0 auto;width:8rem}.cc__headline-desc{margin:0;font-family:var(--body-medium-sys-font-family);font-size:var(--body-medium-sys-font-size);line-height:var(--body-medium-sys-line-height);letter-spacing:var(--body-medium-sys-tracking);color:var(--transparent-neutral-sys-white-80)}.ac{display:flex;flex:1 1 auto;align-items:center;gap:var(--spacing-padding-sys-padding-16);font-family:var(--body-medium-sys-font-family)}.ac__icon{display:inline-flex;align-items:center;justify-content:center;flex-shrink:0;color:var(--surface-surface-sys-on-surface);line-height:0}.ac__text{display:flex;flex-direction:column;gap:var(--spacing-padding-sys-padding-4);flex:1 1 auto;min-width:0}.ac__label{margin:0;font-family:var(--label-large-sys-font-family);font-size:var(--label-large-sys-font-size);line-height:var(--label-large-sys-line-height);font-weight:var(--label-large-sys-font-weight-emphasized);letter-spacing:var(--label-large-sys-tracking);color:var(--surface-surface-sys-on-surface)}.ac__desc{font-family:var(--body-small-sys-font-family);font-size:var(--body-small-sys-font-size);line-height:var(--body-small-sys-line-height);letter-spacing:var(--body-small-sys-tracking);color:var(--surface-surface-sys-on-surface-variant)}.ac__arrow{display:inline-flex;flex-shrink:0;color:var(--surface-surface-sys-on-surface-variant);line-height:0}.ac--no-desc .ac__label{line-height:1}.ac--vertical{flex-direction:column;align-items:flex-start;justify-content:flex-start;gap:var(--spacing-padding-sys-padding-16)}.ac__badge{display:inline-flex;align-items:center;justify-content:center;width:var(--sys-size-xl);height:var(--sys-size-xl);flex-shrink:0;border-radius:var(--border-radius-sys-radius-full);background-color:var(--surface-surface-container-sys-surface-container);color:var(--surface-surface-sys-on-surface);transition:background-color .14s ease-out;line-height:0}:host(:hover) .ac__badge{background-color:var(--surface-surface-container-sys-surface-container-lowest)}.ac--vertical .ac__label{white-space:pre-line;overflow:visible;font-size:var(--title-small-sys-font-size);line-height:var(--title-small-sys-line-height);font-weight:var(--title-small-sys-font-weight)}@media(prefers-reduced-motion:reduce){.ac__badge{transition:none}}.mc{display:flex;flex:1 1 auto;flex-direction:column;align-items:center;justify-content:center;gap:var(--spacing-padding-sys-padding-8);text-align:center;font-family:var(--body-medium-sys-font-family)}.mc__value{font-family:var(--headline-medium-sys-font-family);font-size:var(--headline-medium-sys-font-size);line-height:var(--headline-medium-sys-line-height);font-weight:var(--headline-medium-sys-font-weight);letter-spacing:var(--headline-medium-sys-tracking);color:var(--surface-surface-sys-on-surface)}.mc__label{font-family:var(--label-large-sys-font-family);font-size:var(--label-large-sys-font-size);line-height:var(--label-large-sys-line-height);font-weight:var(--label-large-sys-font-weight);letter-spacing:var(--label-large-sys-tracking);color:var(--surface-surface-sys-on-surface)}.mc--current .mc__value,.mc--current .mc__label{color:var(--accent-primary-sys-primary)}.mc--current .mc__value{font-weight:var(--headline-medium-sys-font-weight-emphasized)}.mc--current .mc__label{font-weight:var(--label-large-sys-font-weight-emphasized)}:host.cmp-card--metric{box-shadow:0 2px 2px #0000000f,0 2px 4px #0000000a}:host.cmp-card--metric-sm .mc{gap:var(--spacing-padding-sys-padding-4)}:host.cmp-card--metric-sm .mc__value{font-size:var(--headline-small-sys-font-size);line-height:var(--headline-small-sys-line-height);letter-spacing:var(--headline-small-sys-tracking);font-weight:var(--headline-small-sys-font-weight)}:host.cmp-card--metric-sm .mc--current .mc__value{font-weight:var(--headline-small-sys-font-weight-emphasized)}:host.cmp-card--metric-sm .mc__label{font-size:var(--label-medium-sys-font-size);line-height:var(--label-medium-sys-line-height);letter-spacing:var(--label-medium-sys-tracking);font-weight:var(--label-medium-sys-font-weight)}:host.cmp-card--metric-sm .mc--current .mc__label{font-weight:var(--label-medium-sys-font-weight-emphasized)}:host.cmp-card--metric.cmp-card--current{box-shadow:0 0 0 var(--spacing-padding-sys-padding-4) var(--transparent-primary-sys-primary-08)}.bc{display:flex;flex-direction:column;flex:1 1 auto;gap:var(--spacing-padding-sys-padding-48);padding:var(--spacing-padding-sys-padding-32);font-family:var(--body-medium-sys-font-family)}.bc__top{display:flex;align-items:flex-start;justify-content:space-between;gap:var(--spacing-padding-sys-padding-8)}.bc__icon{display:inline-flex;flex-shrink:0;color:var(--surface-surface-sys-on-surface);line-height:0}.bc__icon--badge{align-items:center;justify-content:center;width:60px;height:60px;border-radius:var(--border-radius-sys-radius-full);background-color:var(--accent-primary-sys-primary);color:var(--accent-primary-sys-on-primary)}.bc__top-end{display:inline-flex;align-items:center;gap:var(--spacing-padding-sys-padding-8)}.bc__arrow{display:inline-flex;flex-shrink:0;color:var(--surface-surface-sys-on-surface-variant);line-height:0}.bc__chip{display:inline-flex;align-items:center;padding:var(--spacing-padding-sys-padding-4) var(--spacing-padding-sys-padding-12);border-radius:var(--border-radius-sys-radius-full);background-color:var(--custom-info-sys-info-container);color:var(--custom-info-sys-on-info-container);font-family:var(--label-medium-sys-font-family);font-size:var(--label-medium-sys-font-size);line-height:var(--label-medium-sys-line-height);white-space:nowrap}.bc__body{display:flex;flex-direction:column;gap:var(--spacing-padding-sys-padding-24)}.bc__text{display:flex;flex-direction:column;gap:var(--spacing-padding-sys-padding-12)}.bc__heading{display:flex;flex-direction:column;gap:var(--spacing-padding-sys-padding-4)}.bc__eyebrow{margin:0;font-family:var(--label-medium-sys-font-family);font-size:var(--label-medium-sys-font-size);line-height:var(--label-medium-sys-line-height);letter-spacing:var(--label-medium-sys-tracking);color:var(--surface-surface-sys-on-surface-variant)}.bc__title{margin:0;font-family:var(--title-medium-sys-font-family);font-size:var(--title-medium-sys-font-size);line-height:var(--title-medium-sys-line-height);letter-spacing:var(--title-medium-sys-tracking);font-weight:var(--title-medium-sys-font-weight);color:var(--surface-surface-sys-on-surface)}.bc__subtitle{margin:0;font-family:var(--title-medium-sys-font-family);font-size:var(--title-medium-sys-font-size);line-height:var(--title-medium-sys-line-height);letter-spacing:var(--title-medium-sys-tracking);font-weight:var(--title-medium-sys-font-weight);color:var(--surface-surface-sys-on-surface-variant)}.bc__desc{margin:0;font-family:var(--body-medium-sys-font-family);font-size:var(--body-medium-sys-font-size);line-height:var(--body-medium-sys-line-height);letter-spacing:var(--body-medium-sys-tracking);color:var(--surface-surface-sys-on-surface-variant)}:host.cmp-card--gradient.cmp-card--basic:not([data-card-size=xs]):not([data-card-size=lg]){background-image:none;border-radius:var(--border-radius-sys-radius-xl)}:host.cmp-card--gradient.cmp-card--basic:not([data-card-size=xs]):not([data-card-size=lg]) .cmp-card__body{padding:var(--spacing-padding-sys-padding-8)}:host.cmp-card--gradient.cmp-card--basic:not([data-card-size=xs]):not([data-card-size=lg]) .bc{gap:var(--spacing-padding-sys-padding-32);padding:var(--spacing-padding-sys-padding-24);border-radius:var(--border-radius-sys-radius-lg);background-image:linear-gradient(180deg,var(--transparent-primary-sys-primary-08) 0%,var(--transparent-neutral-sys-white-10) 100%)}.bc--banner{justify-content:space-between;gap:var(--spacing-padding-sys-padding-12);min-height:15.25rem}.bc--banner .bc__title{color:var(--accent-primary-sys-on-primary)}.bc--banner .bc__subtitle{color:var(--transparent-neutral-sys-white-80)}.bc--banner .bc__desc{color:var(--transparent-neutral-sys-white-50)}.bc--banner .bc__arrow{align-self:flex-end;color:var(--accent-primary-sys-on-primary)}:host.cmp-card--banner .bc--row .bc__title,:host.cmp-card--banner .bc--row .bc__icon,:host.cmp-card--banner .bc--row .bc__arrow{color:var(--accent-primary-sys-on-primary)}:host[data-card-size=sm] .bc{gap:var(--spacing-padding-sys-padding-40);padding:var(--spacing-padding-sys-padding-24)}:host[data-card-size=sm] .bc__title,:host[data-card-size=sm] .bc__subtitle{font-family:var(--title-small-sys-font-family);font-size:var(--title-small-sys-font-size);line-height:var(--title-small-sys-line-height);letter-spacing:var(--title-small-sys-tracking);font-weight:var(--title-small-sys-font-weight)}:host[data-card-size=sm] .bc__desc{font-family:var(--body-small-sys-font-family);font-size:var(--body-small-sys-font-size);line-height:var(--body-small-sys-line-height);letter-spacing:var(--body-small-sys-tracking)}:host[data-card-size=xs]{border-radius:var(--border-radius-sys-radius-md)}.bc--row{flex-direction:row;align-items:center;gap:var(--spacing-padding-sys-padding-12);padding:var(--spacing-padding-sys-padding-16)}.bc--row .bc__icon{color:var(--surface-surface-sys-on-surface)}.bc--row .bc__row-text{flex:1 1 auto;min-width:0}.bc--row .bc__title{font-family:var(--body-medium-sys-font-family);font-size:var(--body-medium-sys-font-size);line-height:var(--body-medium-sys-line-height);letter-spacing:var(--body-medium-sys-tracking);font-weight:var(--body-medium-sys-font-weight)}.bc--promo{justify-content:space-between;gap:var(--spacing-padding-sys-padding-24)}.bc--promo .bc__chip{align-self:flex-start}.bc--promo compsych-button{align-self:flex-end}.bc--promo.bc--banner .bc__title{color:var(--accent-primary-sys-on-primary)}.bc--promo.bc--banner .bc__subtitle{color:var(--transparent-neutral-sys-white-80)}.bc--promo.bc--banner .bc__desc{color:var(--transparent-neutral-sys-white-50)}:host.cmp-card--filled .bc__title,:host.cmp-card--filled .bc__icon{color:var(--accent-primary-sys-on-primary-container)}:host.cmp-card--filled .bc__eyebrow,:host.cmp-card--filled .bc__subtitle,:host.cmp-card--filled .bc__desc,:host.cmp-card--filled .bc__arrow{color:var(--accent-primary-sys-on-primary-container-variant)}\n"] }]
|
|
249
|
+
}], ctorParameters: () => [], propDecorators: { variant: [{ type: i0.Input, args: [{ isSignal: true, alias: "variant", required: false }] }], appearance: [{ type: i0.Input, args: [{ isSignal: true, alias: "appearance", required: false }] }], radius: [{ type: i0.Input, args: [{ isSignal: true, alias: "radius", required: false }] }], padding: [{ type: i0.Input, args: [{ isSignal: true, alias: "padding", required: false }] }], size: [{ type: i0.Input, args: [{ isSignal: true, alias: "size", required: false }] }], interactive: [{ type: i0.Input, args: [{ isSignal: true, alias: "interactive", required: false }] }], disabled: [{ type: i0.Input, args: [{ isSignal: true, alias: "disabled", required: false }] }], selected: [{ type: i0.Input, args: [{ isSignal: true, alias: "selected", required: false }] }], imageSrc: [{ type: i0.Input, args: [{ isSignal: true, alias: "imageSrc", required: false }] }], hideImage: [{ type: i0.Input, args: [{ isSignal: true, alias: "hideImage", required: false }] }], imagePosition: [{ type: i0.Input, args: [{ isSignal: true, alias: "imagePosition", required: false }] }], icon: [{ type: i0.Input, args: [{ isSignal: true, alias: "icon", required: false }] }], category: [{ type: i0.Input, args: [{ isSignal: true, alias: "category", required: false }] }], categoryStyle: [{ type: i0.Input, args: [{ isSignal: true, alias: "categoryStyle", required: false }] }], iconStyle: [{ type: i0.Input, args: [{ isSignal: true, alias: "iconStyle", required: false }] }], title: [{ type: i0.Input, args: [{ isSignal: true, alias: "title", required: false }] }], subtitle: [{ type: i0.Input, args: [{ isSignal: true, alias: "subtitle", required: false }] }], description: [{ type: i0.Input, args: [{ isSignal: true, alias: "description", required: false }] }], headline: [{ type: i0.Input, args: [{ isSignal: true, alias: "headline", required: false }] }], headlineDescription: [{ type: i0.Input, args: [{ isSignal: true, alias: "headlineDescription", required: false }] }], metrics: [{ type: i0.Input, args: [{ isSignal: true, alias: "metrics", required: false }] }], actionLabel: [{ type: i0.Input, args: [{ isSignal: true, alias: "actionLabel", required: false }] }], actionLeadingIcon: [{ type: i0.Input, args: [{ isSignal: true, alias: "actionLeadingIcon", required: false }] }], actionTrailingIcon: [{ type: i0.Input, args: [{ isSignal: true, alias: "actionTrailingIcon", required: false }] }], inlineIcon: [{ type: i0.Input, args: [{ isSignal: true, alias: "inlineIcon", required: false }] }], showArrow: [{ type: i0.Input, args: [{ isSignal: true, alias: "showArrow", required: false }] }], showGradient: [{ type: i0.Input, args: [{ isSignal: true, alias: "showGradient", required: false }] }], compact: [{ type: i0.Input, args: [{ isSignal: true, alias: "compact", required: false }] }], darkBackground: [{ type: i0.Input, args: [{ isSignal: true, alias: "darkBackground", required: false }] }], label: [{ type: i0.Input, args: [{ isSignal: true, alias: "label", required: false }] }], trailingIcon: [{ type: i0.Input, args: [{ isSignal: true, alias: "trailingIcon", required: false }] }], orientation: [{ type: i0.Input, args: [{ isSignal: true, alias: "orientation", required: false }] }], fullWidth: [{ type: i0.Input, args: [{ isSignal: true, alias: "fullWidth", required: false }] }], metricSize: [{ type: i0.Input, args: [{ isSignal: true, alias: "metricSize", required: false }] }], value: [{ type: i0.Input, args: [{ isSignal: true, alias: "value", required: false }] }], current: [{ type: i0.Input, args: [{ isSignal: true, alias: "current", required: false }] }], headingLevel: [{ type: i0.Input, args: [{ isSignal: true, alias: "headingLevel", required: false }] }], ariaLabel: [{ type: i0.Input, args: [{ isSignal: true, alias: "aria-label", required: false }] }], cardClick: [{ type: i0.Output, args: ["cardClick"] }], actionClick: [{ type: i0.Output, args: ["actionClick"] }] } });
|
|
222
250
|
//# sourceMappingURL=card.js.map
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"card.js","sourceRoot":"","sources":["../../../../../../packages/angular/src/lib/card-base/card.ts","../../../../../../packages/angular/src/lib/card-base/card.html"],"names":[],"mappings":"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","sourcesContent":["import {\r\n ChangeDetectionStrategy,\r\n Component,\r\n computed,\r\n effect,\r\n inject,\r\n input,\r\n output,\r\n} from '@angular/core';\r\nimport { NgTemplateOutlet } from '@angular/common';\r\nimport { DomSanitizer, SafeHtml } from '@angular/platform-browser';\r\nimport { LUCIDE_ICONS } from '@compsych-ui-components/shared/assets/lucide-icons.generated';\r\nimport { RippleDirective } from './ripple.directive';\r\n\r\n/**\r\n * Card type — selects the projected/laid-out content. Mirrors the library's `variant` pattern.\r\n * `basic` is the Figma \"cards\" section (the \"Card Item\" family: icon + arrow +\r\n * title/subtitle, sized, across the outlined/filled/gradient/image surfaces) —\r\n * distinct from the `content` category tiles.\r\n */\r\nexport type CardVariant = 'basic' | 'content' | 'action' | 'metric';\r\n/** Visual surface treatment. Mirrors the Figma \"Card Item\" Style property. */\r\nexport type CardAppearance = 'outlined' | 'filled' | 'gradient' | 'image';\r\n/** Corner radius token: `md` (12px), `lg` (16px), `xl` (24px). */\r\nexport type CardRadius = 'md' | 'lg' | 'xl';\r\n/** Inner padding token (used by `variant=\"basic\"`; typed variants size themselves). */\r\nexport type CardPadding = 'none' | 'sm' | 'md' | 'lg' | 'xl';\r\n/** Action-card layout. */\r\nexport type CardOrientation = 'horizontal' | 'vertical';\r\n/** Base Card Item size (Figma \"Size\" property). Drives layout + type scale. */\r\nexport type CardSize = 'xl' | 'lg' | 'md' | 'sm' | 'xs';\r\n/** Heading level for the title / hero headline / action label (screen-reader heading semantics). */\r\nexport type CardHeadingLevel = 2 | 3 | 4 | 5 | 6;\r\n/** How the content-variant category renders: trailing pill (`chip`) or leading plain-text `label`. */\r\nexport type CardCategoryStyle = 'chip' | 'label';\r\n/**\r\n * Content-variant icon badge treatment:\r\n * - `primary` — white icon on a filled primary (blue) circle (default).\r\n * - `neutral` — dark (on-surface) icon on a white circle with a thin outline.\r\n */\r\nexport type CardIconStyle = 'primary' | 'neutral';\r\n\r\n/**\r\n * Card — the single Cards component for the ComPsych Design System.\r\n *\r\n * Figma: Core Components — \"Cards\" (file VFBn7KCDy3FSIlvhNo3ylq, 1117:9829).\r\n *\r\n * One component, switched by `variant` (like Accordion's `variant`):\r\n * - `basic` — a bare surface; project your own content.\r\n * - `content` — icon badge / image, category chip, title, subtitle, description,\r\n * action pill, arrow; hero (`headline`) layout.\r\n * - `action` — compact interactive row (icon · label/description · arrow); horizontal/vertical.\r\n * - `metric` — centered value + label; `current` (selected) state.\r\n *\r\n * `appearance` is the orthogonal surface skin (outlined / filled / gradient / image).\r\n * When `interactive`, the whole card is a button (role/tabindex/keyboard) with the\r\n * hover / focus / pressed ripple. All values are sys design tokens.\r\n *\r\n * <compsych-card variant=\"content\" appearance=\"gradient\" icon=\"circle-play\"\r\n * category=\"Video\" title=\"Mindful breathing\" actionLabel=\"Watch\" [interactive]=\"true\" />\r\n * <compsych-card variant=\"metric\" value=\"24\" label=\"Sessions\" [current]=\"true\" [interactive]=\"true\" />\r\n * <compsych-card>Projected content</compsych-card>\r\n */\r\n@Component({\r\n selector: 'compsych-card',\r\n standalone: true,\r\n changeDetection: ChangeDetectionStrategy.OnPush,\r\n imports: [NgTemplateOutlet],\r\n hostDirectives: [RippleDirective],\r\n templateUrl: './card.html',\r\n styleUrl: './card.css',\r\n host: {\r\n class: 'cmp-card',\r\n '[class.cmp-card--outlined]': \"appearance() === 'outlined'\",\r\n '[class.cmp-card--filled]': \"appearance() === 'filled'\",\r\n '[class.cmp-card--gradient]': \"appearance() === 'gradient'\",\r\n '[class.cmp-card--image]': \"appearance() === 'image'\",\r\n '[class.cmp-card--content]': \"variant() === 'content'\",\r\n '[class.cmp-card--basic]': \"variant() === 'basic'\",\r\n '[attr.data-card-size]': \"variant() === 'basic' ? size() : null\",\r\n '[class.cmp-card--hero]': \"variant() === 'content' && !!headline()\",\r\n '[class.cmp-card--metric]': \"variant() === 'metric'\",\r\n '[class.cmp-card--current]': \"variant() === 'metric' && current()\",\r\n '[class.cmp-card--radius-md]': \"radius() === 'md'\",\r\n '[class.cmp-card--radius-lg]': \"radius() === 'lg'\",\r\n '[class.cmp-card--radius-xl]': \"radius() === 'xl'\",\r\n '[class.cmp-card--pad-none]': \"effectivePadding() === 'none'\",\r\n '[class.cmp-card--pad-sm]': \"effectivePadding() === 'sm'\",\r\n '[class.cmp-card--pad-md]': \"effectivePadding() === 'md'\",\r\n '[class.cmp-card--pad-lg]': \"effectivePadding() === 'lg'\",\r\n '[class.cmp-card--pad-xl]': \"effectivePadding() === 'xl'\",\r\n '[style.width]': \"fullWidth() ? '100%' : null\",\r\n '[class.cmp-card--interactive]': 'interactive()',\r\n '[class.cmp-card--disabled]': 'disabled()',\r\n '[class.cmp-card--selected]': 'selected()',\r\n '[class.cmp-card--no-gradient]': '!showGradient()',\r\n '[class.cmp-card--compact]': 'compact()',\r\n '[attr.role]': \"interactive() ? 'button' : null\",\r\n '[attr.tabindex]': 'interactive() && !disabled() ? 0 : null',\r\n '[attr.aria-label]': 'ariaLabel() ?? null',\r\n '[attr.aria-disabled]': 'disabled() || null',\r\n '[attr.aria-pressed]': \"interactive() && variant() === 'metric' ? current() : null\",\r\n '[style.border-color]': \"variant() === 'metric' && current() ? 'var(--accent-primary-sys-primary)' : null\",\r\n '[style.border-width]': \"variant() === 'metric' && current() ? 'var(--border-width-sys-stroke-thick)' : null\",\r\n '(click)': 'onActivate()',\r\n '(keydown)': 'onKeyDown($event)',\r\n },\r\n})\r\nexport class CardComponent {\r\n // ── Surface (all variants) ──────────────────────────────\r\n /** Card type. Defaults to `basic` (projected content). */\r\n readonly variant = input<CardVariant>('basic');\r\n /** Surface treatment. Defaults to `outlined`. */\r\n readonly appearance = input<CardAppearance>('outlined');\r\n /** Corner radius token. Defaults to `lg` (16px). */\r\n readonly radius = input<CardRadius>('lg');\r\n /** Inner padding for `variant=\"basic\"`. Typed variants size themselves. */\r\n readonly padding = input<CardPadding>('lg');\r\n /** Card Item size (`variant=\"basic\"`): xl/lg/md/sm/xs. Defaults to `md`. */\r\n readonly size = input<CardSize>('md');\r\n /** Whole-card click target: adds role/tabindex, hover/press states and ripple. */\r\n readonly interactive = input<boolean>(false);\r\n /** Disabled visual + non-interactive. */\r\n readonly disabled = input<boolean>(false);\r\n /** Applies the focused (blue outline) appearance. Useful for action cards to indicate selection. */\r\n readonly selected = input<boolean>(false);\r\n /** Background image URL for `appearance=\"image\"`. */\r\n readonly imageSrc = input<string>('');\r\n /**\r\n * `background-position` for the `image` appearance media (e.g. `'85% 0'` for an\r\n * off-center hero). Defaults to `'center'` — unchanged from before.\r\n */\r\n readonly imagePosition = input<string>('center');\r\n\r\n // ── Content variant ─────────────────────────────────────\r\n /** Lucide icon name (content badge / action leading icon). */\r\n readonly icon = input<string>('');\r\n /** Content: category chip text. */\r\n readonly category = input<string>('');\r\n /**\r\n * Content: how the category renders — `'chip'` (default) as the trailing pill,\r\n * or `'label'` as a leading plain-text label beside the icon.\r\n */\r\n readonly categoryStyle = input<CardCategoryStyle>('chip');\r\n /**\r\n * Content: icon badge treatment — `'primary'` (default) is a white icon on a\r\n * filled primary (blue) circle; `'neutral'` is a dark icon on a white circle\r\n * with a thin outline.\r\n */\r\n readonly iconStyle = input<CardIconStyle>('primary');\r\n /** Content: title. */\r\n readonly title = input<string>('');\r\n /** Content: subtitle. */\r\n readonly subtitle = input<string>('');\r\n /** Content/action: supporting description. */\r\n readonly description = input<string>('');\r\n /** Content: large hero display text (switches to the XL hero layout). */\r\n readonly headline = input<string>('');\r\n /** Content: presentational action pill label. */\r\n readonly actionLabel = input<string>('');\r\n /** Content: show the trailing arrow-up-right affordance. */\r\n readonly showArrow = input<boolean>(true);\r\n /** Content (gradient): show the inner gradient panel background. Set to `false` to render a flat surface. */\r\n readonly showGradient = input<boolean>(true);\r\n /** Content: remove the fixed min-height so the card sizes to its content. */\r\n readonly compact = input<boolean>(false);\r\n\r\n // ── Action variant ──────────────────────────────────────\r\n /** Action/metric: primary label. */\r\n readonly label = input<string>('');\r\n /** Action: trailing Lucide icon (horizontal layout). */\r\n readonly trailingIcon = input<string>('arrow-up-right');\r\n /** Action: layout orientation. */\r\n readonly orientation = input<CardOrientation>('horizontal');\r\n /** Action: stretch the card to 100% of its container width. */\r\n readonly fullWidth = input<boolean>(false);\r\n\r\n // ── Metric variant ──────────────────────────────────────\r\n /** Metric: the prominent value. */\r\n readonly value = input<string | number>('');\r\n /** Metric: selected/current state (primary border + text). */\r\n readonly current = input<boolean>(false);\r\n\r\n // ── Accessibility ───────────────────────────────────────\r\n /**\r\n * Opts the title / hero headline / action label into a heading in the\r\n * accessibility tree via `role=\"heading\"` + `aria-level`, so consumers that\r\n * replace real headings keep heading semantics and screen-reader heading\r\n * navigation (WCAG 1.3.1). Omit (default) to render as plain text — no visual\r\n * or behavioral change for existing usages.\r\n */\r\n readonly headingLevel = input<CardHeadingLevel | undefined>(undefined);\r\n /**\r\n * Accessible name for an `interactive` card (which is a `role=\"button\"`).\r\n * Required for image-only / icon-only interactive cards that have no text, and\r\n * useful to give text-heavy cards a concise name instead of their full content.\r\n * Bind as `aria-label`.\r\n */\r\n readonly ariaLabel = input<string | undefined>(undefined, { alias: 'aria-label' });\r\n\r\n /** Emits on click / Enter / Space when interactive and not disabled. */\r\n readonly cardClick = output<void>();\r\n\r\n private readonly sanitizer = inject(DomSanitizer);\r\n private readonly ripple = inject(RippleDirective);\r\n\r\n readonly isImage = computed(() => this.appearance() === 'image');\r\n\r\n /**\r\n * Heading level actually applied. Suppressed when the whole card is interactive\r\n * (`role=\"button\"`), since a heading nested in a button isn't exposed as a\r\n * heading — the two would conflict.\r\n */\r\n readonly effectiveHeadingLevel = computed(() =>\r\n this.interactive() ? undefined : this.headingLevel(),\r\n );\r\n\r\n /** Base Card Item plain-icon glyph size by `size` (48 md, 32 sm, 24 xs). */\r\n readonly basicIconSize = computed(() => (this.size() === 'sm' ? 32 : this.size() === 'xs' ? 24 : 48));\r\n /** Base Card Item arrow glyph size by `size` (24 md, 20 sm/xs). */\r\n readonly basicArrowSize = computed(() => (this.size() === 'md' ? 24 : 20));\r\n\r\n /** CSS `url(...)` for the media layer, or null when no image is set. */\r\n readonly mediaUrl = computed(() => {\r\n const src = this.imageSrc();\r\n return src ? `url(\"${src}\")` : null;\r\n });\r\n\r\n /** Padding resolved per variant; `basic` honors the `padding` input. */\r\n readonly effectivePadding = computed<CardPadding>(() => {\r\n switch (this.variant()) {\r\n case 'content':\r\n return this.isImage() || this.headline() ? 'none' : 'sm';\r\n case 'action':\r\n return 'lg'; // 24px — Figma action card (60017:8036)\r\n case 'basic':\r\n return 'none'; // .bc controls its own padding per style (Figma Base Card Item)\r\n case 'metric':\r\n return 'lg'; // 24px — Figma metric card (60024:10073)\r\n default:\r\n return this.padding();\r\n }\r\n });\r\n\r\n constructor() {\r\n effect(() => {\r\n this.ripple.suppressed = !this.interactive() || this.disabled();\r\n });\r\n }\r\n\r\n onActivate(): void {\r\n if (!this.interactive() || this.disabled()) return;\r\n this.cardClick.emit();\r\n }\r\n\r\n onKeyDown(event: KeyboardEvent): void {\r\n if (!this.interactive() || this.disabled()) return;\r\n if (event.repeat) return;\r\n if (event.key !== 'Enter' && event.key !== ' ') return;\r\n event.preventDefault();\r\n this.cardClick.emit();\r\n }\r\n\r\n /** Renders a sized/weighted Lucide SVG for template use. */\r\n iconSvg(name: string, size: number, strokeWidth = 1.75): SafeHtml {\r\n let svg = LUCIDE_ICONS[name] ?? '';\r\n svg = svg.replace('<svg ', `<svg width=\"${size}\" height=\"${size}\" `);\r\n if (strokeWidth !== 1.5) {\r\n svg = svg.replace('stroke-width=\"1.5\"', `stroke-width=\"${strokeWidth}\"`);\r\n }\r\n return this.sanitizer.bypassSecurityTrustHtml(svg);\r\n }\r\n}\r\n","@if (isImage() && mediaUrl()) {\r\n <div class=\"cmp-card__media\" [style.background-image]=\"mediaUrl()\" [style.background-position]=\"imagePosition()\"></div>\r\n <div class=\"cmp-card__scrim\" aria-hidden=\"true\"></div>\r\n}\r\n\r\n<div class=\"cmp-card__body\">\r\n @switch (variant()) {\r\n @case ('content') {\r\n @if (headline()) {\r\n <!-- Hero (image/filled): icon top-left, eyebrow + display headline + action bottom. -->\r\n <div class=\"cc cc--hero\" [class.cc--image]=\"isImage()\" [class.cc--filled]=\"appearance() === 'filled'\">\r\n @if (icon()) {\r\n @if (isImage()) {\r\n <div class=\"cc__media-icon\" [innerHTML]=\"iconSvg(icon(), 48)\" aria-hidden=\"true\"></div>\r\n } @else {\r\n <div class=\"cc__icon\" [class.cc__icon--neutral]=\"iconStyle() === 'neutral'\" [innerHTML]=\"iconSvg(icon(), 24)\" aria-hidden=\"true\"></div>\r\n }\r\n }\r\n <div class=\"cc__img-foot\">\r\n <div class=\"cc__hero-text\">\r\n @if (title()) { <p class=\"cc__eyebrow\">{{ title() }}</p> }\r\n <ng-container [ngTemplateOutlet]=\"headlineTpl\" />\r\n @if (description()) { <p class=\"cc__desc\">{{ description() }}</p> }\r\n </div>\r\n @if (actionLabel()) {\r\n <span class=\"cc__button cc__button--solid\">{{ actionLabel() }}</span>\r\n } @else if (showArrow()) {\r\n <span class=\"cc__arrow\" [innerHTML]=\"iconSvg('arrow-up-right', 24)\" aria-hidden=\"true\"></span>\r\n }\r\n </div>\r\n </div>\r\n } @else if (isImage()) {\r\n <div class=\"cc cc--image\">\r\n <div class=\"cc__img-top\">\r\n @if (icon()) {\r\n <div class=\"cc__media-icon\" [innerHTML]=\"iconSvg(icon(), 48)\" aria-hidden=\"true\"></div>\r\n }\r\n @if (category()) { <span class=\"cc__chip cc__chip--glass\">{{ category() }}</span> }\r\n </div>\r\n <div class=\"cc__img-foot\">\r\n @if (title() || subtitle() || description()) {\r\n <div class=\"cc__hero-text\">\r\n @if (title() || subtitle()) {\r\n <div class=\"cc__heading\">\r\n @if (title()) { <ng-container [ngTemplateOutlet]=\"titleTpl\" /> }\r\n @if (subtitle()) { <p class=\"cc__subtitle\">{{ subtitle() }}</p> }\r\n </div>\r\n }\r\n @if (description()) { <p class=\"cc__desc\">{{ description() }}</p> }\r\n </div>\r\n }\r\n @if (actionLabel()) {\r\n <span class=\"cc__button cc__button--solid\">{{ actionLabel() }}</span>\r\n } @else if (showArrow()) {\r\n <span class=\"cc__arrow\" [innerHTML]=\"iconSvg('arrow-up-right', 24)\" aria-hidden=\"true\"></span>\r\n }\r\n </div>\r\n </div>\r\n } @else if (appearance() === 'gradient') {\r\n <div class=\"cc\" [class.cc--filled]=\"appearance() === 'filled'\">\r\n <div class=\"cc__top\" [class.cc__top--label]=\"categoryStyle() === 'label'\">\r\n @if (icon()) {\r\n <div class=\"cc__icon\" [class.cc__icon--neutral]=\"iconStyle() === 'neutral'\" [innerHTML]=\"iconSvg(icon(), 24)\" aria-hidden=\"true\"></div>\r\n }\r\n @if (categoryStyle() === 'label' && category()) {\r\n <span class=\"cc__category-label\">{{ category() }}</span>\r\n }\r\n <div class=\"cc__top-end\">\r\n @if (categoryStyle() === 'chip' && category()) { <span class=\"cc__chip\">{{ category() }}</span> }\r\n @if (showArrow()) {\r\n <span class=\"cc__arrow\" [innerHTML]=\"iconSvg('arrow-up-right', 24)\" aria-hidden=\"true\"></span>\r\n }\r\n </div>\r\n </div>\r\n <div class=\"cc__text\">\r\n @if (title() || subtitle()) {\r\n <div class=\"cc__heading\">\r\n @if (title()) { <ng-container [ngTemplateOutlet]=\"titleTpl\" /> }\r\n @if (subtitle()) { <p class=\"cc__subtitle\">{{ subtitle() }}</p> }\r\n </div>\r\n }\r\n @if (description()) { <p class=\"cc__desc\">{{ description() }}</p> }\r\n </div>\r\n @if (actionLabel()) { <span class=\"cc__button\">{{ actionLabel() }}</span> }\r\n </div>\r\n } @else {\r\n <!-- With-icon content card (Figma 59444:2263): a full-width light-blue\r\n icon banner over a gray category eyebrow + title + body, with the\r\n text distributed top/bottom. Default for outlined/filled content. -->\r\n <div class=\"cc cc--with-icon\" [class.cc--filled]=\"appearance() === 'filled'\">\r\n <div class=\"cc__banner\">\r\n @if (icon()) {\r\n <span class=\"cc__banner-icon\" [innerHTML]=\"iconSvg(icon(), 48, 1.5)\" aria-hidden=\"true\"></span>\r\n }\r\n </div>\r\n <div class=\"cc__container\">\r\n <div class=\"cc__title-group\">\r\n @if (category()) { <p class=\"cc__category-eyebrow\">{{ category() }}</p> }\r\n @if (title()) { <ng-container [ngTemplateOutlet]=\"titleTpl\" /> }\r\n </div>\r\n @if (description()) { <p class=\"cc__desc\">{{ description() }}</p> }\r\n </div>\r\n </div>\r\n }\r\n }\r\n\r\n @case ('action') {\r\n @if (orientation() === 'vertical') {\r\n <div class=\"ac ac--vertical\" [class.ac--no-desc]=\"!description()\">\r\n @if (icon()) {\r\n <div class=\"ac__badge\" [innerHTML]=\"iconSvg(icon(), 24, 1.5)\" aria-hidden=\"true\"></div>\r\n }\r\n <div class=\"ac__text\">\r\n <ng-container [ngTemplateOutlet]=\"labelTpl\" />\r\n @if (description()) { <span class=\"ac__desc\">{{ description() }}</span> }\r\n </div>\r\n </div>\r\n } @else {\r\n <div class=\"ac\" [class.ac--no-desc]=\"!description()\">\r\n @if (icon()) {\r\n <div class=\"ac__icon\" [innerHTML]=\"iconSvg(icon(), 32)\" aria-hidden=\"true\"></div>\r\n }\r\n <div class=\"ac__text\">\r\n <ng-container [ngTemplateOutlet]=\"labelTpl\" />\r\n @if (description()) { <span class=\"ac__desc\">{{ description() }}</span> }\r\n </div>\r\n </div>\r\n }\r\n }\r\n\r\n @case ('metric') {\r\n <div class=\"mc\" [class.mc--current]=\"current()\">\r\n <span class=\"mc__value\">{{ value() }}</span>\r\n @if (label()) { <span class=\"mc__label\">{{ label() }}</span> }\r\n </div>\r\n }\r\n\r\n @case ('basic') {\r\n @if (size() === 'xs') {\r\n <!-- xs base card (Figma 243:3264): compact horizontal row — icon · title · arrow. -->\r\n <div class=\"bc bc--row\">\r\n @if (icon()) {\r\n <div class=\"bc__icon\" [innerHTML]=\"iconSvg(icon(), 24, 1.5)\" aria-hidden=\"true\"></div>\r\n }\r\n <div class=\"bc__row-text\">\r\n @if (title()) { <ng-container [ngTemplateOutlet]=\"bcTitleTpl\" /> }\r\n </div>\r\n @if (showArrow()) {\r\n <span class=\"bc__arrow\" [innerHTML]=\"iconSvg('arrow-up-right', 20)\" aria-hidden=\"true\"></span>\r\n }\r\n </div>\r\n } @else if (size() === 'lg') {\r\n <!-- lg base card (Figma 243:3205): text + optional chip, button bottom-right. -->\r\n <div class=\"bc bc--promo\" [class.bc--image]=\"isImage()\">\r\n <div class=\"bc__text\">\r\n @if (label()) { <p class=\"bc__eyebrow\">{{ label() }}</p> }\r\n @if (title() || subtitle()) {\r\n <div class=\"bc__heading\">\r\n @if (title()) { <ng-container [ngTemplateOutlet]=\"bcTitleTpl\" /> }\r\n @if (subtitle()) { <p class=\"bc__subtitle\">{{ subtitle() }}</p> }\r\n </div>\r\n }\r\n @if (description()) { <p class=\"bc__desc\">{{ description() }}</p> }\r\n @if (category()) { <span class=\"bc__chip\">{{ category() }}</span> }\r\n </div>\r\n @if (actionLabel()) { <span class=\"bc__button bc__button--end\">{{ actionLabel() }}</span> }\r\n </div>\r\n } @else if (isImage()) {\r\n <!-- md image base card (Figma 59442:12042): text over the image, arrow bottom-right. -->\r\n <div class=\"bc bc--image\">\r\n <div class=\"bc__text\">\r\n @if (title() || subtitle()) {\r\n <div class=\"bc__heading\">\r\n @if (title()) { <ng-container [ngTemplateOutlet]=\"bcTitleTpl\" /> }\r\n @if (subtitle()) { <p class=\"bc__subtitle\">{{ subtitle() }}</p> }\r\n </div>\r\n }\r\n @if (description()) { <p class=\"bc__desc\">{{ description() }}</p> }\r\n </div>\r\n @if (showArrow()) {\r\n <span class=\"bc__arrow\" [innerHTML]=\"iconSvg('arrow-up-right', basicArrowSize())\" aria-hidden=\"true\"></span>\r\n }\r\n </div>\r\n } @else {\r\n <!-- md / sm base card (Figma 243:3174, 243:3179, 947:8067):\r\n icon + arrow row, then eyebrow / title / subtitle / description / button. -->\r\n <div class=\"bc\">\r\n <div class=\"bc__top\">\r\n @if (icon()) {\r\n @if (appearance() === 'gradient') {\r\n <div class=\"bc__icon bc__icon--badge\" [innerHTML]=\"iconSvg(icon(), 32)\" aria-hidden=\"true\"></div>\r\n } @else {\r\n <div class=\"bc__icon\" [innerHTML]=\"iconSvg(icon(), basicIconSize(), 1.5)\" aria-hidden=\"true\"></div>\r\n }\r\n }\r\n <div class=\"bc__top-end\">\r\n @if (category()) { <span class=\"bc__chip\">{{ category() }}</span> }\r\n @if (showArrow()) {\r\n <span class=\"bc__arrow\" [innerHTML]=\"iconSvg('arrow-up-right', basicArrowSize())\" aria-hidden=\"true\"></span>\r\n }\r\n </div>\r\n </div>\r\n <div class=\"bc__body\">\r\n <div class=\"bc__text\">\r\n @if (label()) { <p class=\"bc__eyebrow\">{{ label() }}</p> }\r\n @if (title() || subtitle()) {\r\n <div class=\"bc__heading\">\r\n @if (title()) { <ng-container [ngTemplateOutlet]=\"bcTitleTpl\" /> }\r\n @if (subtitle()) { <p class=\"bc__subtitle\">{{ subtitle() }}</p> }\r\n </div>\r\n }\r\n @if (description()) { <p class=\"bc__desc\">{{ description() }}</p> }\r\n </div>\r\n @if (actionLabel()) { <span class=\"bc__button\">{{ actionLabel() }}</span> }\r\n </div>\r\n </div>\r\n }\r\n }\r\n\r\n @default {\r\n <ng-content />\r\n }\r\n }\r\n</div>\r\n\r\n<!-- Heading fragments: render a real <h2>–<h6> when `headingLevel` is set, else the\r\n original <p>/<span>. Shared across layouts so semantics stay consistent and the\r\n cc__title / cc__headline / ac__label styling is unchanged. -->\r\n<ng-template #titleTpl>\r\n @switch (effectiveHeadingLevel()) {\r\n @case (2) { <h2 class=\"cc__title\">{{ title() }}</h2> }\r\n @case (3) { <h3 class=\"cc__title\">{{ title() }}</h3> }\r\n @case (4) { <h4 class=\"cc__title\">{{ title() }}</h4> }\r\n @case (5) { <h5 class=\"cc__title\">{{ title() }}</h5> }\r\n @case (6) { <h6 class=\"cc__title\">{{ title() }}</h6> }\r\n @default { <p class=\"cc__title\">{{ title() }}</p> }\r\n }\r\n</ng-template>\r\n\r\n<ng-template #headlineTpl>\r\n @switch (effectiveHeadingLevel()) {\r\n @case (2) { <h2 class=\"cc__headline\">{{ headline() }}</h2> }\r\n @case (3) { <h3 class=\"cc__headline\">{{ headline() }}</h3> }\r\n @case (4) { <h4 class=\"cc__headline\">{{ headline() }}</h4> }\r\n @case (5) { <h5 class=\"cc__headline\">{{ headline() }}</h5> }\r\n @case (6) { <h6 class=\"cc__headline\">{{ headline() }}</h6> }\r\n @default { <p class=\"cc__headline\">{{ headline() }}</p> }\r\n }\r\n</ng-template>\r\n\r\n<ng-template #labelTpl>\r\n @switch (effectiveHeadingLevel()) {\r\n @case (2) { <h2 class=\"ac__label\">{{ label() }}</h2> }\r\n @case (3) { <h3 class=\"ac__label\">{{ label() }}</h3> }\r\n @case (4) { <h4 class=\"ac__label\">{{ label() }}</h4> }\r\n @case (5) { <h5 class=\"ac__label\">{{ label() }}</h5> }\r\n @case (6) { <h6 class=\"ac__label\">{{ label() }}</h6> }\r\n @default { <span class=\"ac__label\">{{ label() }}</span> }\r\n }\r\n</ng-template>\r\n\r\n<ng-template #bcTitleTpl>\r\n @switch (effectiveHeadingLevel()) {\r\n @case (2) { <h2 class=\"bc__title\">{{ title() }}</h2> }\r\n @case (3) { <h3 class=\"bc__title\">{{ title() }}</h3> }\r\n @case (4) { <h4 class=\"bc__title\">{{ title() }}</h4> }\r\n @case (5) { <h5 class=\"bc__title\">{{ title() }}</h5> }\r\n @case (6) { <h6 class=\"bc__title\">{{ title() }}</h6> }\r\n @default { <p class=\"bc__title\">{{ title() }}</p> }\r\n }\r\n</ng-template>\r\n"]}
|
|
1
|
+
{"version":3,"file":"card.js","sourceRoot":"","sources":["../../../../../../packages/angular/src/lib/card-base/card.ts","../../../../../../packages/angular/src/lib/card-base/card.html"],"names":[],"mappings":"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","sourcesContent":["import {\r\n ChangeDetectionStrategy,\r\n Component,\r\n computed,\r\n effect,\r\n inject,\r\n input,\r\n output,\r\n} from '@angular/core';\r\nimport { NgTemplateOutlet } from '@angular/common';\r\nimport { DomSanitizer, SafeHtml } from '@angular/platform-browser';\r\nimport { LUCIDE_ICONS } from '@compsych-ui-components/shared/assets/lucide-icons.generated';\r\nimport { RippleDirective } from './ripple.directive';\r\nimport { ButtonComponent } from '../button/button';\r\n\r\n/** A single metric item for the banner card's metric row. */\r\nexport interface BannerMetric {\r\n value: string | number;\r\n label?: string;\r\n /** Renders the metric in its primary-color \"current\" state. */\r\n current?: boolean;\r\n}\r\n\r\n/**\r\n * Card type — selects the projected/laid-out content. Mirrors the library's `variant` pattern.\r\n * `basic` is the Figma \"cards\" section (the \"Card Item\" family: icon + arrow +\r\n * title/subtitle, sized, across the outlined/filled/gradient/banner surfaces) —\r\n * distinct from the `content` category tiles.\r\n */\r\nexport type CardVariant = 'basic' | 'content' | 'action' | 'metric';\r\n/** Visual surface treatment. Mirrors the Figma \"Card Item\" Style property. */\r\nexport type CardAppearance = 'outlined' | 'filled' | 'gradient' | 'banner';\r\n/** Corner radius token: `md` (12px), `lg` (16px), `xl` (24px). */\r\nexport type CardRadius = 'md' | 'lg' | 'xl';\r\n/** Inner padding token (used by `variant=\"basic\"`; typed variants size themselves). */\r\nexport type CardPadding = 'none' | 'sm' | 'md' | 'lg' | 'xl';\r\n/** Action-card layout. */\r\nexport type CardOrientation = 'horizontal' | 'vertical';\r\n/** Metric-card size. `medium` is the default (24px padding, headline-medium value); `small` is compact (16px padding, headline-small value). */\r\nexport type CardMetricSize = 'medium' | 'small';\r\n/** Base Card Item size (Figma \"Size\" property). Drives layout + type scale. */\r\nexport type CardSize = 'xl' | 'lg' | 'md' | 'sm' | 'xs';\r\n/** Heading level for the title / headline / action label (screen-reader heading semantics). */\r\nexport type CardHeadingLevel = 2 | 3 | 4 | 5 | 6;\r\n/** How the content-variant category renders: trailing pill (`chip`) or leading plain-text `label`. */\r\nexport type CardCategoryStyle = 'chip' | 'label';\r\n/**\r\n * Content-variant icon badge treatment:\r\n * - `primary` — white icon on a filled primary (blue) circle (default).\r\n * - `neutral` — dark (on-surface) icon on a white circle with a thin outline.\r\n */\r\nexport type CardIconStyle = 'primary' | 'neutral';\r\n\r\n/**\r\n * Card — the single Cards component for the ComPsych Design System.\r\n *\r\n * Figma: Core Components — \"Cards\" (file VFBn7KCDy3FSIlvhNo3ylq, 1117:9829).\r\n *\r\n * One component, switched by `variant` (like Accordion's `variant`):\r\n * - `basic` — a bare surface; project your own content.\r\n * - `content` — icon badge / image, category chip, title, subtitle, description,\r\n * action pill, arrow; headline layout.\r\n * - `action` — compact interactive row (icon · label/description · arrow); horizontal/vertical.\r\n * - `metric` — centered value + label; `current` (selected) state.\r\n *\r\n * `appearance` is the orthogonal surface skin (outlined / filled / gradient / banner).\r\n * When `interactive`, the whole card is a button (role/tabindex/keyboard) with the\r\n * hover / focus / pressed ripple. All values are sys design tokens.\r\n *\r\n * <compsych-card variant=\"content\" appearance=\"gradient\" icon=\"circle-play\"\r\n * category=\"Video\" title=\"Mindful breathing\" actionLabel=\"Watch\" [interactive]=\"true\" />\r\n * <compsych-card variant=\"metric\" value=\"24\" label=\"Sessions\" [current]=\"true\" [interactive]=\"true\" />\r\n * <compsych-card>Projected content</compsych-card>\r\n */\r\n@Component({\r\n selector: 'compsych-card',\r\n standalone: true,\r\n changeDetection: ChangeDetectionStrategy.OnPush,\r\n imports: [NgTemplateOutlet, ButtonComponent, CardComponent],\r\n hostDirectives: [RippleDirective],\r\n templateUrl: './card.html',\r\n styleUrl: './card.css',\r\n host: {\r\n class: 'cmp-card',\r\n '[class.cmp-card--outlined]': \"appearance() === 'outlined'\",\r\n '[class.cmp-card--filled]': \"appearance() === 'filled'\",\r\n '[class.cmp-card--gradient]': \"appearance() === 'gradient'\",\r\n '[class.cmp-card--banner]': \"appearance() === 'banner'\",\r\n '[class.cmp-card--content]': \"variant() === 'content'\",\r\n '[class.cmp-card--basic]': \"variant() === 'basic'\",\r\n '[attr.data-card-size]': \"variant() === 'basic' ? size() : null\",\r\n '[class.cmp-card--metric]': \"variant() === 'metric'\",\r\n '[class.cmp-card--current]': \"variant() === 'metric' && current()\",\r\n '[class.cmp-card--radius-md]': \"radius() === 'md'\",\r\n '[class.cmp-card--radius-lg]': \"radius() === 'lg'\",\r\n '[class.cmp-card--radius-xl]': \"radius() === 'xl'\",\r\n '[class.cmp-card--pad-none]': \"effectivePadding() === 'none'\",\r\n '[class.cmp-card--pad-sm]': \"effectivePadding() === 'sm'\",\r\n '[class.cmp-card--pad-md]': \"effectivePadding() === 'md'\",\r\n '[class.cmp-card--pad-lg]': \"effectivePadding() === 'lg'\",\r\n '[class.cmp-card--pad-xl]': \"effectivePadding() === 'xl'\",\r\n '[style.width]': \"fullWidth() ? '100%' : null\",\r\n '[class.cmp-card--interactive]': 'interactive()',\r\n '[class.cmp-card--disabled]': 'disabled()',\r\n '[class.cmp-card--selected]': 'selected()',\r\n '[class.cmp-card--no-gradient]': '!showGradient()',\r\n '[class.cmp-card--compact]': 'compact()',\r\n '[class.cmp-card--metric-sm]': \"variant() === 'metric' && metricSize() === 'small'\",\r\n '[class.cmp-card--dark-bg]': 'darkBackground()',\r\n '[class.cmp-card--hide-image]': 'hideImage()',\r\n '[attr.role]': \"interactive() ? 'button' : null\",\r\n '[attr.tabindex]': 'interactive() && !disabled() ? 0 : null',\r\n '[attr.aria-label]': 'ariaLabel() ?? null',\r\n '[attr.aria-disabled]': 'disabled() || null',\r\n '[attr.aria-pressed]': \"interactive() && variant() === 'metric' ? current() : null\",\r\n '[style.border-color]': \"variant() === 'metric' && current() ? 'var(--accent-primary-sys-primary)' : null\",\r\n '[style.border-width]': \"variant() === 'metric' && current() ? 'var(--border-width-sys-stroke-thick)' : null\",\r\n '(click)': 'onActivate()',\r\n '(keydown)': 'onKeyDown($event)',\r\n },\r\n})\r\nexport class CardComponent {\r\n // ── Surface (all variants) ──────────────────────────────\r\n /** Card type. Defaults to `basic` (projected content). */\r\n readonly variant = input<CardVariant>('basic');\r\n /** Surface treatment. Defaults to `outlined`. */\r\n readonly appearance = input<CardAppearance>('outlined');\r\n /** Corner radius token. Defaults to `lg` (16px). */\r\n readonly radius = input<CardRadius>('lg');\r\n /** Inner padding for `variant=\"basic\"`. Typed variants size themselves. */\r\n readonly padding = input<CardPadding>('lg');\r\n /** Card Item size (`variant=\"basic\"`): xl/lg/md/sm/xs. Defaults to `md`. */\r\n readonly size = input<CardSize>('md');\r\n /** Whole-card click target: adds role/tabindex, hover/press states and ripple. */\r\n readonly interactive = input<boolean>(false);\r\n /** Disabled visual + non-interactive. */\r\n readonly disabled = input<boolean>(false);\r\n /** Applies the focused (blue outline) appearance. Useful for action cards to indicate selection. */\r\n readonly selected = input<boolean>(false);\r\n /** Background image URL for `appearance=\"banner\"`. */\r\n readonly imageSrc = input<string>('');\r\n /**\r\n * Hides the background image on an `appearance=\"banner\"` card and replaces it\r\n * with a `--accent-primary-sys-primary-container` solid background.\r\n */\r\n readonly hideImage = input<boolean>(false);\r\n /**\r\n * `background-position` for the `banner` appearance media (e.g. `'85% 0'` for an\r\n * off-center image). Defaults to `'center'`.\r\n */\r\n readonly imagePosition = input<string>('center');\r\n\r\n // ── Content variant ─────────────────────────────────────\r\n /** Lucide icon name (content badge / action leading icon). */\r\n readonly icon = input<string>('');\r\n /** Content: category chip text. */\r\n readonly category = input<string>('');\r\n /**\r\n * Content: how the category renders — `'chip'` (default) as the trailing pill,\r\n * or `'label'` as a leading plain-text label beside the icon.\r\n */\r\n readonly categoryStyle = input<CardCategoryStyle>('chip');\r\n /**\r\n * Content: icon badge treatment — `'primary'` (default) is a white icon on a\r\n * filled primary (blue) circle; `'neutral'` is a dark icon on a white circle\r\n * with a thin outline.\r\n */\r\n readonly iconStyle = input<CardIconStyle>('primary');\r\n /** Content: title. */\r\n readonly title = input<string>('');\r\n /** Content: subtitle. */\r\n readonly subtitle = input<string>('');\r\n /** Content/action: supporting description. */\r\n readonly description = input<string>('');\r\n /** Content: large display text for the headline layout. */\r\n readonly headline = input<string>('');\r\n /** Content (`appearance=\"banner\"`): supporting text rendered below the headline, in white-80. */\r\n readonly headlineDescription = input<string>('');\r\n /** Content (`appearance=\"banner\"`): metric cards rendered in a dark row below the headline description. */\r\n readonly metrics = input<BannerMetric[]>([]);\r\n /** Content: presentational action pill label. */\r\n readonly actionLabel = input<string>('');\r\n /** Content: leading Lucide icon name rendered inside the action pill. */\r\n readonly actionLeadingIcon = input<string>('');\r\n /** Content: trailing Lucide icon name rendered inside the action pill. */\r\n readonly actionTrailingIcon = input<string>('');\r\n /** Content (outlined/filled): when true, replaces the full-width banner with a plain icon in the top-left corner. */\r\n readonly inlineIcon = input<boolean>(false);\r\n /** Content: show the trailing arrow-up-right affordance. */\r\n readonly showArrow = input<boolean>(true);\r\n /** Content (gradient): show the inner gradient panel background. Set to `false` to render a flat surface. */\r\n readonly showGradient = input<boolean>(true);\r\n /** Content: remove the fixed min-height so the card sizes to its content. */\r\n readonly compact = input<boolean>(false);\r\n /**\r\n * Renders the card on a dark surface: background becomes\r\n * `--transparent-neutral-sys-white-20` (closest token to rgba(255,255,255,0.16))\r\n * and text color becomes white.\r\n */\r\n readonly darkBackground = input<boolean>(false);\r\n\r\n // ── Action variant ──────────────────────────────────────\r\n /** Action/metric: primary label. */\r\n readonly label = input<string>('');\r\n /** Action: trailing Lucide icon (horizontal layout). */\r\n readonly trailingIcon = input<string>('arrow-up-right');\r\n /** Action: layout orientation. */\r\n readonly orientation = input<CardOrientation>('horizontal');\r\n /** Action: stretch the card to 100% of its container width. */\r\n readonly fullWidth = input<boolean>(false);\r\n\r\n // ── Metric variant ──────────────────────────────────────\r\n /** Metric: size variant. Defaults to `medium`. */\r\n readonly metricSize = input<CardMetricSize>('medium');\r\n /** Metric: the prominent value. */\r\n readonly value = input<string | number>('');\r\n /** Metric: selected/current state (primary border + text). */\r\n readonly current = input<boolean>(false);\r\n\r\n // ── Accessibility ───────────────────────────────────────\r\n /**\r\n * Opts the title / headline / action label into a heading in the\r\n * accessibility tree via `role=\"heading\"` + `aria-level`, so consumers that\r\n * replace real headings keep heading semantics and screen-reader heading\r\n * navigation (WCAG 1.3.1). Omit (default) to render as plain text — no visual\r\n * or behavioral change for existing usages.\r\n */\r\n readonly headingLevel = input<CardHeadingLevel | undefined>(undefined);\r\n /**\r\n * Accessible name for an `interactive` card (which is a `role=\"button\"`).\r\n * Required for image-only / icon-only interactive cards that have no text, and\r\n * useful to give text-heavy cards a concise name instead of their full content.\r\n * Bind as `aria-label`.\r\n */\r\n readonly ariaLabel = input<string | undefined>(undefined, { alias: 'aria-label' });\r\n\r\n /** Emits on click / Enter / Space when interactive and not disabled. */\r\n readonly cardClick = output<void>();\r\n /** Emits when the banner card's action button is clicked. */\r\n readonly actionClick = output<void>();\r\n\r\n private readonly sanitizer = inject(DomSanitizer);\r\n private readonly ripple = inject(RippleDirective);\r\n\r\n readonly isBanner = computed(() => this.appearance() === 'banner');\r\n\r\n /**\r\n * Heading level actually applied. Suppressed when the whole card is interactive\r\n * (`role=\"button\"`), since a heading nested in a button isn't exposed as a\r\n * heading — the two would conflict.\r\n */\r\n readonly effectiveHeadingLevel = computed(() =>\r\n this.interactive() ? undefined : this.headingLevel(),\r\n );\r\n\r\n /** Base Card Item plain-icon glyph size by `size` (48 md, 32 sm, 24 xs). */\r\n readonly basicIconSize = computed(() => (this.size() === 'sm' ? 32 : this.size() === 'xs' ? 24 : 48));\r\n /** Base Card Item arrow glyph size by `size` (24 md, 20 sm/xs). */\r\n readonly basicArrowSize = computed(() => (this.size() === 'md' ? 24 : 20));\r\n\r\n /** CSS `url(...)` for the media layer, or null when no image is set. */\r\n readonly mediaUrl = computed(() => {\r\n const src = this.imageSrc();\r\n return src ? `url(\"${src}\")` : null;\r\n });\r\n\r\n /** Padding resolved per variant; `basic` honors the `padding` input. */\r\n readonly effectivePadding = computed<CardPadding>(() => {\r\n switch (this.variant()) {\r\n case 'content':\r\n return this.isBanner() ? 'none' : 'sm';\r\n case 'action':\r\n return 'lg'; // 24px — Figma action card (60017:8036)\r\n case 'basic':\r\n return 'none'; // .bc controls its own padding per style (Figma Base Card Item)\r\n case 'metric':\r\n return this.metricSize() === 'small' ? 'sm' : 'lg'; // sm=16px, lg=24px\r\n default:\r\n return this.padding();\r\n }\r\n });\r\n\r\n constructor() {\r\n effect(() => {\r\n this.ripple.suppressed = !this.interactive() || this.disabled();\r\n });\r\n }\r\n\r\n onActivate(): void {\r\n if (!this.interactive() || this.disabled()) return;\r\n this.cardClick.emit();\r\n }\r\n\r\n onKeyDown(event: KeyboardEvent): void {\r\n if (!this.interactive() || this.disabled()) return;\r\n if (event.repeat) return;\r\n if (event.key !== 'Enter' && event.key !== ' ') return;\r\n event.preventDefault();\r\n this.cardClick.emit();\r\n }\r\n\r\n /** Renders a sized/weighted Lucide SVG for template use. */\r\n iconSvg(name: string, size: number, strokeWidth = 1.75): SafeHtml {\r\n let svg = LUCIDE_ICONS[name] ?? '';\r\n svg = svg.replace('<svg ', `<svg width=\"${size}\" height=\"${size}\" `);\r\n if (strokeWidth !== 1.5) {\r\n svg = svg.replace('stroke-width=\"1.5\"', `stroke-width=\"${strokeWidth}\"`);\r\n }\r\n return this.sanitizer.bypassSecurityTrustHtml(svg);\r\n }\r\n}\r\n","@if (isBanner() && mediaUrl() && !hideImage()) {\n <div class=\"cmp-card__media\" [style.background-image]=\"mediaUrl()\" [style.background-position]=\"imagePosition()\"></div>\n <div class=\"cmp-card__scrim\" aria-hidden=\"true\"></div>\n}\n\n<div class=\"cmp-card__body\">\n @switch (variant()) {\n @case ('content') {\n @if (isBanner()) {\n <div class=\"cc cc--banner\">\n <div class=\"cc__img-top\">\n @if (icon()) {\n <div class=\"cc__media-icon\" [innerHTML]=\"iconSvg(icon(), 48)\" aria-hidden=\"true\"></div>\n }\n @if (category()) { <span class=\"cc__chip cc__chip--glass\">{{ category() }}</span> }\n </div>\n <div class=\"cc__img-foot\">\n @if (title() || subtitle() || headline() || description() || headlineDescription() || metrics().length) {\n <div class=\"cc__banner-text\">\n @if (title() || subtitle()) {\n <div class=\"cc__heading\">\n @if (title()) { <ng-container [ngTemplateOutlet]=\"headingTpl\" [ngTemplateOutletContext]=\"{ $implicit: 'cc__title', text: title() }\" /> }\n @if (subtitle()) { <p class=\"cc__subtitle\">{{ subtitle() }}</p> }\n </div>\n }\n @if (description()) { <p class=\"cc__desc\">{{ description() }}</p> }\n @if (headline()) { <ng-container [ngTemplateOutlet]=\"headingTpl\" [ngTemplateOutletContext]=\"{ $implicit: 'cc__headline', text: headline() }\" /> }\n @if (headlineDescription()) { <p class=\"cc__headline-desc\">{{ headlineDescription() }}</p> }\n @if (metrics().length) {\n <div class=\"cc__metrics\">\n @for (m of metrics(); track $index) {\n <compsych-card variant=\"metric\" [value]=\"m.value\" [label]=\"m.label ?? ''\" [current]=\"m.current ?? false\" [darkBackground]=\"true\" metricSize=\"small\" />\n }\n </div>\n }\n </div>\n }\n @if (actionLabel()) {\n <compsych-button variant=\"elevated\" [label]=\"actionLabel()\" [leadingIcon]=\"actionLeadingIcon()\" [trailingIcon]=\"actionTrailingIcon()\" (click)=\"actionClick.emit(); $event.stopPropagation()\" />\n } @else if (showArrow()) {\n <span class=\"cc__arrow\" [innerHTML]=\"iconSvg('arrow-up-right', 24)\" aria-hidden=\"true\"></span>\n }\n </div>\n </div>\n } @else if (appearance() === 'gradient') {\n <div class=\"cc\">\n <div class=\"cc__top\" [class.cc__top--label]=\"categoryStyle() === 'label'\">\n @if (icon()) {\n <div class=\"cc__icon\" [class.cc__icon--neutral]=\"iconStyle() === 'neutral'\" [innerHTML]=\"iconSvg(icon(), 24)\" aria-hidden=\"true\"></div>\n }\n @if (categoryStyle() === 'label' && category()) {\n <span class=\"cc__category-label\">{{ category() }}</span>\n }\n <div class=\"cc__top-end\">\n @if (categoryStyle() === 'chip' && category()) { <span class=\"cc__chip\">{{ category() }}</span> }\n @if (showArrow()) {\n <span class=\"cc__arrow\" [innerHTML]=\"iconSvg('arrow-up-right', 24)\" aria-hidden=\"true\"></span>\n }\n </div>\n </div>\n <div class=\"cc__text\">\n @if (title() || subtitle()) {\n <div class=\"cc__heading\">\n @if (title()) { <ng-container [ngTemplateOutlet]=\"headingTpl\" [ngTemplateOutletContext]=\"{ $implicit: 'cc__title', text: title() }\" /> }\n @if (subtitle()) { <p class=\"cc__subtitle\">{{ subtitle() }}</p> }\n </div>\n }\n @if (description()) { <p class=\"cc__desc\">{{ description() }}</p> }\n </div>\n @if (actionLabel()) {\n <compsych-button variant=\"outlined\" [label]=\"actionLabel()\" [leadingIcon]=\"actionLeadingIcon()\" [trailingIcon]=\"actionTrailingIcon()\" />\n }\n </div>\n } @else {\n <div class=\"cc cc--with-icon\" [class.cc--filled]=\"appearance() === 'filled'\" [class.cc--inline-icon]=\"inlineIcon()\">\n @if (inlineIcon()) {\n @if (icon()) {\n <span class=\"cc__banner-icon\" [innerHTML]=\"iconSvg(icon(), 32, 1.5)\" aria-hidden=\"true\"></span>\n }\n } @else {\n <div class=\"cc__banner\">\n @if (icon()) {\n <span class=\"cc__banner-icon\" [innerHTML]=\"iconSvg(icon(), 48, 1.5)\" aria-hidden=\"true\"></span>\n }\n </div>\n }\n <div class=\"cc__container\">\n <div class=\"cc__title-group\">\n @if (category()) { <p class=\"cc__category-eyebrow\">{{ category() }}</p> }\n @if (title()) { <ng-container [ngTemplateOutlet]=\"headingTpl\" [ngTemplateOutletContext]=\"{ $implicit: 'cc__title', text: title() }\" /> }\n </div>\n @if (description()) { <p class=\"cc__desc\">{{ description() }}</p> }\n @if (headline()) { <ng-container [ngTemplateOutlet]=\"headingTpl\" [ngTemplateOutletContext]=\"{ $implicit: 'cc__headline', text: headline() }\" /> }\n </div>\n </div>\n }\n }\n\n @case ('action') {\n @if (orientation() === 'vertical') {\n <div class=\"ac ac--vertical\" [class.ac--no-desc]=\"!description()\">\n @if (icon()) {\n <div class=\"ac__badge\" [innerHTML]=\"iconSvg(icon(), 24, 1.5)\" aria-hidden=\"true\"></div>\n }\n <div class=\"ac__text\">\n <ng-container [ngTemplateOutlet]=\"labelTpl\" />\n @if (description()) { <span class=\"ac__desc\">{{ description() }}</span> }\n </div>\n </div>\n } @else {\n <div class=\"ac\" [class.ac--no-desc]=\"!description()\">\n @if (icon()) {\n <div class=\"ac__icon\" [innerHTML]=\"iconSvg(icon(), 32)\" aria-hidden=\"true\"></div>\n }\n <div class=\"ac__text\">\n <ng-container [ngTemplateOutlet]=\"labelTpl\" />\n @if (description()) { <span class=\"ac__desc\">{{ description() }}</span> }\n </div>\n </div>\n }\n }\n\n @case ('metric') {\n <div class=\"mc\" [class.mc--current]=\"current()\">\n <span class=\"mc__value\">{{ value() }}</span>\n @if (label()) { <span class=\"mc__label\">{{ label() }}</span> }\n </div>\n }\n\n @case ('basic') {\n @if (size() === 'xs') {\n <!-- xs base card (Figma 243:3264): compact horizontal row — icon · title · arrow. -->\n <div class=\"bc bc--row\">\n @if (icon()) {\n <div class=\"bc__icon\" [innerHTML]=\"iconSvg(icon(), 24, 1.5)\" aria-hidden=\"true\"></div>\n }\n <div class=\"bc__row-text\">\n @if (title()) { <ng-container [ngTemplateOutlet]=\"headingTpl\" [ngTemplateOutletContext]=\"{ $implicit: 'bc__title', text: title() }\" /> }\n </div>\n @if (showArrow()) {\n <span class=\"bc__arrow\" [innerHTML]=\"iconSvg('arrow-up-right', 20)\" aria-hidden=\"true\"></span>\n }\n </div>\n } @else if (size() === 'lg') {\n <!-- lg base card (Figma 243:3205): text + optional chip, button bottom-right. -->\n <div class=\"bc bc--promo\" [class.bc--banner]=\"isBanner()\">\n <div class=\"bc__text\">\n @if (label()) { <p class=\"bc__eyebrow\">{{ label() }}</p> }\n @if (title() || subtitle()) {\n <div class=\"bc__heading\">\n @if (title()) { <ng-container [ngTemplateOutlet]=\"headingTpl\" [ngTemplateOutletContext]=\"{ $implicit: 'bc__title', text: title() }\" /> }\n @if (subtitle()) { <p class=\"bc__subtitle\">{{ subtitle() }}</p> }\n </div>\n }\n @if (description()) { <p class=\"bc__desc\">{{ description() }}</p> }\n @if (category()) { <span class=\"bc__chip\">{{ category() }}</span> }\n </div>\n @if (actionLabel()) { <compsych-button variant=\"outlined\" [label]=\"actionLabel()\" /> }\n </div>\n } @else if (isBanner()) {\n <!-- md banner base card (Figma 59442:12042): text over the image, arrow bottom-right. -->\n <div class=\"bc bc--banner\">\n <div class=\"bc__text\">\n @if (title() || subtitle()) {\n <div class=\"bc__heading\">\n @if (title()) { <ng-container [ngTemplateOutlet]=\"headingTpl\" [ngTemplateOutletContext]=\"{ $implicit: 'bc__title', text: title() }\" /> }\n @if (subtitle()) { <p class=\"bc__subtitle\">{{ subtitle() }}</p> }\n </div>\n }\n @if (description()) { <p class=\"bc__desc\">{{ description() }}</p> }\n </div>\n @if (showArrow()) {\n <span class=\"bc__arrow\" [innerHTML]=\"iconSvg('arrow-up-right', basicArrowSize())\" aria-hidden=\"true\"></span>\n }\n </div>\n } @else {\n <!-- md / sm base card (Figma 243:3174, 243:3179, 947:8067):\n icon + arrow row, then eyebrow / title / subtitle / description / button. -->\n <div class=\"bc\">\n <div class=\"bc__top\">\n @if (icon()) {\n @if (appearance() === 'gradient') {\n <div class=\"bc__icon bc__icon--badge\" [innerHTML]=\"iconSvg(icon(), 32)\" aria-hidden=\"true\"></div>\n } @else {\n <div class=\"bc__icon\" [innerHTML]=\"iconSvg(icon(), basicIconSize(), 1.5)\" aria-hidden=\"true\"></div>\n }\n }\n <div class=\"bc__top-end\">\n @if (category()) { <span class=\"bc__chip\">{{ category() }}</span> }\n @if (showArrow()) {\n <span class=\"bc__arrow\" [innerHTML]=\"iconSvg('arrow-up-right', basicArrowSize())\" aria-hidden=\"true\"></span>\n }\n </div>\n </div>\n <div class=\"bc__body\">\n <div class=\"bc__text\">\n @if (label()) { <p class=\"bc__eyebrow\">{{ label() }}</p> }\n @if (title() || subtitle()) {\n <div class=\"bc__heading\">\n @if (title()) { <ng-container [ngTemplateOutlet]=\"headingTpl\" [ngTemplateOutletContext]=\"{ $implicit: 'bc__title', text: title() }\" /> }\n @if (subtitle()) { <p class=\"bc__subtitle\">{{ subtitle() }}</p> }\n </div>\n }\n @if (description()) { <p class=\"bc__desc\">{{ description() }}</p> }\n </div>\n @if (actionLabel()) { <compsych-button variant=\"outlined\" [label]=\"actionLabel()\" /> }\n </div>\n </div>\n }\n }\n\n @default {\n <ng-content />\n }\n }\n</div>\n\n<!-- Heading fragment: renders <h2>–<h6> when headingLevel is set, else <p>.\n Pass $implicit = CSS class string, text = display text.\n Used by all title/headline slots across content and basic variants. -->\n<ng-template #headingTpl let-cls let-text=\"text\">\n @switch (effectiveHeadingLevel()) {\n @case (2) { <h2 [class]=\"cls\">{{ text }}</h2> }\n @case (3) { <h3 [class]=\"cls\">{{ text }}</h3> }\n @case (4) { <h4 [class]=\"cls\">{{ text }}</h4> }\n @case (5) { <h5 [class]=\"cls\">{{ text }}</h5> }\n @case (6) { <h6 [class]=\"cls\">{{ text }}</h6> }\n @default { <p [class]=\"cls\">{{ text }}</p> }\n }\n</ng-template>\n\n<!-- Action-card label: same heading-level logic but defaults to <span> (inline) not <p>. -->\n<ng-template #labelTpl>\n @switch (effectiveHeadingLevel()) {\n @case (2) { <h2 class=\"ac__label\">{{ label() }}</h2> }\n @case (3) { <h3 class=\"ac__label\">{{ label() }}</h3> }\n @case (4) { <h4 class=\"ac__label\">{{ label() }}</h4> }\n @case (5) { <h5 class=\"ac__label\">{{ label() }}</h5> }\n @case (6) { <h6 class=\"ac__label\">{{ label() }}</h6> }\n @default { <span class=\"ac__label\">{{ label() }}</span> }\n }\n</ng-template>\n"]}
|
package/index.d.ts
CHANGED
|
@@ -19,7 +19,7 @@ export type { HeaderNavLevel, NavAction } from './lib/header-nav/header-nav';
|
|
|
19
19
|
export { SidebarComponent } from './lib/sidebar/sidebar';
|
|
20
20
|
export type { SidebarItem } from './lib/sidebar/sidebar';
|
|
21
21
|
export { CardComponent } from './lib/card-base/card';
|
|
22
|
-
export type { CardVariant, CardAppearance, CardRadius, CardPadding, CardOrientation, CardSize, CardHeadingLevel, CardCategoryStyle, CardIconStyle } from './lib/card-base/card';
|
|
22
|
+
export type { CardVariant, CardAppearance, CardRadius, CardPadding, CardOrientation, CardSize, CardMetricSize, CardHeadingLevel, CardCategoryStyle, CardIconStyle, BannerMetric } from './lib/card-base/card';
|
|
23
23
|
export { RippleDirective } from './lib/card-base/ripple.directive';
|
|
24
24
|
export { TextInputComponent } from './lib/text-input/text-input';
|
|
25
25
|
export type { TextInputSize, TextInputType, TextInputLabelButton } from './lib/text-input/text-input';
|
package/lib/card-base/card.d.ts
CHANGED
|
@@ -1,24 +1,33 @@
|
|
|
1
1
|
import { SafeHtml } from '@angular/platform-browser';
|
|
2
2
|
import * as i0 from "@angular/core";
|
|
3
3
|
import * as i1 from "./ripple.directive";
|
|
4
|
+
/** A single metric item for the banner card's metric row. */
|
|
5
|
+
export interface BannerMetric {
|
|
6
|
+
value: string | number;
|
|
7
|
+
label?: string;
|
|
8
|
+
/** Renders the metric in its primary-color "current" state. */
|
|
9
|
+
current?: boolean;
|
|
10
|
+
}
|
|
4
11
|
/**
|
|
5
12
|
* Card type — selects the projected/laid-out content. Mirrors the library's `variant` pattern.
|
|
6
13
|
* `basic` is the Figma "cards" section (the "Card Item" family: icon + arrow +
|
|
7
|
-
* title/subtitle, sized, across the outlined/filled/gradient/
|
|
14
|
+
* title/subtitle, sized, across the outlined/filled/gradient/banner surfaces) —
|
|
8
15
|
* distinct from the `content` category tiles.
|
|
9
16
|
*/
|
|
10
17
|
export type CardVariant = 'basic' | 'content' | 'action' | 'metric';
|
|
11
18
|
/** Visual surface treatment. Mirrors the Figma "Card Item" Style property. */
|
|
12
|
-
export type CardAppearance = 'outlined' | 'filled' | 'gradient' | '
|
|
19
|
+
export type CardAppearance = 'outlined' | 'filled' | 'gradient' | 'banner';
|
|
13
20
|
/** Corner radius token: `md` (12px), `lg` (16px), `xl` (24px). */
|
|
14
21
|
export type CardRadius = 'md' | 'lg' | 'xl';
|
|
15
22
|
/** Inner padding token (used by `variant="basic"`; typed variants size themselves). */
|
|
16
23
|
export type CardPadding = 'none' | 'sm' | 'md' | 'lg' | 'xl';
|
|
17
24
|
/** Action-card layout. */
|
|
18
25
|
export type CardOrientation = 'horizontal' | 'vertical';
|
|
26
|
+
/** Metric-card size. `medium` is the default (24px padding, headline-medium value); `small` is compact (16px padding, headline-small value). */
|
|
27
|
+
export type CardMetricSize = 'medium' | 'small';
|
|
19
28
|
/** Base Card Item size (Figma "Size" property). Drives layout + type scale. */
|
|
20
29
|
export type CardSize = 'xl' | 'lg' | 'md' | 'sm' | 'xs';
|
|
21
|
-
/** Heading level for the title /
|
|
30
|
+
/** Heading level for the title / headline / action label (screen-reader heading semantics). */
|
|
22
31
|
export type CardHeadingLevel = 2 | 3 | 4 | 5 | 6;
|
|
23
32
|
/** How the content-variant category renders: trailing pill (`chip`) or leading plain-text `label`. */
|
|
24
33
|
export type CardCategoryStyle = 'chip' | 'label';
|
|
@@ -36,11 +45,11 @@ export type CardIconStyle = 'primary' | 'neutral';
|
|
|
36
45
|
* One component, switched by `variant` (like Accordion's `variant`):
|
|
37
46
|
* - `basic` — a bare surface; project your own content.
|
|
38
47
|
* - `content` — icon badge / image, category chip, title, subtitle, description,
|
|
39
|
-
* action pill, arrow;
|
|
48
|
+
* action pill, arrow; headline layout.
|
|
40
49
|
* - `action` — compact interactive row (icon · label/description · arrow); horizontal/vertical.
|
|
41
50
|
* - `metric` — centered value + label; `current` (selected) state.
|
|
42
51
|
*
|
|
43
|
-
* `appearance` is the orthogonal surface skin (outlined / filled / gradient /
|
|
52
|
+
* `appearance` is the orthogonal surface skin (outlined / filled / gradient / banner).
|
|
44
53
|
* When `interactive`, the whole card is a button (role/tabindex/keyboard) with the
|
|
45
54
|
* hover / focus / pressed ripple. All values are sys design tokens.
|
|
46
55
|
*
|
|
@@ -66,11 +75,16 @@ export declare class CardComponent {
|
|
|
66
75
|
readonly disabled: import("@angular/core").InputSignal<boolean>;
|
|
67
76
|
/** Applies the focused (blue outline) appearance. Useful for action cards to indicate selection. */
|
|
68
77
|
readonly selected: import("@angular/core").InputSignal<boolean>;
|
|
69
|
-
/** Background image URL for `appearance="
|
|
78
|
+
/** Background image URL for `appearance="banner"`. */
|
|
70
79
|
readonly imageSrc: import("@angular/core").InputSignal<string>;
|
|
71
80
|
/**
|
|
72
|
-
*
|
|
73
|
-
*
|
|
81
|
+
* Hides the background image on an `appearance="banner"` card and replaces it
|
|
82
|
+
* with a `--accent-primary-sys-primary-container` solid background.
|
|
83
|
+
*/
|
|
84
|
+
readonly hideImage: import("@angular/core").InputSignal<boolean>;
|
|
85
|
+
/**
|
|
86
|
+
* `background-position` for the `banner` appearance media (e.g. `'85% 0'` for an
|
|
87
|
+
* off-center image). Defaults to `'center'`.
|
|
74
88
|
*/
|
|
75
89
|
readonly imagePosition: import("@angular/core").InputSignal<string>;
|
|
76
90
|
/** Lucide icon name (content badge / action leading icon). */
|
|
@@ -94,16 +108,32 @@ export declare class CardComponent {
|
|
|
94
108
|
readonly subtitle: import("@angular/core").InputSignal<string>;
|
|
95
109
|
/** Content/action: supporting description. */
|
|
96
110
|
readonly description: import("@angular/core").InputSignal<string>;
|
|
97
|
-
/** Content: large
|
|
111
|
+
/** Content: large display text for the headline layout. */
|
|
98
112
|
readonly headline: import("@angular/core").InputSignal<string>;
|
|
113
|
+
/** Content (`appearance="banner"`): supporting text rendered below the headline, in white-80. */
|
|
114
|
+
readonly headlineDescription: import("@angular/core").InputSignal<string>;
|
|
115
|
+
/** Content (`appearance="banner"`): metric cards rendered in a dark row below the headline description. */
|
|
116
|
+
readonly metrics: import("@angular/core").InputSignal<BannerMetric[]>;
|
|
99
117
|
/** Content: presentational action pill label. */
|
|
100
118
|
readonly actionLabel: import("@angular/core").InputSignal<string>;
|
|
119
|
+
/** Content: leading Lucide icon name rendered inside the action pill. */
|
|
120
|
+
readonly actionLeadingIcon: import("@angular/core").InputSignal<string>;
|
|
121
|
+
/** Content: trailing Lucide icon name rendered inside the action pill. */
|
|
122
|
+
readonly actionTrailingIcon: import("@angular/core").InputSignal<string>;
|
|
123
|
+
/** Content (outlined/filled): when true, replaces the full-width banner with a plain icon in the top-left corner. */
|
|
124
|
+
readonly inlineIcon: import("@angular/core").InputSignal<boolean>;
|
|
101
125
|
/** Content: show the trailing arrow-up-right affordance. */
|
|
102
126
|
readonly showArrow: import("@angular/core").InputSignal<boolean>;
|
|
103
127
|
/** Content (gradient): show the inner gradient panel background. Set to `false` to render a flat surface. */
|
|
104
128
|
readonly showGradient: import("@angular/core").InputSignal<boolean>;
|
|
105
129
|
/** Content: remove the fixed min-height so the card sizes to its content. */
|
|
106
130
|
readonly compact: import("@angular/core").InputSignal<boolean>;
|
|
131
|
+
/**
|
|
132
|
+
* Renders the card on a dark surface: background becomes
|
|
133
|
+
* `--transparent-neutral-sys-white-20` (closest token to rgba(255,255,255,0.16))
|
|
134
|
+
* and text color becomes white.
|
|
135
|
+
*/
|
|
136
|
+
readonly darkBackground: import("@angular/core").InputSignal<boolean>;
|
|
107
137
|
/** Action/metric: primary label. */
|
|
108
138
|
readonly label: import("@angular/core").InputSignal<string>;
|
|
109
139
|
/** Action: trailing Lucide icon (horizontal layout). */
|
|
@@ -112,12 +142,14 @@ export declare class CardComponent {
|
|
|
112
142
|
readonly orientation: import("@angular/core").InputSignal<CardOrientation>;
|
|
113
143
|
/** Action: stretch the card to 100% of its container width. */
|
|
114
144
|
readonly fullWidth: import("@angular/core").InputSignal<boolean>;
|
|
145
|
+
/** Metric: size variant. Defaults to `medium`. */
|
|
146
|
+
readonly metricSize: import("@angular/core").InputSignal<CardMetricSize>;
|
|
115
147
|
/** Metric: the prominent value. */
|
|
116
148
|
readonly value: import("@angular/core").InputSignal<string | number>;
|
|
117
149
|
/** Metric: selected/current state (primary border + text). */
|
|
118
150
|
readonly current: import("@angular/core").InputSignal<boolean>;
|
|
119
151
|
/**
|
|
120
|
-
* Opts the title /
|
|
152
|
+
* Opts the title / headline / action label into a heading in the
|
|
121
153
|
* accessibility tree via `role="heading"` + `aria-level`, so consumers that
|
|
122
154
|
* replace real headings keep heading semantics and screen-reader heading
|
|
123
155
|
* navigation (WCAG 1.3.1). Omit (default) to render as plain text — no visual
|
|
@@ -133,9 +165,11 @@ export declare class CardComponent {
|
|
|
133
165
|
readonly ariaLabel: import("@angular/core").InputSignal<string | undefined>;
|
|
134
166
|
/** Emits on click / Enter / Space when interactive and not disabled. */
|
|
135
167
|
readonly cardClick: import("@angular/core").OutputEmitterRef<void>;
|
|
168
|
+
/** Emits when the banner card's action button is clicked. */
|
|
169
|
+
readonly actionClick: import("@angular/core").OutputEmitterRef<void>;
|
|
136
170
|
private readonly sanitizer;
|
|
137
171
|
private readonly ripple;
|
|
138
|
-
readonly
|
|
172
|
+
readonly isBanner: import("@angular/core").Signal<boolean>;
|
|
139
173
|
/**
|
|
140
174
|
* Heading level actually applied. Suppressed when the whole card is interactive
|
|
141
175
|
* (`role="button"`), since a heading nested in a button isn't exposed as a
|
|
@@ -156,5 +190,5 @@ export declare class CardComponent {
|
|
|
156
190
|
/** Renders a sized/weighted Lucide SVG for template use. */
|
|
157
191
|
iconSvg(name: string, size: number, strokeWidth?: number): SafeHtml;
|
|
158
192
|
static ɵfac: i0.ɵɵFactoryDeclaration<CardComponent, never>;
|
|
159
|
-
static ɵcmp: i0.ɵɵComponentDeclaration<CardComponent, "compsych-card", never, { "variant": { "alias": "variant"; "required": false; "isSignal": true; }; "appearance": { "alias": "appearance"; "required": false; "isSignal": true; }; "radius": { "alias": "radius"; "required": false; "isSignal": true; }; "padding": { "alias": "padding"; "required": false; "isSignal": true; }; "size": { "alias": "size"; "required": false; "isSignal": true; }; "interactive": { "alias": "interactive"; "required": false; "isSignal": true; }; "disabled": { "alias": "disabled"; "required": false; "isSignal": true; }; "selected": { "alias": "selected"; "required": false; "isSignal": true; }; "imageSrc": { "alias": "imageSrc"; "required": false; "isSignal": true; }; "imagePosition": { "alias": "imagePosition"; "required": false; "isSignal": true; }; "icon": { "alias": "icon"; "required": false; "isSignal": true; }; "category": { "alias": "category"; "required": false; "isSignal": true; }; "categoryStyle": { "alias": "categoryStyle"; "required": false; "isSignal": true; }; "iconStyle": { "alias": "iconStyle"; "required": false; "isSignal": true; }; "title": { "alias": "title"; "required": false; "isSignal": true; }; "subtitle": { "alias": "subtitle"; "required": false; "isSignal": true; }; "description": { "alias": "description"; "required": false; "isSignal": true; }; "headline": { "alias": "headline"; "required": false; "isSignal": true; }; "actionLabel": { "alias": "actionLabel"; "required": false; "isSignal": true; }; "showArrow": { "alias": "showArrow"; "required": false; "isSignal": true; }; "showGradient": { "alias": "showGradient"; "required": false; "isSignal": true; }; "compact": { "alias": "compact"; "required": false; "isSignal": true; }; "label": { "alias": "label"; "required": false; "isSignal": true; }; "trailingIcon": { "alias": "trailingIcon"; "required": false; "isSignal": true; }; "orientation": { "alias": "orientation"; "required": false; "isSignal": true; }; "fullWidth": { "alias": "fullWidth"; "required": false; "isSignal": true; }; "value": { "alias": "value"; "required": false; "isSignal": true; }; "current": { "alias": "current"; "required": false; "isSignal": true; }; "headingLevel": { "alias": "headingLevel"; "required": false; "isSignal": true; }; "ariaLabel": { "alias": "aria-label"; "required": false; "isSignal": true; }; }, { "cardClick": "cardClick"; }, never, ["*"], true, [{ directive: typeof i1.RippleDirective; inputs: {}; outputs: {}; }]>;
|
|
193
|
+
static ɵcmp: i0.ɵɵComponentDeclaration<CardComponent, "compsych-card", never, { "variant": { "alias": "variant"; "required": false; "isSignal": true; }; "appearance": { "alias": "appearance"; "required": false; "isSignal": true; }; "radius": { "alias": "radius"; "required": false; "isSignal": true; }; "padding": { "alias": "padding"; "required": false; "isSignal": true; }; "size": { "alias": "size"; "required": false; "isSignal": true; }; "interactive": { "alias": "interactive"; "required": false; "isSignal": true; }; "disabled": { "alias": "disabled"; "required": false; "isSignal": true; }; "selected": { "alias": "selected"; "required": false; "isSignal": true; }; "imageSrc": { "alias": "imageSrc"; "required": false; "isSignal": true; }; "hideImage": { "alias": "hideImage"; "required": false; "isSignal": true; }; "imagePosition": { "alias": "imagePosition"; "required": false; "isSignal": true; }; "icon": { "alias": "icon"; "required": false; "isSignal": true; }; "category": { "alias": "category"; "required": false; "isSignal": true; }; "categoryStyle": { "alias": "categoryStyle"; "required": false; "isSignal": true; }; "iconStyle": { "alias": "iconStyle"; "required": false; "isSignal": true; }; "title": { "alias": "title"; "required": false; "isSignal": true; }; "subtitle": { "alias": "subtitle"; "required": false; "isSignal": true; }; "description": { "alias": "description"; "required": false; "isSignal": true; }; "headline": { "alias": "headline"; "required": false; "isSignal": true; }; "headlineDescription": { "alias": "headlineDescription"; "required": false; "isSignal": true; }; "metrics": { "alias": "metrics"; "required": false; "isSignal": true; }; "actionLabel": { "alias": "actionLabel"; "required": false; "isSignal": true; }; "actionLeadingIcon": { "alias": "actionLeadingIcon"; "required": false; "isSignal": true; }; "actionTrailingIcon": { "alias": "actionTrailingIcon"; "required": false; "isSignal": true; }; "inlineIcon": { "alias": "inlineIcon"; "required": false; "isSignal": true; }; "showArrow": { "alias": "showArrow"; "required": false; "isSignal": true; }; "showGradient": { "alias": "showGradient"; "required": false; "isSignal": true; }; "compact": { "alias": "compact"; "required": false; "isSignal": true; }; "darkBackground": { "alias": "darkBackground"; "required": false; "isSignal": true; }; "label": { "alias": "label"; "required": false; "isSignal": true; }; "trailingIcon": { "alias": "trailingIcon"; "required": false; "isSignal": true; }; "orientation": { "alias": "orientation"; "required": false; "isSignal": true; }; "fullWidth": { "alias": "fullWidth"; "required": false; "isSignal": true; }; "metricSize": { "alias": "metricSize"; "required": false; "isSignal": true; }; "value": { "alias": "value"; "required": false; "isSignal": true; }; "current": { "alias": "current"; "required": false; "isSignal": true; }; "headingLevel": { "alias": "headingLevel"; "required": false; "isSignal": true; }; "ariaLabel": { "alias": "aria-label"; "required": false; "isSignal": true; }; }, { "cardClick": "cardClick"; "actionClick": "actionClick"; }, never, ["*"], true, [{ directive: typeof i1.RippleDirective; inputs: {}; outputs: {}; }]>;
|
|
160
194
|
}
|