@ds-mo/ui 13.4.0 → 13.5.0

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
Files changed (85) hide show
  1. package/dist/.package-ready.json +1 -1
  2. package/dist/agent-patterns.json +1 -1
  3. package/dist/agent.json +19 -21
  4. package/dist/components/ds-card-overview.js +1 -1
  5. package/dist/components/ds-card-overview.js.map +1 -1
  6. package/dist/components/ds-input.js +1 -1
  7. package/dist/components/ds-input.js.map +1 -1
  8. package/dist/components/ds-select.js +1 -1
  9. package/dist/components/ds-select.js.map +1 -1
  10. package/dist/docs/components.json +10 -16
  11. package/dist/mcp-data/registry/agent-activity.json +1 -1
  12. package/dist/mcp-data/registry/agent-response.json +1 -1
  13. package/dist/mcp-data/registry/agent-source-list.json +1 -1
  14. package/dist/mcp-data/registry/agent-tool-call.json +1 -1
  15. package/dist/mcp-data/registry/attachment-list.json +1 -1
  16. package/dist/mcp-data/registry/avatar.json +1 -1
  17. package/dist/mcp-data/registry/badge.json +1 -1
  18. package/dist/mcp-data/registry/bar-nav.json +1 -1
  19. package/dist/mcp-data/registry/bar-title.json +1 -1
  20. package/dist/mcp-data/registry/bar-workflow.json +1 -1
  21. package/dist/mcp-data/registry/breadcrumb.json +1 -1
  22. package/dist/mcp-data/registry/button-filled.json +1 -1
  23. package/dist/mcp-data/registry/button-unfilled.json +1 -1
  24. package/dist/mcp-data/registry/card-data-viz.json +1 -1
  25. package/dist/mcp-data/registry/card-overview.json +33 -35
  26. package/dist/mcp-data/registry/card-setting.json +1 -1
  27. package/dist/mcp-data/registry/chart-bar.json +1 -1
  28. package/dist/mcp-data/registry/chart-donut.json +1 -1
  29. package/dist/mcp-data/registry/chart-legend.json +1 -1
  30. package/dist/mcp-data/registry/chart-line.json +1 -1
  31. package/dist/mcp-data/registry/checkbox.json +1 -1
  32. package/dist/mcp-data/registry/chip.json +1 -1
  33. package/dist/mcp-data/registry/code-block.json +1 -1
  34. package/dist/mcp-data/registry/conversation-list-item.json +1 -1
  35. package/dist/mcp-data/registry/conversation-list-section.json +1 -1
  36. package/dist/mcp-data/registry/conversation-list.json +1 -1
  37. package/dist/mcp-data/registry/divider.json +1 -1
  38. package/dist/mcp-data/registry/empty-state.json +1 -1
  39. package/dist/mcp-data/registry/field.json +1 -1
  40. package/dist/mcp-data/registry/icon.json +1 -1
  41. package/dist/mcp-data/registry/input.json +6 -6
  42. package/dist/mcp-data/registry/loader.json +1 -1
  43. package/dist/mcp-data/registry/markdown.json +1 -1
  44. package/dist/mcp-data/registry/menu.json +1 -1
  45. package/dist/mcp-data/registry/message-actions.json +1 -1
  46. package/dist/mcp-data/registry/message-bubble.json +1 -1
  47. package/dist/mcp-data/registry/message-composer.json +1 -1
  48. package/dist/mcp-data/registry/message-scroller.json +1 -1
  49. package/dist/mcp-data/registry/message.json +1 -1
  50. package/dist/mcp-data/registry/mobile-bar-nav.json +1 -1
  51. package/dist/mcp-data/registry/mobile-header.json +1 -1
  52. package/dist/mcp-data/registry/mobile-section-switcher.json +1 -1
  53. package/dist/mcp-data/registry/mobile-sheet-nav.json +1 -1
  54. package/dist/mcp-data/registry/modal.json +1 -1
  55. package/dist/mcp-data/registry/panel-nav.json +1 -1
  56. package/dist/mcp-data/registry/panel-sub-nav.json +1 -1
  57. package/dist/mcp-data/registry/panel-tool-header.json +1 -1
  58. package/dist/mcp-data/registry/panel-tool-search.json +1 -1
  59. package/dist/mcp-data/registry/panel-tools.json +1 -1
  60. package/dist/mcp-data/registry/radio.json +1 -1
  61. package/dist/mcp-data/registry/registry.json +19 -21
  62. package/dist/mcp-data/registry/scroll-overlay.json +1 -1
  63. package/dist/mcp-data/registry/select.json +5 -5
  64. package/dist/mcp-data/registry/shell-app.json +1 -1
  65. package/dist/mcp-data/registry/shell-page.json +1 -1
  66. package/dist/mcp-data/registry/shell-tools.json +1 -1
  67. package/dist/mcp-data/registry/skeleton.json +1 -1
  68. package/dist/mcp-data/registry/slider.json +1 -1
  69. package/dist/mcp-data/registry/swatch-picker.json +1 -1
  70. package/dist/mcp-data/registry/switch.json +1 -1
  71. package/dist/mcp-data/registry/tab-group.json +1 -1
  72. package/dist/mcp-data/registry/tag.json +1 -1
  73. package/dist/mcp-data/registry/text.json +1 -1
  74. package/dist/mcp-data/registry/toast.json +1 -1
  75. package/dist/mcp-data/registry/tooltip-data-viz.json +1 -1
  76. package/dist/mcp-data/registry/tooltip.json +1 -1
  77. package/dist/mcp-data/registry/typing-indicator.json +1 -1
  78. package/dist/types/components/CardOverview/CardOverview.d.ts +10 -9
  79. package/dist/types/components/CardOverview/card-overview-controller.d.ts +13 -1
  80. package/dist/types/components/CardOverview/card-overview-types.d.ts +8 -2
  81. package/dist/types/components/CardOverview/index.d.ts +1 -1
  82. package/dist/types/components/Input/Input.d.ts +1 -1
  83. package/dist/types/components/Select/Select.d.ts +1 -1
  84. package/dist/types/components.d.ts +16 -16
  85. package/package.json +3 -3
@@ -1 +1 @@
1
- {"schemaVersion":1,"package":"@ds-mo/ui","version":"13.4.0","components":66,"digest":"965cb04509f749efa81806c9442ec61ed4c27f7f7a1b487542cd9cf487daa5b9","completedAt":"2026-07-31T05:27:07.162Z"}
1
+ {"schemaVersion":1,"package":"@ds-mo/ui","version":"13.5.0","components":66,"digest":"eebaa1f1eabb8a41935b6137f29b9e5a04282391042c802fc0025b1e4802e141","completedAt":"2026-07-31T23:33:12.355Z"}
@@ -1,7 +1,7 @@
1
1
  {
2
2
  "schemaVersion": "1.0.0",
3
3
  "package": "@ds-mo/ui",
4
- "packageVersion": "13.4.0",
4
+ "packageVersion": "13.5.0",
5
5
  "kind": "patterns",
6
6
  "entries": [
7
7
  {
package/dist/agent.json CHANGED
@@ -1,7 +1,7 @@
1
1
  {
2
2
  "schemaVersion": "1.0.0",
3
3
  "package": "@ds-mo/ui",
4
- "packageVersion": "13.4.0",
4
+ "packageVersion": "13.5.0",
5
5
  "kind": "components",
6
6
  "entries": [
7
7
  {
@@ -1790,12 +1790,12 @@
1790
1790
  "tag": "ds-card-overview",
1791
1791
  "name": "card-overview",
1792
1792
  "title": "CardOverview",
1793
- "summary": "Page-level summary card pairing one headline score with a reporting period, an application-owned period control, and a responsive grid of comparable measures, with an optional elevated scroll-collapse surface and compact 48px presentation.",
1793
+ "summary": "Page-level summary with a persistent 48px reporting bar above an equal-track grid of an optional safety score and comparable measures, plus an elevated page-controlled collapse surface.",
1794
1794
  "intentStatus": "complete",
1795
1795
  "intent": {
1796
1796
  "audience": "general",
1797
1797
  "status": "experimental",
1798
- "summary": "Page-level summary card pairing one headline score with a reporting period, an application-owned period control, and a responsive grid of comparable measures, with an optional elevated scroll-collapse surface and compact 48px presentation.",
1798
+ "summary": "Page-level summary with a persistent 48px reporting bar above an equal-track grid of an optional safety score and comparable measures, plus an elevated page-controlled collapse surface.",
1799
1799
  "useWhen": [
1800
1800
  "A page opens with one headline figure that the surrounding measures explain.",
1801
1801
  "Every measure is compared against the same period, so one caption describes the comparison for all of them.",
@@ -1827,8 +1827,7 @@
1827
1827
  ],
1828
1828
  "accessibility": [
1829
1829
  "The bar is a labelled region; set overviewLabel to name what is being summarised, such as Safety summary.",
1830
- "Trend arrows are decorative and hidden from assistive technology, so the formatted change value must read correctly on its own.",
1831
- "Colour never carries the trend meaning alone; the arrow direction and the value are both present.",
1830
+ "Colour never carries trend meaning alone; the arrow direction and formatted change value are both included in the accessible text.",
1832
1831
  "Measures become selectable only when they are not inactive. Selectable measures form one roving tab stop, so the grid is a single stop and arrow keys move between measures.",
1833
1832
  "Set labelTooltip when a measure's label needs qualifying rather than shortening the label into something ambiguous.",
1834
1833
  "While loading, the region exposes a busy state and renders skeletons whose type metrics match the resolved content."
@@ -1837,20 +1836,21 @@
1837
1836
  "Score and measures are supplied as data; the component owns their type treatment so summary bars stay consistent across pages.",
1838
1837
  "Trend is supplied already resolved as a direction, a formatted value, and a tone. Whether a rise reads well is a product decision, so the component never infers tone from the numbers. Derive it with resolveMetricTrend.",
1839
1838
  "Omit a trend when there is nothing to report; resolveMetricTrend returns null in that case so no zero change is rendered.",
1840
- "Omit score to render the bar without a headline figure. Set scoreErrorMessage to report that the figure could not be resolved while the measures remain readable.",
1839
+ "Omit score to render a centered Score unavailable cell with a tertiary border and no score fill. Set scoreErrorMessage to replace that copy while the measures remain readable.",
1841
1840
  "Loading replaces the score and the measures with skeletons and does not alter the slotted period control.",
1842
- "At most six measures are shown. Keep larger collections outside the summary bar rather than turning it into a dense dashboard.",
1843
- "The period control is slotted rather than owned, because the choice of stepper, select, or date range varies by product surface.",
1844
- "During a page-controlled scroll collapse, the component preserves its expanded flow height while the elevated visual surface shrinks toward 48px and the full content translates upward inside an internal clip. The elevation remains fitted to the visible surface instead of being clipped with the content.",
1845
- "compact is exactly 48px high and keeps only the score label, score value, trend, reporting copy, and slotted period control. It omits the score band, measures, and footer."
1841
+ "At most seven measures are shown. Keep larger collections outside the summary bar rather than turning it into a dense dashboard.",
1842
+ "The period and filter controls are slotted rather than owned. Use the period slot when the current range is selectable; otherwise periodLabel supplies fixed current copy in the same md control-frame and label-inset anatomy. Use the filter slot for the application-owned comparison-window control. Slotted Selects use hasBorder false so the 48px bar owns their surrounding boundary.",
1843
+ "A numeric safety score infers fair from 0–50, good from 51–80, and excellent from 81–100. The level can be supplied explicitly when the displayed value is not numeric. The deprecated band field is ignored.",
1844
+ "The safety score is the first grid cell and uses the same track, 8px outer inset, 6px inner padding, dividers, and responsive behavior as metric cells. The display value removes 12px from both block edges of its line box so it does not increase the shared row height. Score remains nonselectable and excluded from metric roving focus.",
1845
+ "During page-controlled scroll collapse, the component preserves its expanded flow height and stationary reporting bar while the metric grid moves and clips beneath it. Elevation remains fitted to the visible surface.",
1846
+ "compact is exactly 48px high and renders only the reporting bar. It omits Score, measures, and footer."
1846
1847
  ],
1847
1848
  "responsiveBehavior": [
1848
- "The measure grid reflows to fewer columns and finally stacks, driven by the minimum measure width alone. There is no measurement and no horizontal scrolling.",
1849
+ "The measure grid reflows to fewer columns and finally stacks without horizontal scrolling. Even cell totals prefer complete rows; odd totals retain the densest fitting layout and may leave an orphan in the final row.",
1849
1850
  "Every occupied grid track has the same width. When a final row is incomplete, its measures keep the same width as the row above and the unused tracks remain empty.",
1850
1851
  "Set metricMinWidth to change the width a measure may shrink to before the grid drops a column.",
1851
- "The score block hugs its content and never shrinks, so the headline figure holds its size while the grid absorbs the remaining width.",
1852
- "Once the card reaches its narrow stacked state, one summary block holds the score label, score, trend, score band, reporting period, and the application-owned period control above the single-column measures.",
1853
- "In that stacked summary, the score and trend share one line at the start, while the score band is hidden to preserve space. The period control stays at the upper end, while the current period and comparison sit on separate right-aligned lines beside the score.",
1852
+ "The safety score participates in the same equal-width tracks as measures rather than occupying a separate rail.",
1853
+ "The reporting bar owns an exact 8px inset on every edge. Fixed current copy and slotted controls begin at that inset; their labels share md control-frame geometry and truncate before changing the 48px height.",
1854
1854
  "Every measure occupies a full-width row in the stacked state.",
1855
1855
  "Set layout to stacked when the owning page shell enters a responsive mode before the card's own container reaches its narrow threshold.",
1856
1856
  "CardOverview does not observe scroll, choose sticky offsets, or switch its own presentation. The page owner supplies collapse progress, keeps the card sticky at the appropriate shell inset, and swaps to compact at the 48px endpoint.",
@@ -1859,7 +1859,7 @@
1859
1859
  "frameworkCaveats": {
1860
1860
  "customElements": [
1861
1861
  "Assign score and metrics as JavaScript properties; both are objects and cannot be expressed as HTML attributes.",
1862
- "Place the period control in the filter slot; the component reserves space for it but never renders one.",
1862
+ "Place an optional current-range control in the period slot and the comparison-window control in the filter slot; the component reserves their layout but never computes or renders controls.",
1863
1863
  "When driving scroll collapse, update scrollCollapseProgress from page-owned geometry and swap to a separate compact presentation at the endpoint."
1864
1864
  ],
1865
1865
  "react": [
@@ -1870,7 +1870,7 @@
1870
1870
  "angular": [
1871
1871
  "Bind [score] and [metrics] as properties and read the selected measure from $event.detail on (dsMetricSelect).",
1872
1872
  "Derive each trend with resolveMetricTrend so tone stays an explicit product decision.",
1873
- "Keep sticky geometry and [scrollCollapseProgress] in the page owner; CardOverview only renders the visual collapse."
1873
+ "Keep date math, sticky geometry, and [scrollCollapseProgress] in the page owner; CardOverview only renders the supplied composition and visual collapse."
1874
1874
  ]
1875
1875
  },
1876
1876
  "references": [
@@ -1946,11 +1946,9 @@
1946
1946
  },
1947
1947
  "dependencies": [
1948
1948
  "@ds-mo/ui",
1949
- "@ds-mo/tokens",
1950
- "@ds-mo/icons"
1949
+ "@ds-mo/tokens"
1951
1950
  ],
1952
1951
  "componentDependencies": [
1953
- "icon",
1954
1952
  "skeleton",
1955
1953
  "text",
1956
1954
  "tooltip"
@@ -3720,7 +3718,7 @@
3720
3718
  ],
3721
3719
  "states": [
3722
3720
  "Every size applies one complete control-density recipe across frame height, inline padding, icon zones, text-container inset, gap, and radius; supporting error content follows the shared 4px field flow.",
3723
- "The normal field boundary uses the shared secondary inset border. Focus promotes it to the thicker bold-brand inset stroke, while error uses the thicker bold-negative inset stroke without changing geometry.",
3721
+ "The normal field boundary uses the shared secondary inset border. Focus promotes it to the thicker bold-brand inset stroke, while error uses the thicker bold-negative inset stroke without changing geometry. Set hasBorder to false only in chrome that supplies enough surrounding structure; the control then remains borderless at rest, while focused, and while invalid, with semantics and supporting error copy unchanged.",
3724
3722
  "Placeholder text is secondary at rest and quaternary while the editable field is focused because it becomes decorative once typing begins.",
3725
3723
  "Entered values use the parent surface's primary foreground; prefix icons, suffix content, and resting placeholder text use its secondary foreground.",
3726
3724
  "Search fields show a standard borderless CrossCircle icon action only while they contain a value. Clearing emits the empty value and restores focus to the native field.",
@@ -6434,7 +6432,7 @@
6434
6432
  "An empty filtered list composes the message-only body variant of EmptyState. Keep the default neutral no-results message unless localized product guidance makes the outcome clearer.",
6435
6433
  "Enable searchable for more than roughly 20 options, user-managed listings, large domains such as addresses, or sets users cannot efficiently scan. Local matching includes option labels, subtext, and section headings; the owner resolves remote data before assigning options.",
6436
6434
  "Validation timing belongs to the form owner and may be immediate or deferred until blur or submit; the Select exposes validity and error presentation without imposing that policy.",
6437
- "The error trigger uses a 1.5px bold-negative inset stroke so invalid state remains distinguishable from the normal 1px border without changing control geometry.",
6435
+ "The error trigger uses a 1.5px bold-negative inset stroke so invalid state remains distinguishable from the normal 1px border without changing control geometry. Set hasBorder to false for chrome where the trigger must remain borderless at rest, when selected or focused, and when invalid; error semantics and supporting copy remain available.",
6438
6436
  "An initially empty option set is not an expected Select use case. The no-results state describes a search with no matches, not a source with no choices.",
6439
6437
  "Use options for a flat list or sections for grouped choices; when sections are present they take precedence.",
6440
6438
  "The background prop describes the actual parent surface and uses the same surface set as ButtonUnfilled."
@@ -1,2 +1,2 @@
1
- import{p as e,H as r,c as i,h as o,a as s,t as d}from"./index.js";import{d as c}from"./p-BAfG3M8z.js";import{d as a}from"./p-DHAuidt1.js";import{d as t}from"./p-w2kKeG_h.js";import{d as n}from"./p-UtfErnpX.js";import{r as v}from"./p-BJMRBHKW.js";import{T as l}from"./p-C4uYvyq6.js";function w(e){const r=Math.max(0,e.compactHeight);const i=Math.max(e.expandedHeight,r);const o=e.variant==="compact"||!Number.isFinite(e.progress)?0:Math.min(1,Math.max(0,e.progress));const s=Math.max(0,i-r);const d=s*o;return{active:o>0&&s>0,expandedHeight:i,offset:d,visibleHeight:i-d}}function h(e,r){const i=e.findIndex((e=>!e.isInactive));if(i<0)return-1;return e[r]&&!e[r].isInactive?r:i}function m(e,r,i){for(let o=1;o<=e.length;o+=1){const s=((r+i*o)%e.length+e.length)%e.length;if(!e[s]?.isInactive)return s}return-1}const f=()=>`@media (forced-colors: active){.sc-ds-card-overview:root,.sc-ds-card-overview-h,.ds-forced-colors-scope.sc-ds-card-overview{--ds-forced-color-surface:Canvas;--ds-forced-color-content:CanvasText;--ds-forced-color-control-boundary:ButtonText;--ds-forced-color-selected:Highlight;--ds-forced-color-on-selected:HighlightText;--ds-forced-color-disabled:GrayText}}.ds-interaction-fill.sc-ds-card-overview-h,.ds-interaction-fill.sc-ds-card-overview{position:relative;z-index:0;cursor:default;--ds-interaction-hover:var(--color-interaction-hover);--ds-interaction-pressed:var(--color-interaction-pressed);--ds-interaction-active:var(--color-interaction-active-brand);--ds-interaction-border-width:0px;--ds-interaction-border-color:transparent}.ds-interaction-fill.sc-ds-card-overview-h::before,.ds-interaction-fill.sc-ds-card-overview::before,.ds-interaction-fill.sc-ds-card-overview-h::after,.ds-interaction-fill.sc-ds-card-overview::after{content:'';position:absolute;inset:0;border-radius:inherit;background:transparent;pointer-events:none;cursor:inherit;transition:none}.ds-interaction-fill.sc-ds-card-overview-h::before,.ds-interaction-fill.sc-ds-card-overview::before{z-index:1}.ds-interaction-fill.sc-ds-card-overview-h::after,.ds-interaction-fill.sc-ds-card-overview::after{z-index:3;box-shadow:inset 0 0 0 var(--ds-interaction-border-width) var(--ds-interaction-border-color)}.ds-interaction-fill--bordered.sc-ds-card-overview-h,.ds-interaction-fill--bordered.sc-ds-card-overview{--ds-interaction-border-width:var(--dimension-stroke-width-012);--ds-interaction-border-color:var(--color-border-secondary)}.ds-interaction-fill--selected.sc-ds-card-overview-h::before,.ds-interaction-fill--selected.sc-ds-card-overview::before{background:var(--ds-interaction-active)}.ds-interaction-fill--selected.sc-ds-card-overview-h,.ds-interaction-fill--selected.sc-ds-card-overview{--ds-interaction-dot-ring:var(--ds-interaction-active)}@media (hover: hover) and (pointer: fine){.ds-interaction-fill.sc-ds-card-overview-h:hover:not(:disabled)::after,.ds-interaction-fill.sc-ds-card-overview:hover:not(:disabled)::after{background:var(--ds-interaction-hover)}}.ds-interaction-fill.sc-ds-card-overview-h:active:not(:disabled)::after,.ds-interaction-fill.sc-ds-card-overview:active:not(:disabled)::after{background:var(--ds-interaction-pressed)}.ds-interaction-fill.sc-ds-card-overview-h>.ds-interaction-fill__content.sc-ds-card-overview,.ds-interaction-fill.sc-ds-card-overview>.ds-interaction-fill__content.sc-ds-card-overview,.ds-interaction-fill__content.sc-ds-card-overview{position:relative;z-index:2;cursor:inherit}.ds-interaction-fill--on-faint.sc-ds-card-overview-h,.ds-interaction-fill--on-faint.sc-ds-card-overview{--ds-interaction-active:var(--color-interaction-active)}.ds-interaction-fill--on-medium.sc-ds-card-overview-h,.ds-interaction-fill--on-medium.sc-ds-card-overview{--ds-interaction-hover:var(--color-interaction-on-medium-background-hover);--ds-interaction-pressed:var(--color-interaction-on-medium-background-pressed);--ds-interaction-active:var(--color-interaction-on-medium-background-active);--ds-focus-ring-color:var(--color-interaction-on-medium-background-focus)}.ds-interaction-fill--on-bold.sc-ds-card-overview-h,.ds-interaction-fill--on-bold.sc-ds-card-overview{--ds-interaction-hover:var(--color-interaction-on-bold-background-hover);--ds-interaction-pressed:var(--color-interaction-on-bold-background-pressed);--ds-interaction-active:var(--color-interaction-on-bold-background-active);--ds-focus-ring-color:var(--color-interaction-on-bold-background-focus)}.ds-interaction-fill--on-strong.sc-ds-card-overview-h,.ds-interaction-fill--on-strong.sc-ds-card-overview{--ds-interaction-hover:var(--color-interaction-on-strong-background-hover);--ds-interaction-pressed:var(--color-interaction-on-strong-background-pressed);--ds-interaction-active:var(--color-interaction-on-strong-background-active);--ds-focus-ring-color:var(--color-interaction-on-strong-background-focus)}.ds-interaction-fill--on-translucent.sc-ds-card-overview-h,.ds-interaction-fill--on-translucent.sc-ds-card-overview{--ds-interaction-hover:var(--color-translucent-interaction-hover);--ds-interaction-pressed:var(--color-translucent-interaction-pressed);--ds-interaction-active:var(--color-translucent-interaction-active);--ds-focus-ring-color:var(--color-translucent-interaction-focus)}.ds-interaction-fill--on-inverted.sc-ds-card-overview-h,.ds-interaction-fill--on-inverted.sc-ds-card-overview{--ds-interaction-hover:var(--color-inverted-interaction-hover);--ds-interaction-pressed:var(--color-inverted-interaction-pressed);--ds-interaction-active:var(--color-inverted-interaction-active);--ds-focus-ring-color:var(--color-inverted-interaction-focus)}.ds-interaction-fill--on-media.sc-ds-card-overview-h,.ds-interaction-fill--on-media.sc-ds-card-overview{--ds-interaction-hover:var(--color-media-interaction-hover);--ds-interaction-pressed:var(--color-media-interaction-pressed);--ds-interaction-active:var(--color-media-interaction-active);--ds-focus-ring-color:var(--color-media-interaction-focus)}.ds-interaction-fill--on-always-dark.sc-ds-card-overview-h,.ds-interaction-fill--on-always-dark.sc-ds-card-overview{--ds-interaction-hover:var(--color-always-dark-interaction-hover);--ds-interaction-pressed:var(--color-always-dark-interaction-pressed);--ds-interaction-active:var(--color-always-dark-interaction-active);--ds-focus-ring-color:var(--color-always-dark-interaction-focus)}.ds-interaction-fill--on-navigation.sc-ds-card-overview-h,.ds-interaction-fill--on-navigation.sc-ds-card-overview{--ds-interaction-hover:var(--color-navigation-interaction-hover);--ds-interaction-pressed:var(--color-navigation-interaction-pressed);--ds-interaction-active:var(--color-navigation-interaction-active);--ds-focus-ring-color:var(--color-navigation-interaction-focus)}@media (forced-colors: active){.ds-interaction-fill.sc-ds-card-overview-h::after,.ds-interaction-fill.sc-ds-card-overview::after{box-shadow:none;outline:var(--ds-interaction-border-width) solid var(--ds-forced-color-control-boundary);outline-offset:calc(-1 * var(--ds-interaction-border-width))}.ds-interaction-fill--selected.sc-ds-card-overview-h::before,.ds-interaction-fill--selected.sc-ds-card-overview::before{background:transparent;outline:var(--dimension-stroke-width-025) solid var(--ds-forced-color-selected);outline-offset:calc(-1 * var(--dimension-stroke-width-025))}}@media (forced-colors: active) and (hover: hover) and (pointer: fine){.ds-interaction-fill.sc-ds-card-overview-h:hover:not(:disabled):not(:focus-visible):not(:focus-within):not(.ds-focus-ring--visible)::after,.ds-interaction-fill.sc-ds-card-overview:hover:not(:disabled):not(:focus-visible):not(:focus-within):not(.ds-focus-ring--visible)::after{outline-color:var(--ds-forced-color-selected);outline-width:var(--dimension-stroke-width-012)}}@media (forced-colors: active){.sc-ds-card-overview:root,.sc-ds-card-overview-h,.ds-forced-colors-scope.sc-ds-card-overview{--ds-forced-color-surface:Canvas;--ds-forced-color-content:CanvasText;--ds-forced-color-control-boundary:ButtonText;--ds-forced-color-selected:Highlight;--ds-forced-color-on-selected:HighlightText;--ds-forced-color-disabled:GrayText}}.sc-ds-card-overview-h{--ds-focus-ring-width:var(--dimension-stroke-width-025, 2px);--ds-focus-ring-offset:var(--dimension-space-025, 2px);--ds-focus-ring-color:var(--color-interaction-focus)}.ds-focus-ring.sc-ds-card-overview-h,.ds-focus-ring.sc-ds-card-overview,.ds-focus-ring-inset.sc-ds-card-overview-h,.ds-focus-ring-inset.sc-ds-card-overview{outline:none;-webkit-tap-highlight-color:transparent;touch-action:manipulation}.ds-focus-ring.sc-ds-card-overview-h:focus-visible,.ds-focus-ring.sc-ds-card-overview:focus-visible{outline:var(--ds-focus-ring-width) solid var(--ds-focus-ring-color);outline-offset:var(--ds-focus-ring-offset)}.ds-focus-ring.ds-focus-ring--visible.sc-ds-card-overview-h,.ds-focus-ring.ds-focus-ring--visible.sc-ds-card-overview{outline:var(--ds-focus-ring-width) solid var(--ds-focus-ring-color);outline-offset:var(--ds-focus-ring-offset)}.ds-focus-ring-inset.sc-ds-card-overview-h:focus-visible,.ds-focus-ring-inset.sc-ds-card-overview:focus-visible{outline:none}.ds-focus-ring-inset.sc-ds-card-overview-h:focus-visible::after,.ds-focus-ring-inset.sc-ds-card-overview:focus-visible::after{outline:var(--ds-focus-ring-width) solid var(--ds-focus-ring-color);outline-offset:calc(-1 * var(--ds-focus-ring-width))}.ds-focus-ring-inset.ds-focus-ring--visible.sc-ds-card-overview-h,.ds-focus-ring-inset.ds-focus-ring--visible.sc-ds-card-overview{outline:none}.ds-focus-ring-inset.ds-focus-ring--visible.sc-ds-card-overview-h::after,.ds-focus-ring-inset.ds-focus-ring--visible.sc-ds-card-overview::after{outline:var(--ds-focus-ring-width) solid var(--ds-focus-ring-color);outline-offset:calc(-1 * var(--ds-focus-ring-width))}@media (forced-colors: active){.sc-ds-card-overview-h{--ds-focus-ring-color:var(--ds-forced-color-selected)}}.ds-control--lg.sc-ds-card-overview,.ds-control--lg.sc-ds-card-overview-h,.ds-control--md.sc-ds-card-overview-h,.ds-control--md.sc-ds-card-overview,.ds-control--sm.sc-ds-card-overview-h,.ds-control--sm.sc-ds-card-overview,.ds-control--xs.sc-ds-card-overview-h,.ds-control--xs.sc-ds-card-overview{--ds-control-radius:var(--dimension-radius-025)}.ds-control--lg.sc-ds-card-overview-h,.ds-control--lg.sc-ds-card-overview{--ds-control-height:var(--dimension-size-500);--ds-control-icon:var(--dimension-iconography-lg);--ds-control-padding-inline:var(--dimension-space-100);--ds-control-label-inset:var(--dimension-space-050);--ds-control-gap:var(--dimension-space-050)}.ds-control--md.sc-ds-card-overview-h,.ds-control--md.sc-ds-card-overview{--ds-control-height:var(--dimension-size-400);--ds-control-icon:var(--dimension-iconography-md);--ds-control-padding-inline:var(--dimension-space-075);--ds-control-label-inset:var(--dimension-space-025);--ds-control-gap:var(--dimension-space-050)}.ds-control--sm.sc-ds-card-overview-h,.ds-control--sm.sc-ds-card-overview{--ds-control-height:var(--dimension-size-300);--ds-control-icon:var(--dimension-iconography-sm);--ds-control-padding-inline:var(--dimension-space-050);--ds-control-label-inset:var(--dimension-space-025);--ds-control-gap:var(--dimension-space-025)}.ds-control--xs.sc-ds-card-overview-h,.ds-control--xs.sc-ds-card-overview{--ds-control-height:var(--dimension-size-200);--ds-control-icon:var(--dimension-iconography-xs);--ds-control-padding-inline:var(--dimension-space-025);--ds-control-label-inset:var(--dimension-space-025);--ds-control-gap:0}.ds-control-frame.sc-ds-card-overview{display:inline-flex;align-items:center;box-sizing:border-box;height:var(--ds-control-height, var(--dimension-size-400));padding-inline:var(--ds-control-padding-inline, var(--dimension-space-075));gap:var(--ds-control-gap, var(--dimension-space-050));border-radius:var(--ds-control-radius, var(--dimension-radius-025))}.ds-control-icon-box.sc-ds-card-overview{display:inline-flex;align-items:center;justify-content:center;flex-shrink:0;width:var(--ds-control-icon, var(--dimension-iconography-md));height:var(--ds-control-icon, var(--dimension-iconography-md))}.ds-control-label-box.sc-ds-card-overview{min-width:0;padding-inline:var(--ds-control-label-inset, var(--dimension-space-025))}.ds-control-elevation.sc-ds-card-overview-h,.ds-control-elevation.sc-ds-card-overview{position:relative;overflow:visible;box-shadow:var(--ds-control-elevation-shadow, none)}.ds-control-elevation.sc-ds-card-overview-h::after,.ds-control-elevation.sc-ds-card-overview::after{content:'';position:absolute;inset:0;z-index:4;border-radius:inherit;box-shadow:var(--ds-control-elevation-highlight, none);pointer-events:none}.ds-control-elevation--sm.sc-ds-card-overview-h,.ds-control-elevation--sm.sc-ds-card-overview{--ds-control-elevation-shadow:var(--effect-shadow-elevated-sm);--ds-control-elevation-highlight:var(--effect-highlight-elevated-sm)}.ds-control-elevation--md.sc-ds-card-overview-h,.ds-control-elevation--md.sc-ds-card-overview{--ds-control-elevation-shadow:var(--effect-shadow-elevated-md);--ds-control-elevation-highlight:var(--effect-highlight-elevated-md)}.ds-control-elevation--floating.sc-ds-card-overview-h,.ds-control-elevation--floating.sc-ds-card-overview{--ds-control-elevation-shadow:var(--effect-shadow-elevated-floating);--ds-control-elevation-highlight:var(--effect-highlight-elevated-floating)}.ds-control-elevation--press-scale.sc-ds-card-overview{--ds-control-press-active-scale:var(--dimension-scale-default);transition:scale var(--effect-motion-short-2)}.ds-control-elevation--press-scale[data-ds-press-active].sc-ds-card-overview{scale:var(--dimension-scale-subtle)}@media (prefers-reduced-motion: reduce){.ds-control-elevation--press-scale.sc-ds-card-overview,.ds-control-elevation--press-scale[data-ds-press-active].sc-ds-card-overview{scale:none;transition:none}}.sc-ds-card-overview-h{display:block;box-sizing:border-box;container-type:inline-size;-webkit-user-select:none;user-select:none;--ds-card-overview-metric-min:calc(var(--dimension-size-400) * 5);--ds-card-overview-divider-width:var(--dimension-stroke-width-012);--ds-card-overview-divider-color:var(--color-always-dark-border-tertiary);--ds-card-overview-divider:var(--ds-card-overview-divider-width) solid var(--ds-card-overview-divider-color);color:var(--color-always-dark-foreground-primary)}.card-overview__surface.sc-ds-card-overview{width:100%;min-width:0;box-sizing:border-box;border-radius:var(--dimension-radius-050);background:var(--color-always-dark-background);color:var(--color-always-dark-foreground-primary);overflow-anchor:none}.card-overview__clip.sc-ds-card-overview{height:100%;min-width:0;border-radius:inherit;background:inherit;overflow:hidden}.card-overview--scroll-collapsing.sc-ds-card-overview-h{height:var(--ds-card-overview-expanded-height);pointer-events:none}.card-overview--scroll-collapsing.sc-ds-card-overview-h .card-overview__surface.sc-ds-card-overview{height:var(--ds-card-overview-visible-height);pointer-events:auto;will-change:height}.card-overview--scroll-collapsing.sc-ds-card-overview-h .card-overview__layout.sc-ds-card-overview{transform:translateY(calc(-1 * var(--ds-card-overview-content-offset)));will-change:transform}.card-overview__layout.sc-ds-card-overview{display:grid;grid-template-rows:auto minmax(0, 1fr);grid-template-columns:minmax(0, 1fr);align-items:stretch;min-width:0}.card-overview__layout--has-score.sc-ds-card-overview{grid-template-columns:auto minmax(0, 1fr)}.card-overview__summary.sc-ds-card-overview{display:contents}.card-overview__score.sc-ds-card-overview{display:flex;grid-row:1 / span 2;grid-column:1;flex:0 0 auto;flex-direction:column;gap:0;min-width:0;padding:var(--dimension-space-100) var(--dimension-space-200);border-inline-end:var(--ds-card-overview-divider)}.card-overview__score--resolved.sc-ds-card-overview{min-inline-size:max-content}.card-overview__score-label-row.sc-ds-card-overview{display:flex;align-items:center;min-height:var(--ds-control-height)}.card-overview__score-figure.sc-ds-card-overview{display:flex;align-items:baseline;gap:var(--dimension-space-050);min-width:0;margin-block-start:calc(-1 * (var(--dimension-space-150) + var(--dimension-space-012)))}.card-overview__score-value.sc-ds-card-overview{flex:0 0 auto}.card-overview__score-band.sc-ds-card-overview{margin-block-start:calc(-1 * var(--dimension-space-025))}.card-overview__skeleton-baseline.sc-ds-card-overview{position:relative;inset-block-start:calc(-1 * var(--dimension-space-150))}.card-overview__score--error.sc-ds-card-overview{flex-direction:row;align-items:center;gap:var(--dimension-space-050);color:var(--color-always-dark-foreground-negative)}.card-overview__body.sc-ds-card-overview{display:flex;grid-row:2;grid-column:1;flex-direction:column;min-width:0}.card-overview__body--has-score.sc-ds-card-overview{grid-column:2}.card-overview__header.sc-ds-card-overview{display:flex;grid-row:1;grid-column:1;align-items:center;gap:var(--dimension-space-100);min-width:0;padding:var(--dimension-space-100);border-block-end:var(--ds-card-overview-divider);box-sizing:border-box}.card-overview__header--has-score.sc-ds-card-overview{grid-column:2}.card-overview__period.sc-ds-card-overview{display:flex;flex:1 1 auto;align-items:center;gap:var(--dimension-space-050);min-height:var(--ds-control-height);min-width:0;padding-inline:var(--ds-control-padding-inline);overflow:hidden;white-space:nowrap}.card-overview__filter.sc-ds-card-overview{display:flex;flex:0 0 auto;align-items:center}.card-overview__metrics.sc-ds-card-overview{display:grid;flex:1 1 auto;grid-template-columns:repeat( auto-fit, minmax(min(100%, var(--ds-card-overview-metric-min)), 1fr) );align-content:stretch;min-width:0;overflow:clip}.card-overview__metric.sc-ds-card-overview{display:flex;position:relative;flex-direction:column;gap:var(--dimension-space-050);min-width:0;padding:var(--dimension-space-175) var(--dimension-space-200);border-radius:0;box-shadow:var(--ds-card-overview-divider-width) 0 0 0 var(--ds-card-overview-divider-color), 0 var(--ds-card-overview-divider-width) 0 0 var(--ds-card-overview-divider-color)}.card-overview__metric[role='button'].sc-ds-card-overview{cursor:default;-webkit-user-select:none;user-select:none}.card-overview__metric-label.sc-ds-card-overview{min-width:0}.card-overview__metric-figure.sc-ds-card-overview{display:flex;align-items:baseline;gap:var(--dimension-space-100);min-width:0}.card-overview__trend.sc-ds-card-overview{flex:0 0 auto;white-space:nowrap}@container (max-width: 480px){.sc-ds-card-overview-h .card-overview__layout{grid-template-rows:auto minmax(0, 1fr);grid-template-columns:minmax(0, 1fr)}.sc-ds-card-overview-h .card-overview__summary{display:grid;grid-row:1;grid-column:1;grid-template-columns:minmax(0, 1fr) auto;grid-template-rows:auto;border-block-end:var(--ds-card-overview-divider)}.sc-ds-card-overview-h .card-overview__score{display:grid;grid-row:1;grid-column:1;grid-template-rows:auto auto;grid-template-columns:auto auto;justify-content:start;column-gap:var(--dimension-space-100);width:auto;padding-block-end:var(--dimension-space-100);padding-inline-end:var(--dimension-space-100);border-inline-end:none}.sc-ds-card-overview-h .card-overview__score-label-row{grid-row:1;grid-column:1 / -1;min-height:var(--ds-control-height)}.sc-ds-card-overview-h .card-overview__score-band,.sc-ds-card-overview-h .card-overview__score-figure{grid-row:2;margin-block-start:0}.sc-ds-card-overview-h .card-overview__score-figure{grid-column:1;align-self:baseline;gap:var(--dimension-space-100)}.sc-ds-card-overview-h .card-overview__score-band{grid-column:2;align-self:baseline;display:none}.sc-ds-card-overview-h .card-overview__header{display:grid;grid-row:1;grid-column:2;grid-template-rows:auto auto;align-content:start;gap:0;padding:0;border-block-end:none}.sc-ds-card-overview-h .card-overview__filter{grid-row:1;grid-column:1;align-self:start;justify-self:end;padding:var(--dimension-space-100) var(--dimension-space-100) 0 0}.sc-ds-card-overview-h .card-overview__period{grid-row:2;grid-column:1;flex-direction:column;align-items:flex-end;justify-self:stretch;gap:0;min-height:0;padding-block:var(--dimension-space-150) var(--dimension-space-100);padding-inline:var(--dimension-space-100) var(--dimension-space-200);overflow:visible;text-align:end;white-space:nowrap}.sc-ds-card-overview-h .card-overview__body{grid-row:2;grid-column:1}}.card-overview--stacked.sc-ds-card-overview-h .card-overview__layout.sc-ds-card-overview{grid-template-rows:auto minmax(0, 1fr);grid-template-columns:minmax(0, 1fr)}.card-overview--stacked.sc-ds-card-overview-h .card-overview__summary.sc-ds-card-overview{display:grid;grid-row:1;grid-column:1;grid-template-columns:minmax(0, 1fr) auto;grid-template-rows:auto;border-block-end:var(--ds-card-overview-divider)}.card-overview--stacked.sc-ds-card-overview-h .card-overview__score.sc-ds-card-overview{display:grid;grid-row:1;grid-column:1;grid-template-rows:auto auto;grid-template-columns:auto auto;justify-content:start;column-gap:var(--dimension-space-100);width:auto;padding-block-end:var(--dimension-space-100);padding-inline-end:var(--dimension-space-100);border-inline-end:none}.card-overview--stacked.sc-ds-card-overview-h .card-overview__score-label-row.sc-ds-card-overview{grid-row:1;grid-column:1 / -1;min-height:var(--ds-control-height)}.card-overview--stacked.sc-ds-card-overview-h .card-overview__score-band.sc-ds-card-overview,.card-overview--stacked.sc-ds-card-overview-h .card-overview__score-figure.sc-ds-card-overview{grid-row:2;margin-block-start:0}.card-overview--stacked.sc-ds-card-overview-h .card-overview__score-figure.sc-ds-card-overview{grid-column:1;align-self:baseline;gap:var(--dimension-space-100)}.card-overview--stacked.sc-ds-card-overview-h .card-overview__score-band.sc-ds-card-overview{grid-column:2;align-self:baseline;display:none}.card-overview--stacked.sc-ds-card-overview-h .card-overview__header.sc-ds-card-overview{display:grid;grid-row:1;grid-column:2;grid-template-rows:auto auto;align-content:start;gap:0;padding:0;border-block-end:none}.card-overview--stacked.sc-ds-card-overview-h .card-overview__filter.sc-ds-card-overview{grid-row:1;grid-column:1;align-self:start;justify-self:end;padding:var(--dimension-space-100) var(--dimension-space-100) 0 0}.card-overview--stacked.sc-ds-card-overview-h .card-overview__period.sc-ds-card-overview{grid-row:2;grid-column:1;flex-direction:column;align-items:flex-end;justify-self:stretch;gap:0;min-height:0;padding-block:var(--dimension-space-150) var(--dimension-space-100);padding-inline:var(--dimension-space-100) var(--dimension-space-200);overflow:visible;text-align:end;white-space:nowrap}.card-overview--stacked.sc-ds-card-overview-h .card-overview__body.sc-ds-card-overview{grid-row:2;grid-column:1}.card-overview--stacked.sc-ds-card-overview-h .card-overview__metrics.sc-ds-card-overview{grid-template-columns:minmax(0, 1fr)}.card-overview--compact.sc-ds-card-overview-h{height:var(--dimension-size-600);min-height:var(--dimension-size-600)}.card-overview--compact.sc-ds-card-overview-h .card-overview__surface.sc-ds-card-overview{height:100%}.card-overview--compact.sc-ds-card-overview-h .card-overview__layout.sc-ds-card-overview,.card-overview--compact.sc-ds-card-overview-h .card-overview__summary.sc-ds-card-overview{display:flex;width:100%;height:100%;min-width:0}.card-overview--compact.sc-ds-card-overview-h .card-overview__score.sc-ds-card-overview{display:flex;flex:0 0 auto;flex-direction:row;align-items:center;gap:var(--dimension-space-100);width:auto;height:100%;min-width:0;padding:var(--dimension-space-100) var(--dimension-space-200);border-inline-end:var(--ds-card-overview-divider);box-sizing:border-box}.card-overview--compact.sc-ds-card-overview-h .card-overview__score-label-row.sc-ds-card-overview{display:contents;min-height:0}.card-overview--compact.sc-ds-card-overview-h .card-overview__score-label.sc-ds-card-overview,.card-overview--compact.sc-ds-card-overview-h .card-overview__score-figure.sc-ds-card-overview,.card-overview--compact.sc-ds-card-overview-h .card-overview__trend.sc-ds-card-overview{flex:0 0 auto}.card-overview--compact.sc-ds-card-overview-h .card-overview__score-figure.sc-ds-card-overview{display:flex;align-self:center;align-items:baseline;gap:var(--dimension-space-050);margin-block-start:0}.card-overview--compact.sc-ds-card-overview-h .card-overview__score-band.sc-ds-card-overview{display:none}.card-overview--compact.sc-ds-card-overview-h .card-overview__header.sc-ds-card-overview{display:flex;flex:1 1 auto;grid-row:auto;grid-column:auto;align-items:center;gap:var(--dimension-space-100);height:100%;min-width:0;padding:var(--dimension-space-100);border-block-end:none;box-sizing:border-box}.card-overview--compact.sc-ds-card-overview-h .card-overview__period.sc-ds-card-overview{display:flex;flex:1 1 auto;flex-direction:row;align-items:center;gap:var(--dimension-space-050);min-width:0;min-height:var(--ds-control-height);padding-inline:var(--ds-control-padding-inline);overflow:hidden;text-align:start;white-space:nowrap}.card-overview--compact.sc-ds-card-overview-h .card-overview__period-current.sc-ds-card-overview,.card-overview--compact.sc-ds-card-overview-h .card-overview__period-comparison.sc-ds-card-overview{min-width:0;overflow:hidden;text-overflow:ellipsis}.card-overview--compact.sc-ds-card-overview-h .card-overview__period-current.sc-ds-card-overview{flex:0 1 auto}.card-overview--compact.sc-ds-card-overview-h .card-overview__period-comparison.sc-ds-card-overview{flex:1 1 auto}.card-overview--compact.sc-ds-card-overview-h .card-overview__filter.sc-ds-card-overview{display:flex;flex:0 0 auto;align-items:center;padding:0}`;const u="var(--dimension-menu-width-xs)";const g=4;const p=6;const b={positive:"var(--color-always-dark-foreground-positive)",negative:"var(--color-always-dark-foreground-negative)",neutral:"var(--color-always-dark-foreground-secondary)"};const _="var(--color-always-dark-foreground-primary)";const x="var(--color-always-dark-foreground-secondary)";const y=e(class e extends r{constructor(e){super();if(e!==false){this.__registerHost()}this.dsMetricSelect=i(this,"dsMetricSelect");this.variant="default";this.layout="auto";this.periodLabel="";this.comparisonLabel="";this.metrics=[];this.metricMinWidth=u;this.isLoading=false;this.overviewLabel="Overview";this.scrollCollapseProgress=0;this.focusedMetricIndex=0;this.expandedHeight=0;this.layoutResizeObserver=null;this.handleMetricKeyDown=(e,r)=>{switch(e.key){case"ArrowRight":case"ArrowDown":e.preventDefault();this.moveFocus(r,1);break;case"ArrowLeft":case"ArrowUp":e.preventDefault();this.moveFocus(r,-1);break}}}componentDidLoad(){this.observeLayout()}componentDidRender(){if(!this.layoutResizeObserver)this.observeLayout()}disconnectedCallback(){this.layoutResizeObserver?.disconnect();this.layoutResizeObserver=null}get hasScore(){return this.score!==undefined||this.scoreErrorMessage!==undefined||this.isLoading}get visibleMetrics(){return this.metrics.slice(0,p)}get resolvedScrollCollapseProgress(){if(this.variant==="compact"||!Number.isFinite(this.scrollCollapseProgress))return 0;return Math.min(1,Math.max(0,this.scrollCollapseProgress))}get scrollCollapseGeometry(){const e=v(l.size600,48);return w({variant:this.variant,progress:this.resolvedScrollCollapseProgress,expandedHeight:this.expandedHeight,compactHeight:e})}observeLayout(){const e=this.layoutEl;if(!e)return;const r=e=>{if(e>0&&Math.abs(e-this.expandedHeight)>=.5){this.expandedHeight=e}};r(e.getBoundingClientRect().height);if(typeof ResizeObserver==="undefined")return;this.layoutResizeObserver?.disconnect();this.layoutResizeObserver=new ResizeObserver((e=>{const i=e[0]?.contentRect.height;if(i!==undefined)r(i)}));this.layoutResizeObserver.observe(e)}get rovingIndex(){return h(this.visibleMetrics,this.focusedMetricIndex)}selectMetric(e,r){if(e.isInactive)return;this.focusedMetricIndex=r;this.dsMetricSelect.emit(e)}moveFocus(e,r){const i=this.visibleMetrics;const o=m(i,e,r<0?-1:1);if(o<0)return;this.focusedMetricIndex=o;const s=this.el.querySelectorAll(".card-overview__metric");s[o]?.focus()}bar(e,r,i){return o("ds-skeleton",{class:i,variant:"text",textVariant:e,width:r,background:"always-dark"})}renderTrend(e,r,i=false){if(!e)return null;return o("ds-text",{as:"span",class:{"card-overview__trend":true,[`card-overview__trend--${e.tone}`]:true},variant:r,emphasis:i,color:b[e.tone],fontFeature:"tabular-nums"},e.direction==="up"?"↑":"↓"," ",e.value)}renderScore(e){if(this.isLoading){if(e){return o("div",{class:"card-overview__score ds-control--md",part:"score"},this.bar("text-body-medium","40px","card-overview__score-label"),o("div",{class:"card-overview__score-figure"},this.bar("text-body-medium","24px"),this.bar("text-body-medium","32px")))}return o("div",{class:"card-overview__score ds-control--md",part:"score"},o("div",{class:"card-overview__score-label-row"}),o("div",{class:"card-overview__score-figure"},this.bar("text-display-medium","56px"),this.bar("text-body-small","24px","card-overview__skeleton-baseline")),this.bar("text-caption","80px","card-overview__score-band card-overview__score-band--loading"))}if(this.scoreErrorMessage){return o("div",{class:"card-overview__score card-overview__score--error",part:"score",role:"alert"},o("ds-icon",{name:"CircleExclamation",size:"sm",color:"inherit","aria-hidden":"true"}),o("ds-text",{as:"span",variant:"text-body-medium",color:"inherit"},this.scoreErrorMessage))}const r=this.score;if(!r)return null;return o("div",{class:"card-overview__score card-overview__score--resolved ds-control--md",part:"score"},o("div",{class:"card-overview__score-label-row"},o("ds-text",{as:"span",class:"card-overview__score-label",variant:"text-body-medium",emphasis:!e,color:x},r.label)),o("div",{class:"card-overview__score-figure"},o("ds-text",{as:"span",class:"card-overview__score-value",variant:e?"text-body-medium":"text-display-medium",emphasis:true,color:_,fontFeature:"tabular-nums"},r.value),this.renderTrend(r.trend,e?"text-body-medium":"text-body-small",!e)),r.band&&!e&&o("ds-text",{as:"span",class:"card-overview__score-band",variant:"text-caption",color:x},r.band))}renderMetric(e,r){const i=!e.isInactive;const s=o("ds-text",{as:"span",class:"card-overview__metric-label",variant:"text-body-small",color:x},e.label);return o("div",{class:{"card-overview__metric":true,"card-overview__metric--inactive":!i,"ds-interaction-fill":i,"ds-interaction-fill--on-always-dark":i,"ds-focus-ring-inset":i},part:"metric",role:i?"button":undefined,tabIndex:i&&r===this.rovingIndex?0:-1,onClick:()=>this.selectMetric(e,r),onKeyDown:e=>this.handleMetricKeyDown(e,r),onFocusin:()=>{if(i)this.focusedMetricIndex=r}},e.labelTooltip?o("ds-tooltip",{label:e.labelTooltip,side:"top",size:"sm"},s):s,o("div",{class:"card-overview__metric-figure"},o("ds-text",{as:"span",class:"card-overview__metric-value",variant:"text-body-medium",color:_,fontFeature:"tabular-nums"},e.value),this.renderTrend(e.trend,"text-body-medium")))}renderMetrics(){if(this.isLoading&&this.metrics.length===0){return Array.from({length:g},((e,r)=>o("div",{class:"card-overview__metric",key:`loading-${r}`},this.bar("text-body-small","70%","card-overview__metric-label"),o("div",{class:"card-overview__metric-figure"},this.bar("text-body-medium","36px"),this.bar("text-body-medium","40px")))))}return this.visibleMetrics.map(((e,r)=>this.renderMetric(e,r)))}render(){const e=Boolean(this.periodLabel||this.comparisonLabel);const r=this.variant==="compact";const i=this.scrollCollapseGeometry;return o(s,{key:"b0186ecfd59c600575ed2b5ef0fc6ae81760cb40",class:{"card-overview":true,"card-overview--has-score":this.hasScore,"card-overview--compact":r,"card-overview--stacked":!r&&this.layout==="stacked","card-overview--scroll-collapsing":i.active},role:"region","aria-label":this.overviewLabel,"aria-busy":this.isLoading?"true":undefined,style:{"--ds-card-overview-metric-min":this.metricMinWidth,"--ds-card-overview-expanded-height":i.active?`${i.expandedHeight}px`:undefined,"--ds-card-overview-visible-height":i.active?`${i.visibleHeight}px`:undefined,"--ds-card-overview-content-offset":i.active?`${i.offset}px`:undefined}},o("div",{key:"102c078952716641aec41c22b6f5c5bc7eef199e",class:{"card-overview__surface":true,"ds-control-elevation":true,"ds-control-elevation--sm":!r,"ds-control-elevation--floating":r}},o("div",{key:"a5ddfe5f351469d49d3cd9b53df4ef4bfc224b5c",class:"card-overview__clip"},o("div",{key:"1ecfa409c8173eaf3e7d7ca7d1db55297dfb26a4",ref:e=>{this.layoutEl=e??undefined},class:{"card-overview__layout":true,"card-overview__layout--has-score":this.hasScore}},o("div",{key:"1330726725a0099b615ea1b9a79eb3cde7c42d4b",class:"card-overview__summary"},this.hasScore&&this.renderScore(r),o("div",{key:"a6ad5ab8b94d080e60edd97b72350f87e4420161",class:{"card-overview__header":true,"card-overview__header--has-score":this.hasScore,"ds-control--md":true}},this.isLoading?o("div",{class:"card-overview__period ds-control-label-box"},this.bar("text-body-medium","184px"),this.bar("text-body-medium","248px")):e&&o("div",{class:"card-overview__period ds-control-label-box"},this.periodLabel&&o("ds-text",{as:"span",class:"card-overview__period-current ds-control-label-box",variant:"text-body-medium",emphasis:true,color:_},this.periodLabel),this.comparisonLabel&&o("ds-text",{as:"span",class:"card-overview__period-comparison ds-control-label-box",variant:"text-body-medium",color:x},this.comparisonLabel)),o("div",{key:"efd645a645106dc97aed2d5a537fc19c72230de6",class:"card-overview__filter"},this.isLoading?o("ds-skeleton",{variant:"control",controlSize:"md",width:"128px",background:"always-dark"}):o("slot",{name:"filter"})))),!r&&o("div",{key:"c3549f25a2d40fc2cc0b4a6a652cc467cd7493b2",class:{"card-overview__body":true,"card-overview__body--has-score":this.hasScore}},o("div",{key:"5808135410857c9cf8b1f532346f46a5b3f05d34",class:"card-overview__metrics",part:"metrics"},this.renderMetrics()),o("slot",{key:"754843a547f28183ef2c5c43eac5078efe431710",name:"footer"}))))))}get el(){return this}static get style(){return f()}},[262,"ds-card-overview",{variant:[1],layout:[1],score:[16],periodLabel:[1,"period-label"],comparisonLabel:[1,"comparison-label"],metrics:[16],metricMinWidth:[1,"metric-min-width"],isLoading:[4,"is-loading"],scoreErrorMessage:[1,"score-error-message"],overviewLabel:[1,"overview-label"],scrollCollapseProgress:[2,"scroll-collapse-progress"],focusedMetricIndex:[32],expandedHeight:[32]}]);function k(){if(typeof customElements==="undefined"){return}const e=["ds-card-overview","ds-icon","ds-skeleton","ds-text","ds-tooltip"];e.forEach((e=>{switch(e){case"ds-card-overview":if(!customElements.get(d(e))){customElements.define(d(e),y)}break;case"ds-icon":if(!customElements.get(d(e))){c()}break;case"ds-skeleton":if(!customElements.get(d(e))){a()}break;case"ds-text":if(!customElements.get(d(e))){t()}break;case"ds-tooltip":if(!customElements.get(d(e))){n()}break}}))}k();const z=y;const M=k;export{z as DsCardOverview,M as defineCustomElement};
1
+ import{p as e,H as r,c as o,h as i,a as s,t as c}from"./index.js";import{d}from"./p-DHAuidt1.js";import{d as t}from"./p-w2kKeG_h.js";import{d as a}from"./p-UtfErnpX.js";import{r as n}from"./p-BJMRBHKW.js";import{T as v}from"./p-C4uYvyq6.js";function l(e){const r=Math.max(1,Math.floor(e.cellCount));const o=Math.max(1,e.minCellWidth);const i=Math.max(1,Math.floor(e.maxColumns??4));const s=Math.max(1,Math.min(r,i,Math.floor(Math.max(0,e.availableWidth)/o)));if(r%2!==0)return s;for(let e=s;e>=1;e-=1){if(r%e===0)return e}return 1}function f(e){const r=Math.max(0,e.compactHeight);const o=Math.max(e.expandedHeight,r);const i=e.variant==="compact"||!Number.isFinite(e.progress)?0:Math.min(1,Math.max(0,e.progress));const s=Math.max(0,o-r);const c=s*i;return{active:i>0&&s>0,expandedHeight:o,offset:c,visibleHeight:o-c}}function w(e){const r=typeof e==="number"?e:Number(e);if(!Number.isFinite(r)||r<0||r>100)return undefined;if(r<=50)return"fair";if(r<=80)return"good";return"excellent"}function h(e,r){const o=e.findIndex((e=>!e.isInactive));if(o<0)return-1;return e[r]&&!e[r].isInactive?r:o}function u(e,r,o){for(let i=1;i<=e.length;i+=1){const s=((r+o*i)%e.length+e.length)%e.length;if(!e[s]?.isInactive)return s}return-1}const m=()=>`@media (forced-colors: active){.sc-ds-card-overview:root,.sc-ds-card-overview-h,.ds-forced-colors-scope.sc-ds-card-overview{--ds-forced-color-surface:Canvas;--ds-forced-color-content:CanvasText;--ds-forced-color-control-boundary:ButtonText;--ds-forced-color-selected:Highlight;--ds-forced-color-on-selected:HighlightText;--ds-forced-color-disabled:GrayText}}.ds-interaction-fill.sc-ds-card-overview-h,.ds-interaction-fill.sc-ds-card-overview{position:relative;z-index:0;cursor:default;--ds-interaction-hover:var(--color-interaction-hover);--ds-interaction-pressed:var(--color-interaction-pressed);--ds-interaction-active:var(--color-interaction-active-brand);--ds-interaction-border-width:0px;--ds-interaction-border-color:transparent}.ds-interaction-fill.sc-ds-card-overview-h::before,.ds-interaction-fill.sc-ds-card-overview::before,.ds-interaction-fill.sc-ds-card-overview-h::after,.ds-interaction-fill.sc-ds-card-overview::after{content:'';position:absolute;inset:0;border-radius:inherit;background:transparent;pointer-events:none;cursor:inherit;transition:none}.ds-interaction-fill.sc-ds-card-overview-h::before,.ds-interaction-fill.sc-ds-card-overview::before{z-index:1}.ds-interaction-fill.sc-ds-card-overview-h::after,.ds-interaction-fill.sc-ds-card-overview::after{z-index:3;box-shadow:inset 0 0 0 var(--ds-interaction-border-width) var(--ds-interaction-border-color)}.ds-interaction-fill--bordered.sc-ds-card-overview-h,.ds-interaction-fill--bordered.sc-ds-card-overview{--ds-interaction-border-width:var(--dimension-stroke-width-012);--ds-interaction-border-color:var(--color-border-secondary)}.ds-interaction-fill--selected.sc-ds-card-overview-h::before,.ds-interaction-fill--selected.sc-ds-card-overview::before{background:var(--ds-interaction-active)}.ds-interaction-fill--selected.sc-ds-card-overview-h,.ds-interaction-fill--selected.sc-ds-card-overview{--ds-interaction-dot-ring:var(--ds-interaction-active)}@media (hover: hover) and (pointer: fine){.ds-interaction-fill.sc-ds-card-overview-h:hover:not(:disabled)::after,.ds-interaction-fill.sc-ds-card-overview:hover:not(:disabled)::after{background:var(--ds-interaction-hover)}}.ds-interaction-fill.sc-ds-card-overview-h:active:not(:disabled)::after,.ds-interaction-fill.sc-ds-card-overview:active:not(:disabled)::after{background:var(--ds-interaction-pressed)}.ds-interaction-fill.sc-ds-card-overview-h>.ds-interaction-fill__content.sc-ds-card-overview,.ds-interaction-fill.sc-ds-card-overview>.ds-interaction-fill__content.sc-ds-card-overview,.ds-interaction-fill__content.sc-ds-card-overview{position:relative;z-index:2;cursor:inherit}.ds-interaction-fill--on-faint.sc-ds-card-overview-h,.ds-interaction-fill--on-faint.sc-ds-card-overview{--ds-interaction-active:var(--color-interaction-active)}.ds-interaction-fill--on-medium.sc-ds-card-overview-h,.ds-interaction-fill--on-medium.sc-ds-card-overview{--ds-interaction-hover:var(--color-interaction-on-medium-background-hover);--ds-interaction-pressed:var(--color-interaction-on-medium-background-pressed);--ds-interaction-active:var(--color-interaction-on-medium-background-active);--ds-focus-ring-color:var(--color-interaction-on-medium-background-focus)}.ds-interaction-fill--on-bold.sc-ds-card-overview-h,.ds-interaction-fill--on-bold.sc-ds-card-overview{--ds-interaction-hover:var(--color-interaction-on-bold-background-hover);--ds-interaction-pressed:var(--color-interaction-on-bold-background-pressed);--ds-interaction-active:var(--color-interaction-on-bold-background-active);--ds-focus-ring-color:var(--color-interaction-on-bold-background-focus)}.ds-interaction-fill--on-strong.sc-ds-card-overview-h,.ds-interaction-fill--on-strong.sc-ds-card-overview{--ds-interaction-hover:var(--color-interaction-on-strong-background-hover);--ds-interaction-pressed:var(--color-interaction-on-strong-background-pressed);--ds-interaction-active:var(--color-interaction-on-strong-background-active);--ds-focus-ring-color:var(--color-interaction-on-strong-background-focus)}.ds-interaction-fill--on-translucent.sc-ds-card-overview-h,.ds-interaction-fill--on-translucent.sc-ds-card-overview{--ds-interaction-hover:var(--color-translucent-interaction-hover);--ds-interaction-pressed:var(--color-translucent-interaction-pressed);--ds-interaction-active:var(--color-translucent-interaction-active);--ds-focus-ring-color:var(--color-translucent-interaction-focus)}.ds-interaction-fill--on-inverted.sc-ds-card-overview-h,.ds-interaction-fill--on-inverted.sc-ds-card-overview{--ds-interaction-hover:var(--color-inverted-interaction-hover);--ds-interaction-pressed:var(--color-inverted-interaction-pressed);--ds-interaction-active:var(--color-inverted-interaction-active);--ds-focus-ring-color:var(--color-inverted-interaction-focus)}.ds-interaction-fill--on-media.sc-ds-card-overview-h,.ds-interaction-fill--on-media.sc-ds-card-overview{--ds-interaction-hover:var(--color-media-interaction-hover);--ds-interaction-pressed:var(--color-media-interaction-pressed);--ds-interaction-active:var(--color-media-interaction-active);--ds-focus-ring-color:var(--color-media-interaction-focus)}.ds-interaction-fill--on-always-dark.sc-ds-card-overview-h,.ds-interaction-fill--on-always-dark.sc-ds-card-overview{--ds-interaction-hover:var(--color-always-dark-interaction-hover);--ds-interaction-pressed:var(--color-always-dark-interaction-pressed);--ds-interaction-active:var(--color-always-dark-interaction-active);--ds-focus-ring-color:var(--color-always-dark-interaction-focus)}.ds-interaction-fill--on-navigation.sc-ds-card-overview-h,.ds-interaction-fill--on-navigation.sc-ds-card-overview{--ds-interaction-hover:var(--color-navigation-interaction-hover);--ds-interaction-pressed:var(--color-navigation-interaction-pressed);--ds-interaction-active:var(--color-navigation-interaction-active);--ds-focus-ring-color:var(--color-navigation-interaction-focus)}@media (forced-colors: active){.ds-interaction-fill.sc-ds-card-overview-h::after,.ds-interaction-fill.sc-ds-card-overview::after{box-shadow:none;outline:var(--ds-interaction-border-width) solid var(--ds-forced-color-control-boundary);outline-offset:calc(-1 * var(--ds-interaction-border-width))}.ds-interaction-fill--selected.sc-ds-card-overview-h::before,.ds-interaction-fill--selected.sc-ds-card-overview::before{background:transparent;outline:var(--dimension-stroke-width-025) solid var(--ds-forced-color-selected);outline-offset:calc(-1 * var(--dimension-stroke-width-025))}}@media (forced-colors: active) and (hover: hover) and (pointer: fine){.ds-interaction-fill.sc-ds-card-overview-h:hover:not(:disabled):not(:focus-visible):not(:focus-within):not(.ds-focus-ring--visible)::after,.ds-interaction-fill.sc-ds-card-overview:hover:not(:disabled):not(:focus-visible):not(:focus-within):not(.ds-focus-ring--visible)::after{outline-color:var(--ds-forced-color-selected);outline-width:var(--dimension-stroke-width-012)}}@media (forced-colors: active){.sc-ds-card-overview:root,.sc-ds-card-overview-h,.ds-forced-colors-scope.sc-ds-card-overview{--ds-forced-color-surface:Canvas;--ds-forced-color-content:CanvasText;--ds-forced-color-control-boundary:ButtonText;--ds-forced-color-selected:Highlight;--ds-forced-color-on-selected:HighlightText;--ds-forced-color-disabled:GrayText}}.sc-ds-card-overview-h{--ds-focus-ring-width:var(--dimension-stroke-width-025, 2px);--ds-focus-ring-offset:var(--dimension-space-025, 2px);--ds-focus-ring-color:var(--color-interaction-focus)}.ds-focus-ring.sc-ds-card-overview-h,.ds-focus-ring.sc-ds-card-overview,.ds-focus-ring-inset.sc-ds-card-overview-h,.ds-focus-ring-inset.sc-ds-card-overview{outline:none;-webkit-tap-highlight-color:transparent;touch-action:manipulation}.ds-focus-ring.sc-ds-card-overview-h:focus-visible,.ds-focus-ring.sc-ds-card-overview:focus-visible{outline:var(--ds-focus-ring-width) solid var(--ds-focus-ring-color);outline-offset:var(--ds-focus-ring-offset)}.ds-focus-ring.ds-focus-ring--visible.sc-ds-card-overview-h,.ds-focus-ring.ds-focus-ring--visible.sc-ds-card-overview{outline:var(--ds-focus-ring-width) solid var(--ds-focus-ring-color);outline-offset:var(--ds-focus-ring-offset)}.ds-focus-ring-inset.sc-ds-card-overview-h:focus-visible,.ds-focus-ring-inset.sc-ds-card-overview:focus-visible{outline:none}.ds-focus-ring-inset.sc-ds-card-overview-h:focus-visible::after,.ds-focus-ring-inset.sc-ds-card-overview:focus-visible::after{outline:var(--ds-focus-ring-width) solid var(--ds-focus-ring-color);outline-offset:calc(-1 * var(--ds-focus-ring-width))}.ds-focus-ring-inset.ds-focus-ring--visible.sc-ds-card-overview-h,.ds-focus-ring-inset.ds-focus-ring--visible.sc-ds-card-overview{outline:none}.ds-focus-ring-inset.ds-focus-ring--visible.sc-ds-card-overview-h::after,.ds-focus-ring-inset.ds-focus-ring--visible.sc-ds-card-overview::after{outline:var(--ds-focus-ring-width) solid var(--ds-focus-ring-color);outline-offset:calc(-1 * var(--ds-focus-ring-width))}@media (forced-colors: active){.sc-ds-card-overview-h{--ds-focus-ring-color:var(--ds-forced-color-selected)}}.ds-control--lg.sc-ds-card-overview,.ds-control--lg.sc-ds-card-overview-h,.ds-control--md.sc-ds-card-overview-h,.ds-control--md.sc-ds-card-overview,.ds-control--sm.sc-ds-card-overview-h,.ds-control--sm.sc-ds-card-overview,.ds-control--xs.sc-ds-card-overview-h,.ds-control--xs.sc-ds-card-overview{--ds-control-radius:var(--dimension-radius-025)}.ds-control--lg.sc-ds-card-overview-h,.ds-control--lg.sc-ds-card-overview{--ds-control-height:var(--dimension-size-500);--ds-control-icon:var(--dimension-iconography-lg);--ds-control-padding-inline:var(--dimension-space-100);--ds-control-label-inset:var(--dimension-space-050);--ds-control-gap:var(--dimension-space-050)}.ds-control--md.sc-ds-card-overview-h,.ds-control--md.sc-ds-card-overview{--ds-control-height:var(--dimension-size-400);--ds-control-icon:var(--dimension-iconography-md);--ds-control-padding-inline:var(--dimension-space-075);--ds-control-label-inset:var(--dimension-space-025);--ds-control-gap:var(--dimension-space-050)}.ds-control--sm.sc-ds-card-overview-h,.ds-control--sm.sc-ds-card-overview{--ds-control-height:var(--dimension-size-300);--ds-control-icon:var(--dimension-iconography-sm);--ds-control-padding-inline:var(--dimension-space-050);--ds-control-label-inset:var(--dimension-space-025);--ds-control-gap:var(--dimension-space-025)}.ds-control--xs.sc-ds-card-overview-h,.ds-control--xs.sc-ds-card-overview{--ds-control-height:var(--dimension-size-200);--ds-control-icon:var(--dimension-iconography-xs);--ds-control-padding-inline:var(--dimension-space-025);--ds-control-label-inset:var(--dimension-space-025);--ds-control-gap:0}.ds-control-frame.sc-ds-card-overview{display:inline-flex;align-items:center;box-sizing:border-box;height:var(--ds-control-height, var(--dimension-size-400));padding-inline:var(--ds-control-padding-inline, var(--dimension-space-075));gap:var(--ds-control-gap, var(--dimension-space-050));border-radius:var(--ds-control-radius, var(--dimension-radius-025))}.ds-control-icon-box.sc-ds-card-overview{display:inline-flex;align-items:center;justify-content:center;flex-shrink:0;width:var(--ds-control-icon, var(--dimension-iconography-md));height:var(--ds-control-icon, var(--dimension-iconography-md))}.ds-control-label-box.sc-ds-card-overview{min-width:0;padding-inline:var(--ds-control-label-inset, var(--dimension-space-025))}.ds-control-elevation.sc-ds-card-overview-h,.ds-control-elevation.sc-ds-card-overview{position:relative;overflow:visible;box-shadow:var(--ds-control-elevation-shadow, none)}.ds-control-elevation.sc-ds-card-overview-h::after,.ds-control-elevation.sc-ds-card-overview::after{content:'';position:absolute;inset:0;z-index:4;border-radius:inherit;box-shadow:var(--ds-control-elevation-highlight, none);pointer-events:none}.ds-control-elevation--sm.sc-ds-card-overview-h,.ds-control-elevation--sm.sc-ds-card-overview{--ds-control-elevation-shadow:var(--effect-shadow-elevated-sm);--ds-control-elevation-highlight:var(--effect-highlight-elevated-sm)}.ds-control-elevation--md.sc-ds-card-overview-h,.ds-control-elevation--md.sc-ds-card-overview{--ds-control-elevation-shadow:var(--effect-shadow-elevated-md);--ds-control-elevation-highlight:var(--effect-highlight-elevated-md)}.ds-control-elevation--floating.sc-ds-card-overview-h,.ds-control-elevation--floating.sc-ds-card-overview{--ds-control-elevation-shadow:var(--effect-shadow-elevated-floating);--ds-control-elevation-highlight:var(--effect-highlight-elevated-floating)}.ds-control-elevation--press-scale.sc-ds-card-overview{--ds-control-press-active-scale:var(--dimension-scale-default);transition:scale var(--effect-motion-short-2)}.ds-control-elevation--press-scale[data-ds-press-active].sc-ds-card-overview{scale:var(--dimension-scale-subtle)}@media (prefers-reduced-motion: reduce){.ds-control-elevation--press-scale.sc-ds-card-overview,.ds-control-elevation--press-scale[data-ds-press-active].sc-ds-card-overview{scale:none;transition:none}}.sc-ds-card-overview-h{display:block;box-sizing:border-box;container-type:inline-size;-webkit-user-select:none;user-select:none;--ds-card-overview-metric-min:calc(var(--dimension-size-400) * 5);--ds-card-overview-divider-width:var(--dimension-stroke-width-012);--ds-card-overview-divider-color:var(--color-always-dark-border-tertiary);color:var(--color-always-dark-foreground-primary)}.card-overview__surface.sc-ds-card-overview{width:100%;min-width:0;box-sizing:border-box;border-radius:var(--dimension-radius-125);background:var(--color-always-dark-background);color:var(--color-always-dark-foreground-primary);overflow-anchor:none}.card-overview__clip.sc-ds-card-overview{height:100%;min-width:0;border-radius:inherit;background:inherit;overflow:hidden}.card-overview--scroll-collapsing.sc-ds-card-overview-h{height:var(--ds-card-overview-expanded-height);pointer-events:none}.card-overview--scroll-collapsing.sc-ds-card-overview-h .card-overview__surface.sc-ds-card-overview{height:var(--ds-card-overview-visible-height);pointer-events:auto;will-change:height}.card-overview--scroll-collapsing.sc-ds-card-overview-h .card-overview__body.sc-ds-card-overview{transform:translateY(calc(-1 * var(--ds-card-overview-content-offset)));will-change:transform}.card-overview__layout.sc-ds-card-overview{display:flex;flex-direction:column;min-width:0}.card-overview__summary.sc-ds-card-overview{position:relative;z-index:1;flex:0 0 auto;min-width:0;background:var(--color-always-dark-background)}.card-overview__header.sc-ds-card-overview{display:flex;position:relative;align-items:center;gap:0;width:100%;height:var(--dimension-size-600);min-width:0;padding:var(--dimension-space-100);box-sizing:border-box}.card-overview__header.sc-ds-card-overview::after{content:'';position:absolute;inset-inline:0;inset-block-end:0;height:var(--ds-card-overview-divider-width);background:var(--ds-card-overview-divider-color);pointer-events:none}.card-overview__period.sc-ds-card-overview{display:flex;flex:0 1 auto;align-items:center;gap:0;min-width:0;min-height:var(--ds-control-height);overflow:hidden;white-space:nowrap}.card-overview__period-current.sc-ds-card-overview,.card-overview__period-comparison.sc-ds-card-overview{min-width:0;overflow:hidden;text-overflow:ellipsis}.card-overview__period-current.sc-ds-card-overview{display:flex;flex:0 1 auto;align-items:center}.card-overview__period-fixed.sc-ds-card-overview{flex:0 1 auto;min-width:0}.card-overview__period-comparison.sc-ds-card-overview{flex:0 0 auto}.card-overview__filter.sc-ds-card-overview{display:flex;flex:0 1 auto;align-items:center;min-width:0}.card-overview__body.sc-ds-card-overview{display:flex;position:relative;z-index:0;flex-direction:column;min-width:0;transform:translateY(0)}.card-overview__metrics.sc-ds-card-overview{display:grid;flex:1 1 auto;grid-template-columns:repeat( var(--ds-card-overview-grid-columns, auto-fit), minmax(min(100%, var(--ds-card-overview-metric-min)), 1fr) );align-content:stretch;min-width:0;overflow:clip}.card-overview__score.sc-ds-card-overview,.card-overview__metric.sc-ds-card-overview{display:flex;min-width:0;padding:var(--dimension-space-100);box-shadow:var(--ds-card-overview-divider-width) 0 0 0 var(--ds-card-overview-divider-color), 0 var(--ds-card-overview-divider-width) 0 0 var(--ds-card-overview-divider-color);box-sizing:border-box}.card-overview__score-content.sc-ds-card-overview,.card-overview__metric-action.sc-ds-card-overview{display:flex;flex:1 1 auto;min-width:0;padding:var(--dimension-space-075);border-radius:var(--dimension-radius-025);box-sizing:border-box}.card-overview__score-content.sc-ds-card-overview{align-items:center;justify-content:space-between;gap:var(--dimension-space-100);background:var(--color-always-dark-interaction-active);color:var(--color-always-dark-foreground-primary)}.card-overview__score-content--fair.sc-ds-card-overview{background:var(--color-safety-score-background-fair);color:var(--color-safety-score-foreground-on-fair)}.card-overview__score-content--good.sc-ds-card-overview{background:var(--color-safety-score-background-good);color:var(--color-safety-score-foreground-on-good)}.card-overview__score-content--excellent.sc-ds-card-overview{background:var(--color-safety-score-background-excellent);color:var(--color-safety-score-foreground-on-excellent)}.card-overview__score-copy.sc-ds-card-overview{display:flex;flex:1 1 auto;flex-direction:column;align-items:flex-start;gap:var(--dimension-space-025);min-width:0}.card-overview__score-value.sc-ds-card-overview,.card-overview__score-figure.sc-ds-card-overview{flex:0 0 auto;margin-block:calc(-1 * var(--dimension-space-150))}.card-overview__score-content--error.sc-ds-card-overview{align-items:center;justify-content:center;border:var(--ds-card-overview-divider-width) solid var(--color-always-dark-border-tertiary);background:transparent;color:var(--color-always-dark-foreground-negative);text-align:center}.card-overview__metric-action.sc-ds-card-overview{flex-direction:column;justify-content:center;gap:var(--dimension-space-050)}.card-overview__metric-action[role='button'].sc-ds-card-overview{cursor:default}.card-overview__metric-content.sc-ds-card-overview{display:flex;flex-direction:column;justify-content:center;gap:var(--dimension-space-050);min-width:0}.card-overview__metric-label.sc-ds-card-overview{min-width:0}.card-overview__metric-figure.sc-ds-card-overview{display:flex;align-items:baseline;gap:var(--dimension-space-100);min-width:0}.card-overview__trend.sc-ds-card-overview{flex:0 0 auto;white-space:nowrap}.card-overview--stacked.sc-ds-card-overview-h .card-overview__metrics.sc-ds-card-overview{grid-template-columns:minmax(0, 1fr)}.card-overview--compact.sc-ds-card-overview-h{height:var(--dimension-size-600);min-height:var(--dimension-size-600)}.card-overview--compact.sc-ds-card-overview-h .card-overview__surface.sc-ds-card-overview,.card-overview--compact.sc-ds-card-overview-h .card-overview__clip.sc-ds-card-overview,.card-overview--compact.sc-ds-card-overview-h .card-overview__layout.sc-ds-card-overview,.card-overview--compact.sc-ds-card-overview-h .card-overview__summary.sc-ds-card-overview{width:100%;height:100%}.card-overview--compact.sc-ds-card-overview-h .card-overview__header.sc-ds-card-overview::after{display:none}@media (forced-colors: active){.card-overview__header.sc-ds-card-overview::after{background:var(--ds-forced-color-content)}.card-overview__score-content.sc-ds-card-overview{border:var(--dimension-stroke-width-012) solid var(--ds-forced-color-content);background:var(--ds-forced-color-surface);color:var(--ds-forced-color-content)}}`;const g="var(--dimension-menu-width-xs)";const p=4;const b=7;const _={positive:"var(--color-always-dark-foreground-positive)",negative:"var(--color-always-dark-foreground-negative)",neutral:"var(--color-always-dark-foreground-secondary)"};const x="var(--color-always-dark-foreground-primary)";const y="var(--color-always-dark-foreground-secondary)";const k=e(class e extends r{constructor(e){super();if(e!==false){this.__registerHost()}this.dsMetricSelect=o(this,"dsMetricSelect");this.variant="default";this.layout="auto";this.periodLabel="";this.comparisonLabel="";this.metrics=[];this.metricMinWidth=g;this.isLoading=false;this.overviewLabel="Overview";this.scrollCollapseProgress=0;this.focusedMetricIndex=0;this.expandedHeight=0;this.layoutResizeObserver=null;this.handleMetricKeyDown=(e,r)=>{switch(e.key){case"ArrowRight":case"ArrowDown":e.preventDefault();this.moveFocus(r,1);break;case"ArrowLeft":case"ArrowUp":e.preventDefault();this.moveFocus(r,-1);break}}}componentDidLoad(){this.observeLayout()}componentDidRender(){if(!this.layoutResizeObserver)this.observeLayout();else this.updateLayoutGeometry()}disconnectedCallback(){this.layoutResizeObserver?.disconnect();this.layoutResizeObserver=null}get visibleMetrics(){return this.metrics.slice(0,b)}get visibleCellCount(){const e=this.isLoading&&this.metrics.length===0?p:this.visibleMetrics.length;return 1+e}get resolvedScrollCollapseProgress(){if(this.variant==="compact"||!Number.isFinite(this.scrollCollapseProgress))return 0;return Math.min(1,Math.max(0,this.scrollCollapseProgress))}get scrollCollapseGeometry(){const e=n(v.size600,48);return f({variant:this.variant,progress:this.resolvedScrollCollapseProgress,expandedHeight:this.expandedHeight,compactHeight:e})}observeLayout(){const e=this.layoutEl;if(!e)return;const r=e.getBoundingClientRect();this.updateLayoutGeometry(r.width,r.height);if(typeof ResizeObserver==="undefined")return;this.layoutResizeObserver?.disconnect();this.layoutResizeObserver=new ResizeObserver((e=>{const r=e[0]?.contentRect;if(r)this.updateLayoutGeometry(r.width,r.height)}));this.layoutResizeObserver.observe(e)}updateLayoutGeometry(e,r){const o=this.layoutEl;if(!o)return;const i=e===undefined||r===undefined?o.getBoundingClientRect():null;const s=e??i?.width??0;const c=r??i?.height??0;if(c>0&&Math.abs(c-this.expandedHeight)>=.5){this.expandedHeight=c}const d=l({cellCount:this.visibleCellCount,availableWidth:s,minCellWidth:n(this.metricMinWidth,v.menuWidthXs)});if(d!==this.gridColumns)this.gridColumns=d}get rovingIndex(){return h(this.visibleMetrics,this.focusedMetricIndex)}selectMetric(e,r){if(e.isInactive)return;this.focusedMetricIndex=r;this.dsMetricSelect.emit(e)}moveFocus(e,r){const o=this.visibleMetrics;const i=u(o,e,r<0?-1:1);if(i<0)return;this.focusedMetricIndex=i;const s=this.el.querySelectorAll(".card-overview__metric-action");s[i]?.focus()}bar(e,r,o){return i("ds-skeleton",{class:o,variant:"text",textVariant:e,width:r,background:"always-dark"})}renderTrend(e,r,o=false,s){if(!e)return null;return i("ds-text",{as:"span",class:{"card-overview__trend":true,"ds-control-label-box":true,[`card-overview__trend--${e.tone}`]:true},variant:r,emphasis:o,color:s??_[e.tone],fontFeature:"tabular-nums"},e.direction==="up"?"↑":"↓"," ",e.value)}renderScore(){if(this.isLoading){return i("div",{class:"card-overview__score",part:"score"},i("div",{class:"card-overview__score-content"},i("div",{class:"card-overview__score-copy"},this.bar("text-body-small","64px","card-overview__score-label"),this.bar("text-body-medium","28px")),i("div",{class:"card-overview__score-figure"},this.bar("text-display-medium","56px"))))}const e=this.scoreErrorMessage||(!this.score?"Score unavailable":undefined);if(e){return i("div",{class:"card-overview__score",part:"score"},i("ds-text",{as:"span",class:"card-overview__score-content card-overview__score-content--error",variant:"text-body-medium",color:"inherit",role:"alert"},e))}const r=this.score;if(!r)return null;const o=r.level??w(r.value);return i("div",{class:"card-overview__score",part:"score"},i("div",{class:{"card-overview__score-content":true,[`card-overview__score-content--${o}`]:Boolean(o)}},i("div",{class:"card-overview__score-copy"},i("ds-text",{as:"span",class:"card-overview__score-label ds-control-label-box",variant:"text-body-small",color:"inherit"},r.label),this.renderTrend(r.trend,"text-body-medium",false,"inherit")),i("ds-text",{as:"span",class:"card-overview__score-value ds-control-label-box",variant:"text-display-medium",emphasis:true,color:"inherit",fontFeature:"tabular-nums"},r.value)))}renderMetric(e,r){const o=!e.isInactive;const s=i("ds-text",{as:"span",class:"card-overview__metric-label ds-control-label-box",variant:"text-body-small",color:y},e.label);return i("div",{class:"card-overview__metric",part:"metric"},i("div",{class:{"card-overview__metric-action":true,"card-overview__metric-action--inactive":!o,"ds-interaction-fill":o,"ds-interaction-fill--on-always-dark":o,"ds-focus-ring-inset":o},role:o?"button":undefined,tabIndex:o&&r===this.rovingIndex?0:-1,onClick:()=>this.selectMetric(e,r),onKeyDown:e=>this.handleMetricKeyDown(e,r),onFocusin:()=>{if(o)this.focusedMetricIndex=r}},i("div",{class:"ds-interaction-fill__content card-overview__metric-content"},e.labelTooltip?i("ds-tooltip",{label:e.labelTooltip,side:"top",size:"sm"},s):s,i("div",{class:"card-overview__metric-figure"},i("ds-text",{as:"span",class:"card-overview__metric-value ds-control-label-box",variant:"text-body-medium",color:x,fontFeature:"tabular-nums"},e.value),this.renderTrend(e.trend,"text-body-medium")))))}renderMetrics(){if(this.isLoading&&this.metrics.length===0){return[this.renderScore(),...Array.from({length:p},((e,r)=>i("div",{class:"card-overview__metric",key:`loading-${r}`},i("div",{class:"card-overview__metric-action card-overview__metric-action--inactive"},this.bar("text-body-small","70%","card-overview__metric-label"),i("div",{class:"card-overview__metric-figure"},this.bar("text-body-medium","36px"),this.bar("text-body-medium","40px"))))))]}return[this.renderScore(),...this.visibleMetrics.map(((e,r)=>this.renderMetric(e,r)))]}render(){const e=this.variant==="compact";const r=this.scrollCollapseGeometry;return i(s,{key:"efa3cddfce3171c774f277c88ffbceab7077b163",class:{"card-overview":true,"card-overview--compact":e,"card-overview--stacked":!e&&this.layout==="stacked","card-overview--scroll-collapsing":r.active},role:"region","aria-label":this.overviewLabel,"aria-busy":this.isLoading?"true":undefined,style:{"--ds-card-overview-metric-min":this.metricMinWidth,"--ds-card-overview-grid-columns":this.gridColumns?String(this.gridColumns):undefined,"--ds-card-overview-expanded-height":r.active?`${r.expandedHeight}px`:undefined,"--ds-card-overview-visible-height":r.active?`${r.visibleHeight}px`:undefined,"--ds-card-overview-content-offset":r.active?`${r.offset}px`:undefined}},i("div",{key:"71d27a42ca4da8dff057b72301d82e5ada9d9ef4",class:{"card-overview__surface":true,"ds-control-elevation":true,"ds-control-elevation--sm":!e,"ds-control-elevation--floating":e}},i("div",{key:"1a5eb63e7ba34a098afe261361e42c4d074ed0e1",class:"card-overview__clip"},i("div",{key:"5d41b25a34c9f1419da14aa76c7e08aaffaa07c4",ref:e=>{this.layoutEl=e??undefined},class:{"card-overview__layout":true}},i("div",{key:"898c5bde120a2ad606001be415f6bec85578ff8c",class:"card-overview__summary"},i("div",{key:"66b283d535ab7054ee9d1ede2627555491f793af",class:"card-overview__header ds-control--md"},this.isLoading?i("div",{class:"card-overview__period"},this.bar("text-body-medium","184px"),this.bar("text-body-medium","248px")):i("div",{class:"card-overview__period"},i("div",{class:"card-overview__period-current"},i("slot",{name:"period"},this.periodLabel&&i("div",{class:"card-overview__period-fixed ds-control-frame"},i("ds-text",{as:"span",class:"ds-control-label-box",variant:"text-body-medium",emphasis:true,color:x},this.periodLabel)))),this.comparisonLabel&&i("ds-text",{as:"span",class:"card-overview__period-comparison ds-control-label-box",variant:"text-body-medium",color:y},this.comparisonLabel)),i("div",{key:"6fc99c513ef57b516baddbac32c9886d6b294705",class:"card-overview__filter"},this.isLoading?i("ds-skeleton",{variant:"control",controlSize:"md",width:"128px",background:"always-dark"}):i("slot",{name:"filter"})))),!e&&i("div",{key:"b326dec2d06a0c92d5135b5a9e9b28eb388dd0bc",class:"card-overview__body"},i("div",{key:"8476805c27aed8b99b2ee85468d6e2c57830dd58",class:"card-overview__metrics",part:"metrics"},this.renderMetrics()),i("slot",{key:"f27662ddde98c17c283183697f3d3f17fbff5c04",name:"footer"}))))))}get el(){return this}static get style(){return m()}},[262,"ds-card-overview",{variant:[1],layout:[1],score:[16],periodLabel:[1,"period-label"],comparisonLabel:[1,"comparison-label"],metrics:[16],metricMinWidth:[1,"metric-min-width"],isLoading:[4,"is-loading"],scoreErrorMessage:[1,"score-error-message"],overviewLabel:[1,"overview-label"],scrollCollapseProgress:[2,"scroll-collapse-progress"],focusedMetricIndex:[32],expandedHeight:[32],gridColumns:[32]}]);function z(){if(typeof customElements==="undefined"){return}const e=["ds-card-overview","ds-skeleton","ds-text","ds-tooltip"];e.forEach((e=>{switch(e){case"ds-card-overview":if(!customElements.get(c(e))){customElements.define(c(e),k)}break;case"ds-skeleton":if(!customElements.get(c(e))){d()}break;case"ds-text":if(!customElements.get(c(e))){t()}break;case"ds-tooltip":if(!customElements.get(c(e))){a()}break}}))}z();const M=k;const C=z;export{M as DsCardOverview,C as defineCustomElement};
2
2
  //# sourceMappingURL=ds-card-overview.js.map
@@ -1 +1 @@
1
- {"version":3,"names":["resolveCardOverviewCollapseGeometry","options","compactHeight","Math","max","expandedHeight","progress","variant","Number","isFinite","min","distance","offset","active","visibleHeight","resolveOverviewRovingIndex","metrics","focusedIndex","first","findIndex","metric","isInactive","findNextOverviewMetricIndex","from","step","length","next","cardOverviewCss","DEFAULT_METRIC_MIN_WIDTH","LOADING_PLACEHOLDER_COUNT","MAX_METRIC_COUNT","TREND_COLORS","positive","negative","neutral","ALWAYS_DARK_PRIMARY","ALWAYS_DARK_SECONDARY","CardOverview","__stencil_proxyCustomElement","HTMLElement","constructor","registerHost","this","layout","periodLabel","comparisonLabel","metricMinWidth","isLoading","overviewLabel","scrollCollapseProgress","focusedMetricIndex","layoutResizeObserver","handleMetricKeyDown","event","index","key","preventDefault","moveFocus","componentDidLoad","observeLayout","componentDidRender","disconnectedCallback","disconnect","hasScore","score","undefined","scoreErrorMessage","visibleMetrics","slice","resolvedScrollCollapseProgress","scrollCollapseGeometry","resolveCssLengthPx","TOKEN_DEFAULTS","size600","layoutEl","updateHeight","height","abs","getBoundingClientRect","ResizeObserver","entries","contentRect","observe","rovingIndex","selectMetric","dsMetricSelect","emit","cells","el","querySelectorAll","focus","bar","textVariant","width","className","h","class","background","renderTrend","trend","emphasis","as","tone","color","fontFeature","direction","value","renderScore","compact","part","role","name","size","label","band","renderMetric","selectable","tabIndex","onClick","onKeyDown","onFocusin","labelTooltip","side","renderMetrics","Array","_","map","render","hasHeader","Boolean","collapse","Host","style","ref","element","controlSize"],"sources":["src/wc/components/CardOverview/card-overview-controller.ts","src/wc/components/CardOverview/CardOverview.css?tag=ds-card-overview&encapsulation=scoped","src/wc/components/CardOverview/CardOverview.tsx"],"sourcesContent":["import type { CardOverviewVariant, OverviewMetric } from './card-overview-types';\n\nexport interface CardOverviewCollapseGeometry {\n active: boolean;\n expandedHeight: number;\n offset: number;\n visibleHeight: number;\n}\n\nexport function resolveCardOverviewCollapseGeometry(options: {\n variant: CardOverviewVariant;\n progress: number;\n expandedHeight: number;\n compactHeight: number;\n}): CardOverviewCollapseGeometry {\n const compactHeight = Math.max(0, options.compactHeight);\n const expandedHeight = Math.max(options.expandedHeight, compactHeight);\n const progress =\n options.variant === 'compact' || !Number.isFinite(options.progress)\n ? 0\n : Math.min(1, Math.max(0, options.progress));\n const distance = Math.max(0, expandedHeight - compactHeight);\n const offset = distance * progress;\n\n return {\n active: progress > 0 && distance > 0,\n expandedHeight,\n offset,\n visibleHeight: expandedHeight - offset,\n };\n}\n\nexport function resolveOverviewRovingIndex(\n metrics: readonly OverviewMetric[],\n focusedIndex: number\n): number {\n const first = metrics.findIndex(metric => !metric.isInactive);\n if (first < 0) return -1;\n return metrics[focusedIndex] && !metrics[focusedIndex].isInactive\n ? focusedIndex\n : first;\n}\n\nexport function findNextOverviewMetricIndex(\n metrics: readonly OverviewMetric[],\n from: number,\n step: -1 | 1\n): number {\n for (let offset = 1; offset <= metrics.length; offset += 1) {\n const next = (((from + step * offset) % metrics.length) + metrics.length) % metrics.length;\n if (!metrics[next]?.isInactive) return next;\n }\n return -1;\n}\n","@import '../../utils/interaction-fill.css';\n@import '../../utils/focus-ring.css';\n@import '../../utils/control-density.css';\n@import '../../utils/control-parts.css';\n@import '../../styles/control-elevation.css';\n\n/* The summary bar follows the always-dark sub-theme. */\n\n:host {\n display: block;\n box-sizing: border-box;\n /* Drives the narrow layout below from the card's own width, not the viewport's. */\n container-type: inline-size;\n /* A summary is read, not copied; stray selection while clicking cells is noise. */\n -webkit-user-select: none;\n user-select: none;\n /* Width a metric may shrink to before the grid drops a column. */\n --ds-card-overview-metric-min: calc(var(--dimension-size-400) * 5);\n --ds-card-overview-divider-width: var(--dimension-stroke-width-012);\n --ds-card-overview-divider-color: var(--color-always-dark-border-tertiary);\n --ds-card-overview-divider: var(--ds-card-overview-divider-width) solid\n var(--ds-card-overview-divider-color);\n color: var(--color-always-dark-foreground-primary);\n}\n\n.card-overview__surface {\n width: 100%;\n min-width: 0;\n box-sizing: border-box;\n border-radius: var(--dimension-radius-050);\n background: var(--color-always-dark-background);\n color: var(--color-always-dark-foreground-primary);\n overflow-anchor: none;\n}\n\n/*\n * The visual surface owns elevation outside this clipping viewport. Keeping\n * those layers separate lets a page shrink the surface while content moves and\n * clips inside it without cutting off the shadow or inset highlight.\n */\n.card-overview__clip {\n height: 100%;\n min-width: 0;\n border-radius: inherit;\n background: inherit;\n overflow: hidden;\n}\n\n:host(.card-overview--scroll-collapsing) {\n height: var(--ds-card-overview-expanded-height);\n pointer-events: none;\n}\n\n:host(.card-overview--scroll-collapsing) .card-overview__surface {\n height: var(--ds-card-overview-visible-height);\n pointer-events: auto;\n will-change: height;\n}\n\n:host(.card-overview--scroll-collapsing) .card-overview__layout {\n transform: translateY(calc(-1 * var(--ds-card-overview-content-offset)));\n will-change: transform;\n}\n\n.card-overview__layout {\n display: grid;\n grid-template-rows: auto minmax(0, 1fr);\n grid-template-columns: minmax(0, 1fr);\n align-items: stretch;\n min-width: 0;\n}\n\n.card-overview__layout--has-score {\n grid-template-columns: auto minmax(0, 1fr);\n}\n\n/*\n * Transparent at regular widths so the score and header participate in the\n * inner layout grid directly. At the narrow breakpoint it becomes the unified\n * summary block above the metrics.\n */\n.card-overview__summary {\n display: contents;\n}\n\n/* ── Score ────────────────────────────────────────────────────────────────── */\n\n/*\n * Hugs its content and never shrinks, so the headline figure keeps its size and\n * the metric grid absorbs the remaining width.\n */\n/*\n * Top aligned rather than centred, and padded to match the header, so the score\n * label sits in the same 32px box at the same offset as the period text beside\n * it. Both use the same type variant, so their baselines land together.\n */\n.card-overview__score {\n display: flex;\n grid-row: 1 / span 2;\n grid-column: 1;\n flex: 0 0 auto;\n flex-direction: column;\n gap: 0;\n min-width: 0;\n padding: var(--dimension-space-100) var(--dimension-space-200);\n border-inline-end: var(--ds-card-overview-divider);\n}\n\n.card-overview__score--resolved {\n min-inline-size: max-content;\n}\n\n/* The control-height box that aligns this label with the period text. */\n.card-overview__score-label-row {\n display: flex;\n align-items: center;\n min-height: var(--ds-control-height);\n}\n\n/*\n * The score is its own column, so its rows cannot baseline-align with the measure\n * rows through flex or grid — those only align items that share a line. These two\n * offsets pull the column onto the measure baselines instead.\n *\n * They are compensation for how much lower a display-scale figure sits in its line\n * box than the body text it aligns to, so they are coupled to the type pairing:\n * change the score or measure variants and both need re-measuring.\n */\n.card-overview__score-figure {\n display: flex;\n align-items: baseline;\n gap: var(--dimension-space-050);\n min-width: 0;\n margin-block-start: calc(-1 * (var(--dimension-space-150) + var(--dimension-space-012)));\n}\n\n.card-overview__score-value {\n flex: 0 0 auto;\n}\n\n/* Second half of the baseline compensation described above the score figure. */\n.card-overview__score-band {\n margin-block-start: calc(-1 * var(--dimension-space-025));\n}\n\n/*\n * A skeleton bar is a solid block, so in a baseline-aligned row it aligns on its\n * bottom edge while the text it stands in for aligns on its baseline. Next to a\n * display-scale figure that difference is the descent under the figure's\n * baseline, which drops the bar below where the resolved trend sits.\n *\n * The offset is applied with relative positioning rather than a margin: a margin\n * is not part of a synthesized baseline, so it grows the figure instead of moving\n * the bar, which then pushes the band below it out of place.\n *\n * Only needed beside the score figure; the measure rows pair body variants whose\n * bottom edge and baseline already agree.\n */\n.card-overview__skeleton-baseline {\n position: relative;\n inset-block-start: calc(-1 * var(--dimension-space-150));\n}\n\n.card-overview__score--error {\n flex-direction: row;\n align-items: center;\n gap: var(--dimension-space-050);\n color: var(--color-always-dark-foreground-negative);\n}\n\n/* ── Body ─────────────────────────────────────────────────────────────────── */\n\n/*\n * Takes the remaining inline space. The minimum is what makes the host wrap: once\n * the score and roughly two measure columns no longer fit side by side, the body\n * drops below the score instead of squeezing it. `min()` keeps that from becoming\n * an overflow floor on very narrow viewports.\n */\n.card-overview__body {\n display: flex;\n grid-row: 2;\n grid-column: 1;\n flex-direction: column;\n min-width: 0;\n}\n\n.card-overview__body--has-score {\n grid-column: 2;\n}\n\n/*\n * One control row: 8px of padding on every side around a 32px md control, so the\n * bar is 8 + 32 + 8. Both ends of the bar are control-shaped boxes — the period\n * text on the left and the slotted control on the right — so the row reads\n * balanced rather than text on one side and a control on the other.\n */\n.card-overview__header {\n display: flex;\n grid-row: 1;\n grid-column: 1;\n align-items: center;\n gap: var(--dimension-space-100);\n min-width: 0;\n padding: var(--dimension-space-100);\n border-block-end: var(--ds-card-overview-divider);\n box-sizing: border-box;\n}\n\n.card-overview__header--has-score {\n grid-column: 2;\n}\n\n/*\n * Matches the control's box on the opposite end, including its inline padding, so\n * the text lands at the same optical inset the slotted control does:\n * 8 from the bar + 6 from this box + 2 from the label inset = 16.\n *\n * Nowrap keeps the row at the control height; the period truncates rather than\n * growing the bar to two lines.\n */\n.card-overview__period {\n display: flex;\n flex: 1 1 auto;\n align-items: center;\n gap: var(--dimension-space-050);\n min-height: var(--ds-control-height);\n min-width: 0;\n padding-inline: var(--ds-control-padding-inline);\n overflow: hidden;\n white-space: nowrap;\n}\n\n/* The period control is slotted, so only reserve space for it. */\n.card-overview__filter {\n display: flex;\n flex: 0 0 auto;\n align-items: center;\n}\n\n/* ── Metrics ──────────────────────────────────────────────────────────────── */\n\n/*\n * `auto-fit` gives every occupied track an equal share while all metrics fit on\n * one row. Once wrapping creates another row, its cells stay on those same\n * tracks, so a partial final row leaves empty space instead of stretching one\n * measure wider than its peers.\n *\n * Dividers are painted outward from each cell and clipped by this grid. That\n * leaves only the lines between cells: anything emitted from the final column or\n * final row lands outside the grid and is clipped without needing to detect the\n * number of tracks.\n *\n * `flex: 1 1 auto` makes the grid absorb whatever height the body has\n * left, so cells reach the card bottom and their hover wash has no dead strip.\n */\n.card-overview__metrics {\n display: grid;\n flex: 1 1 auto;\n grid-template-columns: repeat(\n auto-fit,\n minmax(min(100%, var(--ds-card-overview-metric-min)), 1fr)\n );\n align-content: stretch;\n min-width: 0;\n overflow: clip;\n}\n\n/*\n * Square by design. Cells tile edge to edge against their dividers, so a radius\n * would break the seam; the card's own radius clips the outer corners instead.\n *\n * Padding is plain rather than control-derived: a cell is a block of content, not\n * a control box that has to optically match something on the far side.\n */\n.card-overview__metric {\n display: flex;\n position: relative;\n flex-direction: column;\n gap: var(--dimension-space-050);\n min-width: 0;\n padding: var(--dimension-space-175) var(--dimension-space-200);\n border-radius: 0;\n box-shadow:\n var(--ds-card-overview-divider-width) 0 0 0 var(--ds-card-overview-divider-color),\n 0 var(--ds-card-overview-divider-width) 0 0 var(--ds-card-overview-divider-color);\n}\n\n.card-overview__metric[role='button'] {\n cursor: default;\n -webkit-user-select: none;\n user-select: none;\n}\n\n.card-overview__metric-label {\n min-width: 0;\n}\n\n.card-overview__metric-figure {\n display: flex;\n align-items: baseline;\n gap: var(--dimension-space-100);\n min-width: 0;\n}\n\n/* ── Trend ────────────────────────────────────────────────────────────────── */\n\n/*\n * Tone arrives resolved from the caller: the arrow direction and the sentiment\n * are independent, so a falling metric can read positive or neutral. The arrow is\n * a glyph inside this text node, so it always matches the surrounding weight.\n */\n.card-overview__trend {\n flex: 0 0 auto;\n white-space: nowrap;\n}\n\n/* ── Narrow layout ────────────────────────────────────────────────────────── */\n\n/*\n * Below roughly two measure columns the card becomes a full stack. The summary\n * wrapper owns one block above the metrics: score label, figure, and trend stay\n * together at the start; the period control sits at the upper end; and the period\n * copy follows the score instead of becoming a separate divided row.\n */\n/*\n * Selectors are host-qualified purely for specificity: the compiled sheet places\n * these rules ahead of the base ones, so a plain class here would only ever add\n * properties and never override them.\n */\n@container (max-width: 480px) {\n :host .card-overview__layout {\n grid-template-rows: auto minmax(0, 1fr);\n grid-template-columns: minmax(0, 1fr);\n }\n\n :host .card-overview__summary {\n display: grid;\n grid-row: 1;\n grid-column: 1;\n grid-template-columns: minmax(0, 1fr) auto;\n grid-template-rows: auto;\n border-block-end: var(--ds-card-overview-divider);\n }\n\n :host .card-overview__score {\n display: grid;\n grid-row: 1;\n grid-column: 1;\n grid-template-rows: auto auto;\n grid-template-columns: auto auto;\n justify-content: start;\n column-gap: var(--dimension-space-100);\n width: auto;\n padding-block-end: var(--dimension-space-100);\n padding-inline-end: var(--dimension-space-100);\n border-inline-end: none;\n }\n\n :host .card-overview__score-label-row {\n grid-row: 1;\n grid-column: 1 / -1;\n min-height: var(--ds-control-height);\n }\n\n /*\n * The wide score uses optical offsets to meet the neighbouring metric\n * baselines. In the stacked summary those neighbours are gone, so natural\n * document flow keeps the label, figure, band, and period clearly ordered.\n */\n :host .card-overview__score-band,\n :host .card-overview__score-figure {\n grid-row: 2;\n margin-block-start: 0;\n }\n\n :host .card-overview__score-figure {\n grid-column: 1;\n align-self: baseline;\n gap: var(--dimension-space-100);\n }\n\n :host .card-overview__score-band {\n grid-column: 2;\n align-self: baseline;\n display: none;\n }\n\n :host .card-overview__header {\n display: grid;\n grid-row: 1;\n grid-column: 2;\n grid-template-rows: auto auto;\n align-content: start;\n gap: 0;\n padding: 0;\n border-block-end: none;\n }\n\n :host .card-overview__filter {\n grid-row: 1;\n grid-column: 1;\n align-self: start;\n justify-self: end;\n padding: var(--dimension-space-100) var(--dimension-space-100) 0 0;\n }\n\n :host .card-overview__period {\n grid-row: 2;\n grid-column: 1;\n flex-direction: column;\n align-items: flex-end;\n justify-self: stretch;\n gap: 0;\n min-height: 0;\n padding-block: var(--dimension-space-150) var(--dimension-space-100);\n padding-inline: var(--dimension-space-100) var(--dimension-space-200);\n overflow: visible;\n text-align: end;\n white-space: nowrap;\n }\n\n :host .card-overview__body {\n grid-row: 2;\n grid-column: 1;\n }\n}\n\n/*\n * Page shells may enter a responsive mode before this card itself becomes\n * narrow. The explicit stacked layout applies the same composition without\n * coupling CardOverview to a viewport breakpoint.\n */\n:host(.card-overview--stacked) .card-overview__layout {\n grid-template-rows: auto minmax(0, 1fr);\n grid-template-columns: minmax(0, 1fr);\n}\n\n:host(.card-overview--stacked) .card-overview__summary {\n display: grid;\n grid-row: 1;\n grid-column: 1;\n grid-template-columns: minmax(0, 1fr) auto;\n grid-template-rows: auto;\n border-block-end: var(--ds-card-overview-divider);\n}\n\n:host(.card-overview--stacked) .card-overview__score {\n display: grid;\n grid-row: 1;\n grid-column: 1;\n grid-template-rows: auto auto;\n grid-template-columns: auto auto;\n justify-content: start;\n column-gap: var(--dimension-space-100);\n width: auto;\n padding-block-end: var(--dimension-space-100);\n padding-inline-end: var(--dimension-space-100);\n border-inline-end: none;\n}\n\n:host(.card-overview--stacked) .card-overview__score-label-row {\n grid-row: 1;\n grid-column: 1 / -1;\n min-height: var(--ds-control-height);\n}\n\n:host(.card-overview--stacked) .card-overview__score-band,\n:host(.card-overview--stacked) .card-overview__score-figure {\n grid-row: 2;\n margin-block-start: 0;\n}\n\n:host(.card-overview--stacked) .card-overview__score-figure {\n grid-column: 1;\n align-self: baseline;\n gap: var(--dimension-space-100);\n}\n\n:host(.card-overview--stacked) .card-overview__score-band {\n grid-column: 2;\n align-self: baseline;\n display: none;\n}\n\n:host(.card-overview--stacked) .card-overview__header {\n display: grid;\n grid-row: 1;\n grid-column: 2;\n grid-template-rows: auto auto;\n align-content: start;\n gap: 0;\n padding: 0;\n border-block-end: none;\n}\n\n:host(.card-overview--stacked) .card-overview__filter {\n grid-row: 1;\n grid-column: 1;\n align-self: start;\n justify-self: end;\n padding: var(--dimension-space-100) var(--dimension-space-100) 0 0;\n}\n\n:host(.card-overview--stacked) .card-overview__period {\n grid-row: 2;\n grid-column: 1;\n flex-direction: column;\n align-items: flex-end;\n justify-self: stretch;\n gap: 0;\n min-height: 0;\n padding-block: var(--dimension-space-150) var(--dimension-space-100);\n padding-inline: var(--dimension-space-100) var(--dimension-space-200);\n overflow: visible;\n text-align: end;\n white-space: nowrap;\n}\n\n:host(.card-overview--stacked) .card-overview__body {\n grid-row: 2;\n grid-column: 1;\n}\n\n:host(.card-overview--stacked) .card-overview__metrics {\n grid-template-columns: minmax(0, 1fr);\n}\n\n/* ── Compact presentation ───────────────────────────────────────────────── */\n\n/*\n * Matches the shared 48px bar contract: one 32px control row with 8px above\n * and below. The score remains a distinct leading cell, while reporting copy\n * absorbs the available width and the application-owned control never shrinks.\n */\n:host(.card-overview--compact) {\n height: var(--dimension-size-600);\n min-height: var(--dimension-size-600);\n}\n\n:host(.card-overview--compact) .card-overview__surface {\n height: 100%;\n}\n\n:host(.card-overview--compact) .card-overview__layout,\n:host(.card-overview--compact) .card-overview__summary {\n display: flex;\n width: 100%;\n height: 100%;\n min-width: 0;\n}\n\n:host(.card-overview--compact) .card-overview__score {\n display: flex;\n flex: 0 0 auto;\n flex-direction: row;\n align-items: center;\n gap: var(--dimension-space-100);\n width: auto;\n height: 100%;\n min-width: 0;\n padding: var(--dimension-space-100) var(--dimension-space-200);\n border-inline-end: var(--ds-card-overview-divider);\n box-sizing: border-box;\n}\n\n:host(.card-overview--compact) .card-overview__score-label-row {\n display: contents;\n min-height: 0;\n}\n\n:host(.card-overview--compact) .card-overview__score-label,\n:host(.card-overview--compact) .card-overview__score-figure,\n:host(.card-overview--compact) .card-overview__trend {\n flex: 0 0 auto;\n}\n\n:host(.card-overview--compact) .card-overview__score-figure {\n display: flex;\n align-self: center;\n align-items: baseline;\n gap: var(--dimension-space-050);\n margin-block-start: 0;\n}\n\n:host(.card-overview--compact) .card-overview__score-band {\n display: none;\n}\n\n:host(.card-overview--compact) .card-overview__header {\n display: flex;\n flex: 1 1 auto;\n grid-row: auto;\n grid-column: auto;\n align-items: center;\n gap: var(--dimension-space-100);\n height: 100%;\n min-width: 0;\n padding: var(--dimension-space-100);\n border-block-end: none;\n box-sizing: border-box;\n}\n\n:host(.card-overview--compact) .card-overview__period {\n display: flex;\n flex: 1 1 auto;\n flex-direction: row;\n align-items: center;\n gap: var(--dimension-space-050);\n min-width: 0;\n min-height: var(--ds-control-height);\n padding-inline: var(--ds-control-padding-inline);\n overflow: hidden;\n text-align: start;\n white-space: nowrap;\n}\n\n:host(.card-overview--compact) .card-overview__period-current,\n:host(.card-overview--compact) .card-overview__period-comparison {\n min-width: 0;\n overflow: hidden;\n text-overflow: ellipsis;\n}\n\n:host(.card-overview--compact) .card-overview__period-current {\n flex: 0 1 auto;\n}\n\n:host(.card-overview--compact) .card-overview__period-comparison {\n flex: 1 1 auto;\n}\n\n:host(.card-overview--compact) .card-overview__filter {\n display: flex;\n flex: 0 0 auto;\n align-items: center;\n padding: 0;\n}\n","import { Component, Element, Event, EventEmitter, h, Host, Prop, State } from '@stencil/core';\nimport { resolveCssLengthPx, TOKEN_DEFAULTS } from '../../utils';\nimport type { TextColor, TextVariant } from '../Text/text-types';\nimport type { MetricTrend } from '../../utils/metric-change';\nimport type {\n CardOverviewLayout,\n CardOverviewVariant,\n OverviewMetric,\n OverviewScore,\n} from './card-overview-types';\nimport {\n findNextOverviewMetricIndex,\n resolveCardOverviewCollapseGeometry,\n resolveOverviewRovingIndex,\n} from './card-overview-controller';\n\n/** Metric cells below this width drop a grid column rather than compress further. */\nconst DEFAULT_METRIC_MIN_WIDTH = 'var(--dimension-menu-width-xs)';\n\n/** Skeleton cells rendered while loading with no metrics supplied yet. */\nconst LOADING_PLACEHOLDER_COUNT = 4;\n\n/** Maximum number of comparable measures the summary bar presents at once. */\nconst MAX_METRIC_COUNT = 6;\n\nconst TREND_COLORS: Record<MetricTrend['tone'], TextColor> = {\n positive: 'var(--color-always-dark-foreground-positive)',\n negative: 'var(--color-always-dark-foreground-negative)',\n neutral: 'var(--color-always-dark-foreground-secondary)',\n};\n\nconst ALWAYS_DARK_PRIMARY: TextColor = 'var(--color-always-dark-foreground-primary)';\nconst ALWAYS_DARK_SECONDARY: TextColor = 'var(--color-always-dark-foreground-secondary)';\n\n@Component({\n tag: 'ds-card-overview',\n styleUrl: 'CardOverview.css',\n scoped: true,\n})\nexport class CardOverview {\n @Element() el!: HTMLElement;\n\n /** Full summary card, or the condensed 48px summary bar. */\n @Prop() variant: CardOverviewVariant = 'default';\n\n /** Intrinsic responsive layout, or a page-owned single-column stack. */\n @Prop() layout: CardOverviewLayout = 'auto';\n\n /** Leading summary block. Omit to render the bar without a headline figure. */\n @Prop() score: OverviewScore | undefined;\n\n /** Current reporting period, for example `Jun 29, 2026 – Jul 26, 2026`. */\n @Prop() periodLabel: string = '';\n\n /** Comparison caption, for example `vs Previous period`. */\n @Prop() comparisonLabel: string = '';\n\n /** Measures rendered in the responsive grid. Only the first six are shown. */\n @Prop() metrics: OverviewMetric[] = [];\n\n /**\n * Width a metric cell may shrink to before the grid drops a column. The grid\n * reflows and then stacks from this alone, so no measurement is required.\n */\n @Prop() metricMinWidth: string = DEFAULT_METRIC_MIN_WIDTH;\n\n /** Replace the score and metrics with skeletons while data resolves. */\n @Prop() isLoading: boolean = false;\n\n /** Message shown in place of the score when its figure cannot be resolved. */\n @Prop() scoreErrorMessage: string | undefined;\n\n /** Accessible name for the region. */\n @Prop() overviewLabel: string = 'Overview';\n\n /**\n * Page-controlled visual collapse from the full card (`0`) toward its 48px\n * compact handoff height (`1`). The component preserves its expanded flow\n * height, keeps elevation on the shrinking surface, and clips translated\n * content internally. The page still owns sticky positioning and the final\n * swap to `variant=\"compact\"`.\n */\n @Prop() scrollCollapseProgress: number = 0;\n\n /** Emitted when a metric that is not inactive is activated. */\n @Event() dsMetricSelect!: EventEmitter<OverviewMetric>;\n\n /** Roving tab stop across selectable metrics. */\n @State() private focusedMetricIndex: number = 0;\n @State() private expandedHeight: number = 0;\n\n private layoutEl?: HTMLElement;\n private layoutResizeObserver: ResizeObserver | null = null;\n\n componentDidLoad() {\n this.observeLayout();\n }\n\n componentDidRender() {\n // Re-bind after HMR when DidLoad's observer was dropped.\n if (!this.layoutResizeObserver) this.observeLayout();\n }\n\n disconnectedCallback() {\n this.layoutResizeObserver?.disconnect();\n this.layoutResizeObserver = null;\n }\n\n private get hasScore(): boolean {\n return this.score !== undefined || this.scoreErrorMessage !== undefined || this.isLoading;\n }\n\n private get visibleMetrics(): OverviewMetric[] {\n return this.metrics.slice(0, MAX_METRIC_COUNT);\n }\n\n private get resolvedScrollCollapseProgress(): number {\n if (this.variant === 'compact' || !Number.isFinite(this.scrollCollapseProgress)) return 0;\n return Math.min(1, Math.max(0, this.scrollCollapseProgress));\n }\n\n private get scrollCollapseGeometry() {\n const compactHeight = resolveCssLengthPx(TOKEN_DEFAULTS.size600, 48);\n return resolveCardOverviewCollapseGeometry({\n variant: this.variant,\n progress: this.resolvedScrollCollapseProgress,\n expandedHeight: this.expandedHeight,\n compactHeight,\n });\n }\n\n private observeLayout() {\n const layout = this.layoutEl;\n if (!layout) return;\n\n const updateHeight = (height: number) => {\n if (height > 0 && Math.abs(height - this.expandedHeight) >= 0.5) {\n this.expandedHeight = height;\n }\n };\n\n updateHeight(layout.getBoundingClientRect().height);\n if (typeof ResizeObserver === 'undefined') return;\n\n this.layoutResizeObserver?.disconnect();\n this.layoutResizeObserver = new ResizeObserver(entries => {\n const height = entries[0]?.contentRect.height;\n if (height !== undefined) updateHeight(height);\n });\n this.layoutResizeObserver.observe(layout);\n }\n\n /** Index of the roving tab stop, skipping inactive metrics. */\n private get rovingIndex(): number {\n return resolveOverviewRovingIndex(this.visibleMetrics, this.focusedMetricIndex);\n }\n\n private selectMetric(metric: OverviewMetric, index: number) {\n if (metric.isInactive) return;\n this.focusedMetricIndex = index;\n this.dsMetricSelect.emit(metric);\n }\n\n /** Move the roving tab stop, wrapping and skipping inactive metrics. */\n private moveFocus(from: number, step: number) {\n const metrics = this.visibleMetrics;\n const next = findNextOverviewMetricIndex(metrics, from, step < 0 ? -1 : 1);\n if (next < 0) return;\n\n this.focusedMetricIndex = next;\n const cells = this.el.querySelectorAll<HTMLElement>('.card-overview__metric');\n cells[next]?.focus();\n }\n\n private handleMetricKeyDown = (event: KeyboardEvent, index: number) => {\n switch (event.key) {\n case 'ArrowRight':\n case 'ArrowDown':\n event.preventDefault();\n this.moveFocus(index, 1);\n break;\n case 'ArrowLeft':\n case 'ArrowUp':\n event.preventDefault();\n this.moveFocus(index, -1);\n break;\n default:\n break;\n }\n };\n\n /**\n * A skeleton bar matching the type metrics of the text it stands in for, so the\n * loading state holds the same shape and rhythm as the resolved content.\n *\n * `background` is always passed so the base and shimmer follow the card's\n * permanently dark surface in both themes.\n */\n private bar(textVariant: TextVariant, width: string, className?: string) {\n return (\n <ds-skeleton\n class={className}\n variant=\"text\"\n textVariant={textVariant}\n width={width}\n background=\"always-dark\"\n />\n );\n }\n\n /**\n * Arrow and change in one text node.\n *\n * The arrow is a typeface glyph rather than an icon so it inherits the exact\n * size, weight, and baseline of the value beside it; an icon would need its\n * own size scale and would drift whenever the type scale changed.\n *\n * Tone is supplied by the caller and never inferred here.\n */\n private renderTrend(trend: MetricTrend | undefined, variant: TextVariant, emphasis = false) {\n if (!trend) return null;\n return (\n <ds-text\n as=\"span\"\n class={{\n 'card-overview__trend': true,\n [`card-overview__trend--${trend.tone}`]: true,\n }}\n variant={variant}\n emphasis={emphasis}\n color={TREND_COLORS[trend.tone]}\n fontFeature=\"tabular-nums\"\n >\n {trend.direction === 'up' ? '↑' : '↓'} {trend.value}\n </ds-text>\n );\n }\n\n private renderScore(compact: boolean) {\n if (this.isLoading) {\n if (compact) {\n return (\n <div class=\"card-overview__score ds-control--md\" part=\"score\">\n {this.bar('text-body-medium', '40px', 'card-overview__score-label')}\n <div class=\"card-overview__score-figure\">\n {this.bar('text-body-medium', '24px')}\n {this.bar('text-body-medium', '32px')}\n </div>\n </div>\n );\n }\n\n return (\n <div class=\"card-overview__score ds-control--md\" part=\"score\">\n {/*\n * The label row is kept but left empty. It carries the control-height\n * box that aligns the score block with the period control, so dropping\n * it would shift the whole block up; a bar inside it would collide with\n * the figure, which sits under the label by design.\n */}\n <div class=\"card-overview__score-label-row\" />\n <div class=\"card-overview__score-figure\">\n {this.bar('text-display-medium', '56px')}\n {this.bar('text-body-small', '24px', 'card-overview__skeleton-baseline')}\n </div>\n {/*\n * Class goes on the skeleton itself, matching the resolved band. In a\n * wrapper the bar picks up inline leading and drops below the resolved\n * band position.\n */}\n {this.bar(\n 'text-caption',\n '80px',\n 'card-overview__score-band card-overview__score-band--loading'\n )}\n </div>\n );\n }\n\n if (this.scoreErrorMessage) {\n return (\n <div class=\"card-overview__score card-overview__score--error\" part=\"score\" role=\"alert\">\n <ds-icon name=\"CircleExclamation\" size=\"sm\" color=\"inherit\" aria-hidden=\"true\" />\n <ds-text as=\"span\" variant=\"text-body-medium\" color=\"inherit\">\n {this.scoreErrorMessage}\n </ds-text>\n </div>\n );\n }\n\n const score = this.score;\n if (!score) return null;\n\n return (\n <div class=\"card-overview__score card-overview__score--resolved ds-control--md\" part=\"score\">\n {/* The row owns cross-layout baseline geometry and becomes display: contents in compact mode. */}\n {/* eslint-disable-next-line local/prefer-direct-ds-text */}\n <div class=\"card-overview__score-label-row\">\n <ds-text\n as=\"span\"\n class=\"card-overview__score-label\"\n variant=\"text-body-medium\"\n emphasis={!compact}\n color={ALWAYS_DARK_SECONDARY}\n >\n {score.label}\n </ds-text>\n </div>\n <div class=\"card-overview__score-figure\">\n <ds-text\n as=\"span\"\n class=\"card-overview__score-value\"\n variant={compact ? 'text-body-medium' : 'text-display-medium'}\n emphasis\n color={ALWAYS_DARK_PRIMARY}\n fontFeature=\"tabular-nums\"\n >\n {score.value}\n </ds-text>\n {this.renderTrend(\n score.trend,\n compact ? 'text-body-medium' : 'text-body-small',\n !compact\n )}\n </div>\n {score.band && !compact && (\n <ds-text\n as=\"span\"\n class=\"card-overview__score-band\"\n variant=\"text-caption\"\n color={ALWAYS_DARK_SECONDARY}\n >\n {score.band}\n </ds-text>\n )}\n </div>\n );\n }\n\n private renderMetric(metric: OverviewMetric, index: number) {\n const selectable = !metric.isInactive;\n const label = (\n <ds-text\n as=\"span\"\n class=\"card-overview__metric-label\"\n variant=\"text-body-small\"\n color={ALWAYS_DARK_SECONDARY}\n >\n {metric.label}\n </ds-text>\n );\n\n return (\n <div\n class={{\n 'card-overview__metric': true,\n 'card-overview__metric--inactive': !selectable,\n // Selection targets get the shared wash; press scaling is not used here\n // so the grid keeps its columns aligned. See docs/control-press-policy.md.\n 'ds-interaction-fill': selectable,\n 'ds-interaction-fill--on-always-dark': selectable,\n 'ds-focus-ring-inset': selectable,\n }}\n part=\"metric\"\n role={selectable ? 'button' : undefined}\n tabIndex={selectable && index === this.rovingIndex ? 0 : -1}\n onClick={() => this.selectMetric(metric, index)}\n onKeyDown={event => this.handleMetricKeyDown(event, index)}\n onFocusin={() => {\n if (selectable) this.focusedMetricIndex = index;\n }}\n >\n {metric.labelTooltip ? (\n <ds-tooltip label={metric.labelTooltip} side=\"top\" size=\"sm\">\n {label}\n </ds-tooltip>\n ) : (\n label\n )}\n <div class=\"card-overview__metric-figure\">\n <ds-text\n as=\"span\"\n class=\"card-overview__metric-value\"\n variant=\"text-body-medium\"\n color={ALWAYS_DARK_PRIMARY}\n fontFeature=\"tabular-nums\"\n >\n {metric.value}\n </ds-text>\n {this.renderTrend(metric.trend, 'text-body-medium')}\n </div>\n </div>\n );\n }\n\n private renderMetrics() {\n if (this.isLoading && this.metrics.length === 0) {\n return Array.from({ length: LOADING_PLACEHOLDER_COUNT }, (_, index) => (\n <div class=\"card-overview__metric\" key={`loading-${index}`}>\n {this.bar('text-body-small', '70%', 'card-overview__metric-label')}\n <div class=\"card-overview__metric-figure\">\n {this.bar('text-body-medium', '36px')}\n {/* text-body-medium, matching renderTrend for a metric — a smaller\n * variant here leaves the trend bar short of the value beside it. */}\n {this.bar('text-body-medium', '40px')}\n </div>\n </div>\n ));\n }\n\n return this.visibleMetrics.map((metric, index) => this.renderMetric(metric, index));\n }\n\n render() {\n const hasHeader = Boolean(this.periodLabel || this.comparisonLabel);\n const compact = this.variant === 'compact';\n const collapse = this.scrollCollapseGeometry;\n\n return (\n <Host\n class={{\n 'card-overview': true,\n 'card-overview--has-score': this.hasScore,\n 'card-overview--compact': compact,\n 'card-overview--stacked': !compact && this.layout === 'stacked',\n 'card-overview--scroll-collapsing': collapse.active,\n }}\n role=\"region\"\n aria-label={this.overviewLabel}\n aria-busy={this.isLoading ? 'true' : undefined}\n style={{\n '--ds-card-overview-metric-min': this.metricMinWidth,\n '--ds-card-overview-expanded-height': collapse.active\n ? `${collapse.expandedHeight}px`\n : undefined,\n '--ds-card-overview-visible-height': collapse.active\n ? `${collapse.visibleHeight}px`\n : undefined,\n '--ds-card-overview-content-offset': collapse.active\n ? `${collapse.offset}px`\n : undefined,\n }}\n >\n <div\n class={{\n 'card-overview__surface': true,\n // Split shadow and inset highlight, so the opaque surface cannot cover\n // the highlight the way a combined elevation shadow would.\n 'ds-control-elevation': true,\n 'ds-control-elevation--sm': !compact,\n 'ds-control-elevation--floating': compact,\n }}\n >\n <div class=\"card-overview__clip\">\n <div\n ref={element => {\n this.layoutEl = (element as HTMLElement) ?? undefined;\n }}\n class={{\n 'card-overview__layout': true,\n 'card-overview__layout--has-score': this.hasScore,\n }}\n >\n <div class=\"card-overview__summary\">\n {this.hasScore && this.renderScore(compact)}\n\n {/* `ds-control--md` supplies the 32px height and the label inset below. */}\n <div\n class={{\n 'card-overview__header': true,\n 'card-overview__header--has-score': this.hasScore,\n 'ds-control--md': true,\n }}\n >\n {this.isLoading ? (\n <div class=\"card-overview__period ds-control-label-box\">\n {this.bar('text-body-medium', '184px')}\n {this.bar('text-body-medium', '248px')}\n </div>\n ) : (\n hasHeader && (\n <div class=\"card-overview__period ds-control-label-box\">\n {this.periodLabel && (\n <ds-text\n as=\"span\"\n class=\"card-overview__period-current ds-control-label-box\"\n variant=\"text-body-medium\"\n emphasis\n color={ALWAYS_DARK_PRIMARY}\n >\n {this.periodLabel}\n </ds-text>\n )}\n {this.comparisonLabel && (\n <ds-text\n as=\"span\"\n class=\"card-overview__period-comparison ds-control-label-box\"\n variant=\"text-body-medium\"\n color={ALWAYS_DARK_SECONDARY}\n >\n {this.comparisonLabel}\n </ds-text>\n )}\n </div>\n )\n )}\n <div class=\"card-overview__filter\">\n {/*\n Period control is application owned: it varies by product surface.\n While loading it is stood in for by a control-shaped skeleton so the\n header keeps its resolved proportions.\n */}\n {this.isLoading ? (\n <ds-skeleton\n variant=\"control\"\n controlSize=\"md\"\n width=\"128px\"\n background=\"always-dark\"\n />\n ) : (\n <slot name=\"filter\" />\n )}\n </div>\n </div>\n </div>\n\n {!compact && (\n <div\n class={{\n 'card-overview__body': true,\n 'card-overview__body--has-score': this.hasScore,\n }}\n >\n <div class=\"card-overview__metrics\" part=\"metrics\">\n {this.renderMetrics()}\n </div>\n\n <slot name=\"footer\" />\n </div>\n )}\n </div>\n </div>\n </div>\n </Host>\n );\n }\n}\n"],"mappings":"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","ignoreList":[]}
1
+ {"version":3,"names":["resolveOverviewGridColumns","options","cellCount","Math","max","floor","minCellWidth","maxColumns","fittingColumns","min","availableWidth","columns","resolveCardOverviewCollapseGeometry","compactHeight","expandedHeight","progress","variant","Number","isFinite","distance","offset","active","visibleHeight","resolveSafetyScoreLevel","value","numericValue","undefined","resolveOverviewRovingIndex","metrics","focusedIndex","first","findIndex","metric","isInactive","findNextOverviewMetricIndex","from","step","length","next","cardOverviewCss","DEFAULT_METRIC_MIN_WIDTH","LOADING_PLACEHOLDER_COUNT","MAX_METRIC_COUNT","TREND_COLORS","positive","negative","neutral","ALWAYS_DARK_PRIMARY","ALWAYS_DARK_SECONDARY","CardOverview","__stencil_proxyCustomElement","HTMLElement","constructor","registerHost","this","layout","periodLabel","comparisonLabel","metricMinWidth","isLoading","overviewLabel","scrollCollapseProgress","focusedMetricIndex","layoutResizeObserver","handleMetricKeyDown","event","index","key","preventDefault","moveFocus","componentDidLoad","observeLayout","componentDidRender","updateLayoutGeometry","disconnectedCallback","disconnect","visibleMetrics","slice","visibleCellCount","metricCount","resolvedScrollCollapseProgress","scrollCollapseGeometry","resolveCssLengthPx","TOKEN_DEFAULTS","size600","layoutEl","bounds","getBoundingClientRect","width","height","ResizeObserver","entries","rect","contentRect","observe","resolvedWidth","resolvedHeight","abs","menuWidthXs","gridColumns","rovingIndex","selectMetric","dsMetricSelect","emit","cells","el","querySelectorAll","focus","bar","textVariant","className","h","class","background","renderTrend","trend","emphasis","color","as","tone","fontFeature","direction","renderScore","part","unavailableMessage","scoreErrorMessage","score","role","level","Boolean","label","renderMetric","selectable","tabIndex","onClick","onKeyDown","onFocusin","labelTooltip","side","size","renderMetrics","Array","_","map","render","compact","collapse","Host","style","String","ref","element","name","controlSize"],"sources":["src/wc/components/CardOverview/card-overview-controller.ts","src/wc/components/CardOverview/CardOverview.css?tag=ds-card-overview&encapsulation=scoped","src/wc/components/CardOverview/CardOverview.tsx"],"sourcesContent":["import type {\n CardOverviewVariant,\n OverviewMetric,\n SafetyScoreLevel,\n} from './card-overview-types';\n\nexport interface CardOverviewCollapseGeometry {\n active: boolean;\n expandedHeight: number;\n offset: number;\n visibleHeight: number;\n}\n\n/**\n * Choose the densest column count that fits without leaving an incomplete row\n * for even cell totals. Odd totals retain the densest fitting layout and may\n * therefore leave an orphan in the final row.\n */\nexport function resolveOverviewGridColumns(options: {\n cellCount: number;\n availableWidth: number;\n minCellWidth: number;\n maxColumns?: number;\n}): number {\n const cellCount = Math.max(1, Math.floor(options.cellCount));\n const minCellWidth = Math.max(1, options.minCellWidth);\n const maxColumns = Math.max(1, Math.floor(options.maxColumns ?? 4));\n const fittingColumns = Math.max(\n 1,\n Math.min(cellCount, maxColumns, Math.floor(Math.max(0, options.availableWidth) / minCellWidth))\n );\n\n if (cellCount % 2 !== 0) return fittingColumns;\n\n for (let columns = fittingColumns; columns >= 1; columns -= 1) {\n if (cellCount % columns === 0) return columns;\n }\n\n return 1;\n}\n\nexport function resolveCardOverviewCollapseGeometry(options: {\n variant: CardOverviewVariant;\n progress: number;\n expandedHeight: number;\n compactHeight: number;\n}): CardOverviewCollapseGeometry {\n const compactHeight = Math.max(0, options.compactHeight);\n const expandedHeight = Math.max(options.expandedHeight, compactHeight);\n const progress =\n options.variant === 'compact' || !Number.isFinite(options.progress)\n ? 0\n : Math.min(1, Math.max(0, options.progress));\n const distance = Math.max(0, expandedHeight - compactHeight);\n const offset = distance * progress;\n\n return {\n active: progress > 0 && distance > 0,\n expandedHeight,\n offset,\n visibleHeight: expandedHeight - offset,\n };\n}\n\nexport function resolveSafetyScoreLevel(value: string | number): SafetyScoreLevel | undefined {\n const numericValue = typeof value === 'number' ? value : Number(value);\n if (!Number.isFinite(numericValue) || numericValue < 0 || numericValue > 100) return undefined;\n if (numericValue <= 50) return 'fair';\n if (numericValue <= 80) return 'good';\n return 'excellent';\n}\n\nexport function resolveOverviewRovingIndex(\n metrics: readonly OverviewMetric[],\n focusedIndex: number\n): number {\n const first = metrics.findIndex(metric => !metric.isInactive);\n if (first < 0) return -1;\n return metrics[focusedIndex] && !metrics[focusedIndex].isInactive\n ? focusedIndex\n : first;\n}\n\nexport function findNextOverviewMetricIndex(\n metrics: readonly OverviewMetric[],\n from: number,\n step: -1 | 1\n): number {\n for (let offset = 1; offset <= metrics.length; offset += 1) {\n const next = (((from + step * offset) % metrics.length) + metrics.length) % metrics.length;\n if (!metrics[next]?.isInactive) return next;\n }\n return -1;\n}\n","@import '../../utils/interaction-fill.css';\n@import '../../utils/focus-ring.css';\n@import '../../utils/control-density.css';\n@import '../../utils/control-parts.css';\n@import '../../styles/control-elevation.css';\n\n:host {\n display: block;\n box-sizing: border-box;\n container-type: inline-size;\n -webkit-user-select: none;\n user-select: none;\n --ds-card-overview-metric-min: calc(var(--dimension-size-400) * 5);\n --ds-card-overview-divider-width: var(--dimension-stroke-width-012);\n --ds-card-overview-divider-color: var(--color-always-dark-border-tertiary);\n color: var(--color-always-dark-foreground-primary);\n}\n\n.card-overview__surface {\n width: 100%;\n min-width: 0;\n box-sizing: border-box;\n border-radius: var(--dimension-radius-125);\n background: var(--color-always-dark-background);\n color: var(--color-always-dark-foreground-primary);\n overflow-anchor: none;\n}\n\n.card-overview__clip {\n height: 100%;\n min-width: 0;\n border-radius: inherit;\n background: inherit;\n overflow: hidden;\n}\n\n:host(.card-overview--scroll-collapsing) {\n height: var(--ds-card-overview-expanded-height);\n pointer-events: none;\n}\n\n:host(.card-overview--scroll-collapsing) .card-overview__surface {\n height: var(--ds-card-overview-visible-height);\n pointer-events: auto;\n will-change: height;\n}\n\n:host(.card-overview--scroll-collapsing) .card-overview__body {\n transform: translateY(calc(-1 * var(--ds-card-overview-content-offset)));\n will-change: transform;\n}\n\n.card-overview__layout {\n display: flex;\n flex-direction: column;\n min-width: 0;\n}\n\n.card-overview__summary {\n position: relative;\n z-index: 1;\n flex: 0 0 auto;\n min-width: 0;\n background: var(--color-always-dark-background);\n}\n\n.card-overview__header {\n display: flex;\n position: relative;\n align-items: center;\n gap: 0;\n width: 100%;\n height: var(--dimension-size-600);\n min-width: 0;\n padding: var(--dimension-space-100);\n box-sizing: border-box;\n}\n\n.card-overview__header::after {\n content: '';\n position: absolute;\n inset-inline: 0;\n inset-block-end: 0;\n height: var(--ds-card-overview-divider-width);\n background: var(--ds-card-overview-divider-color);\n pointer-events: none;\n}\n\n.card-overview__period {\n display: flex;\n flex: 0 1 auto;\n align-items: center;\n gap: 0;\n min-width: 0;\n min-height: var(--ds-control-height);\n overflow: hidden;\n white-space: nowrap;\n}\n\n.card-overview__period-current,\n.card-overview__period-comparison {\n min-width: 0;\n overflow: hidden;\n text-overflow: ellipsis;\n}\n\n.card-overview__period-current {\n display: flex;\n flex: 0 1 auto;\n align-items: center;\n}\n\n.card-overview__period-fixed {\n flex: 0 1 auto;\n min-width: 0;\n}\n\n.card-overview__period-comparison {\n flex: 0 0 auto;\n}\n\n.card-overview__filter {\n display: flex;\n flex: 0 1 auto;\n align-items: center;\n min-width: 0;\n}\n\n.card-overview__body {\n display: flex;\n position: relative;\n z-index: 0;\n flex-direction: column;\n min-width: 0;\n transform: translateY(0);\n}\n\n.card-overview__metrics {\n display: grid;\n flex: 1 1 auto;\n grid-template-columns: repeat(\n var(--ds-card-overview-grid-columns, auto-fit),\n minmax(min(100%, var(--ds-card-overview-metric-min)), 1fr)\n );\n align-content: stretch;\n min-width: 0;\n overflow: clip;\n}\n\n.card-overview__score,\n.card-overview__metric {\n display: flex;\n min-width: 0;\n padding: var(--dimension-space-100);\n box-shadow:\n var(--ds-card-overview-divider-width) 0 0 0 var(--ds-card-overview-divider-color),\n 0 var(--ds-card-overview-divider-width) 0 0 var(--ds-card-overview-divider-color);\n box-sizing: border-box;\n}\n\n.card-overview__score-content,\n.card-overview__metric-action {\n display: flex;\n flex: 1 1 auto;\n min-width: 0;\n padding: var(--dimension-space-075);\n border-radius: var(--dimension-radius-025);\n box-sizing: border-box;\n}\n\n.card-overview__score-content {\n align-items: center;\n justify-content: space-between;\n gap: var(--dimension-space-100);\n background: var(--color-always-dark-interaction-active);\n color: var(--color-always-dark-foreground-primary);\n}\n\n.card-overview__score-content--fair {\n background: var(--color-safety-score-background-fair);\n color: var(--color-safety-score-foreground-on-fair);\n}\n\n.card-overview__score-content--good {\n background: var(--color-safety-score-background-good);\n color: var(--color-safety-score-foreground-on-good);\n}\n\n.card-overview__score-content--excellent {\n background: var(--color-safety-score-background-excellent);\n color: var(--color-safety-score-foreground-on-excellent);\n}\n\n.card-overview__score-copy {\n display: flex;\n flex: 1 1 auto;\n flex-direction: column;\n align-items: flex-start;\n gap: var(--dimension-space-025);\n min-width: 0;\n}\n\n.card-overview__score-value,\n.card-overview__score-figure {\n flex: 0 0 auto;\n margin-block: calc(-1 * var(--dimension-space-150));\n}\n\n.card-overview__score-content--error {\n align-items: center;\n justify-content: center;\n border: var(--ds-card-overview-divider-width) solid\n var(--color-always-dark-border-tertiary);\n background: transparent;\n color: var(--color-always-dark-foreground-negative);\n text-align: center;\n}\n\n.card-overview__metric-action {\n flex-direction: column;\n justify-content: center;\n gap: var(--dimension-space-050);\n}\n\n.card-overview__metric-action[role='button'] {\n cursor: default;\n}\n\n.card-overview__metric-content {\n display: flex;\n flex-direction: column;\n justify-content: center;\n gap: var(--dimension-space-050);\n min-width: 0;\n}\n\n.card-overview__metric-label {\n min-width: 0;\n}\n\n.card-overview__metric-figure {\n display: flex;\n align-items: baseline;\n gap: var(--dimension-space-100);\n min-width: 0;\n}\n\n.card-overview__trend {\n flex: 0 0 auto;\n white-space: nowrap;\n}\n\n:host(.card-overview--stacked) .card-overview__metrics {\n grid-template-columns: minmax(0, 1fr);\n}\n\n:host(.card-overview--compact) {\n height: var(--dimension-size-600);\n min-height: var(--dimension-size-600);\n}\n\n:host(.card-overview--compact) .card-overview__surface,\n:host(.card-overview--compact) .card-overview__clip,\n:host(.card-overview--compact) .card-overview__layout,\n:host(.card-overview--compact) .card-overview__summary {\n width: 100%;\n height: 100%;\n}\n\n:host(.card-overview--compact) .card-overview__header::after {\n display: none;\n}\n\n@media (forced-colors: active) {\n .card-overview__header::after {\n background: var(--ds-forced-color-content);\n }\n\n .card-overview__score-content {\n border: var(--dimension-stroke-width-012) solid var(--ds-forced-color-content);\n background: var(--ds-forced-color-surface);\n color: var(--ds-forced-color-content);\n }\n}\n","import { Component, Element, Event, EventEmitter, h, Host, Prop, State } from '@stencil/core';\nimport { resolveCssLengthPx, TOKEN_DEFAULTS } from '../../utils';\nimport type { TextColor, TextVariant } from '../Text/text-types';\nimport type { MetricTrend } from '../../utils/metric-change';\nimport type {\n CardOverviewLayout,\n CardOverviewVariant,\n OverviewMetric,\n OverviewScore,\n} from './card-overview-types';\nimport {\n findNextOverviewMetricIndex,\n resolveCardOverviewCollapseGeometry,\n resolveOverviewGridColumns,\n resolveOverviewRovingIndex,\n resolveSafetyScoreLevel,\n} from './card-overview-controller';\n\n/** Metric cells below this width drop a grid column rather than compress further. */\nconst DEFAULT_METRIC_MIN_WIDTH = 'var(--dimension-menu-width-xs)';\n\n/** Skeleton cells rendered while loading with no metrics supplied yet. */\nconst LOADING_PLACEHOLDER_COUNT = 4;\n\n/** Maximum number of comparable measures the summary bar presents at once. */\nconst MAX_METRIC_COUNT = 7;\n\nconst TREND_COLORS: Record<MetricTrend['tone'], TextColor> = {\n positive: 'var(--color-always-dark-foreground-positive)',\n negative: 'var(--color-always-dark-foreground-negative)',\n neutral: 'var(--color-always-dark-foreground-secondary)',\n};\n\nconst ALWAYS_DARK_PRIMARY: TextColor = 'var(--color-always-dark-foreground-primary)';\nconst ALWAYS_DARK_SECONDARY: TextColor = 'var(--color-always-dark-foreground-secondary)';\n\n@Component({\n tag: 'ds-card-overview',\n styleUrl: 'CardOverview.css',\n scoped: true,\n})\nexport class CardOverview {\n @Element() el!: HTMLElement;\n\n /** Full summary card, or the condensed 48px summary bar. */\n @Prop() variant: CardOverviewVariant = 'default';\n\n /** Intrinsic responsive layout, or a page-owned single-column stack. */\n @Prop() layout: CardOverviewLayout = 'auto';\n\n /** Optional nonselectable safety score rendered as the first grid cell. */\n @Prop() score: OverviewScore | undefined;\n\n /** Fixed current date or range. Replaced by content in the `period` slot. */\n @Prop() periodLabel: string = '';\n\n /** Copy between the current period and comparison control, usually `vs.`. */\n @Prop() comparisonLabel: string = '';\n\n /** Measures rendered in the responsive grid. Only the first seven are shown. */\n @Prop() metrics: OverviewMetric[] = [];\n\n /**\n * Width a metric cell may shrink to before the grid drops a column. The grid\n * uses this threshold while choosing an evenly distributed column count.\n */\n @Prop() metricMinWidth: string = DEFAULT_METRIC_MIN_WIDTH;\n\n /** Replace the score and metrics with skeletons while data resolves. */\n @Prop() isLoading: boolean = false;\n\n /** Message shown in place of the score when its figure cannot be resolved. */\n @Prop() scoreErrorMessage: string | undefined;\n\n /** Accessible name for the region. */\n @Prop() overviewLabel: string = 'Overview';\n\n /**\n * Page-controlled visual collapse from the full card (`0`) toward its 48px\n * compact handoff height (`1`). The component preserves its expanded flow\n * height, keeps the period bar stationary, and moves/clips the grid beneath\n * it. The page still owns sticky positioning and the final compact handoff.\n */\n @Prop() scrollCollapseProgress: number = 0;\n\n /** Emitted when a metric that is not inactive is activated. */\n @Event() dsMetricSelect!: EventEmitter<OverviewMetric>;\n\n /** Roving tab stop across selectable metrics. */\n @State() private focusedMetricIndex: number = 0;\n @State() private expandedHeight: number = 0;\n @State() private gridColumns: number | undefined;\n\n private layoutEl?: HTMLElement;\n private layoutResizeObserver: ResizeObserver | null = null;\n\n componentDidLoad() {\n this.observeLayout();\n }\n\n componentDidRender() {\n // Re-bind after HMR when DidLoad's observer was dropped.\n if (!this.layoutResizeObserver) this.observeLayout();\n else this.updateLayoutGeometry();\n }\n\n disconnectedCallback() {\n this.layoutResizeObserver?.disconnect();\n this.layoutResizeObserver = null;\n }\n\n private get visibleMetrics(): OverviewMetric[] {\n return this.metrics.slice(0, MAX_METRIC_COUNT);\n }\n\n private get visibleCellCount(): number {\n const metricCount =\n this.isLoading && this.metrics.length === 0\n ? LOADING_PLACEHOLDER_COUNT\n : this.visibleMetrics.length;\n return 1 + metricCount;\n }\n\n private get resolvedScrollCollapseProgress(): number {\n if (this.variant === 'compact' || !Number.isFinite(this.scrollCollapseProgress)) return 0;\n return Math.min(1, Math.max(0, this.scrollCollapseProgress));\n }\n\n private get scrollCollapseGeometry() {\n const compactHeight = resolveCssLengthPx(TOKEN_DEFAULTS.size600, 48);\n return resolveCardOverviewCollapseGeometry({\n variant: this.variant,\n progress: this.resolvedScrollCollapseProgress,\n expandedHeight: this.expandedHeight,\n compactHeight,\n });\n }\n\n private observeLayout() {\n const layout = this.layoutEl;\n if (!layout) return;\n\n const bounds = layout.getBoundingClientRect();\n this.updateLayoutGeometry(bounds.width, bounds.height);\n if (typeof ResizeObserver === 'undefined') return;\n\n this.layoutResizeObserver?.disconnect();\n this.layoutResizeObserver = new ResizeObserver(entries => {\n const rect = entries[0]?.contentRect;\n if (rect) this.updateLayoutGeometry(rect.width, rect.height);\n });\n this.layoutResizeObserver.observe(layout);\n }\n\n private updateLayoutGeometry(width?: number, height?: number) {\n const layout = this.layoutEl;\n if (!layout) return;\n\n const bounds = width === undefined || height === undefined ? layout.getBoundingClientRect() : null;\n const resolvedWidth = width ?? bounds?.width ?? 0;\n const resolvedHeight = height ?? bounds?.height ?? 0;\n\n if (resolvedHeight > 0 && Math.abs(resolvedHeight - this.expandedHeight) >= 0.5) {\n this.expandedHeight = resolvedHeight;\n }\n\n const columns = resolveOverviewGridColumns({\n cellCount: this.visibleCellCount,\n availableWidth: resolvedWidth,\n minCellWidth: resolveCssLengthPx(this.metricMinWidth, TOKEN_DEFAULTS.menuWidthXs),\n });\n if (columns !== this.gridColumns) this.gridColumns = columns;\n }\n\n /** Index of the roving tab stop, skipping inactive metrics. */\n private get rovingIndex(): number {\n return resolveOverviewRovingIndex(this.visibleMetrics, this.focusedMetricIndex);\n }\n\n private selectMetric(metric: OverviewMetric, index: number) {\n if (metric.isInactive) return;\n this.focusedMetricIndex = index;\n this.dsMetricSelect.emit(metric);\n }\n\n /** Move the roving tab stop, wrapping and skipping inactive metrics. */\n private moveFocus(from: number, step: number) {\n const metrics = this.visibleMetrics;\n const next = findNextOverviewMetricIndex(metrics, from, step < 0 ? -1 : 1);\n if (next < 0) return;\n\n this.focusedMetricIndex = next;\n const cells = this.el.querySelectorAll<HTMLElement>('.card-overview__metric-action');\n cells[next]?.focus();\n }\n\n private handleMetricKeyDown = (event: KeyboardEvent, index: number) => {\n switch (event.key) {\n case 'ArrowRight':\n case 'ArrowDown':\n event.preventDefault();\n this.moveFocus(index, 1);\n break;\n case 'ArrowLeft':\n case 'ArrowUp':\n event.preventDefault();\n this.moveFocus(index, -1);\n break;\n default:\n break;\n }\n };\n\n /**\n * A skeleton bar matching the type metrics of the text it stands in for, so the\n * loading state holds the same shape and rhythm as the resolved content.\n *\n * `background` is always passed so the base and shimmer follow the card's\n * permanently dark surface in both themes.\n */\n private bar(textVariant: TextVariant, width: string, className?: string) {\n return (\n <ds-skeleton\n class={className}\n variant=\"text\"\n textVariant={textVariant}\n width={width}\n background=\"always-dark\"\n />\n );\n }\n\n /**\n * Arrow and change in one text node.\n *\n * The arrow is a typeface glyph rather than an icon so it inherits the exact\n * size, weight, and baseline of the value beside it; an icon would need its\n * own size scale and would drift whenever the type scale changed.\n *\n * Tone is supplied by the caller and never inferred here.\n */\n private renderTrend(\n trend: MetricTrend | undefined,\n variant: TextVariant,\n emphasis = false,\n color?: TextColor\n ) {\n if (!trend) return null;\n return (\n <ds-text\n as=\"span\"\n class={{\n 'card-overview__trend': true,\n 'ds-control-label-box': true,\n [`card-overview__trend--${trend.tone}`]: true,\n }}\n variant={variant}\n emphasis={emphasis}\n color={color ?? TREND_COLORS[trend.tone]}\n fontFeature=\"tabular-nums\"\n >\n {trend.direction === 'up' ? '↑' : '↓'} {trend.value}\n </ds-text>\n );\n }\n\n private renderScore() {\n if (this.isLoading) {\n return (\n <div class=\"card-overview__score\" part=\"score\">\n <div class=\"card-overview__score-content\">\n <div class=\"card-overview__score-copy\">\n {this.bar('text-body-small', '64px', 'card-overview__score-label')}\n {this.bar('text-body-medium', '28px')}\n </div>\n <div class=\"card-overview__score-figure\">\n {this.bar('text-display-medium', '56px')}\n </div>\n </div>\n </div>\n );\n }\n\n const unavailableMessage =\n this.scoreErrorMessage || (!this.score ? 'Score unavailable' : undefined);\n if (unavailableMessage) {\n return (\n /* eslint-disable-next-line local/prefer-direct-ds-text -- The score track owns the grid divider and 8px outer inset. */\n <div class=\"card-overview__score\" part=\"score\">\n <ds-text\n as=\"span\"\n class=\"card-overview__score-content card-overview__score-content--error\"\n variant=\"text-body-medium\"\n color=\"inherit\"\n role=\"alert\"\n >\n {unavailableMessage}\n </ds-text>\n </div>\n );\n }\n\n const score = this.score;\n if (!score) return null;\n const level = score.level ?? resolveSafetyScoreLevel(score.value);\n\n return (\n <div class=\"card-overview__score\" part=\"score\">\n <div\n class={{\n 'card-overview__score-content': true,\n [`card-overview__score-content--${level}`]: Boolean(level),\n }}\n >\n <div class=\"card-overview__score-copy\">\n <ds-text\n as=\"span\"\n class=\"card-overview__score-label ds-control-label-box\"\n variant=\"text-body-small\"\n color=\"inherit\"\n >\n {score.label}\n </ds-text>\n {this.renderTrend(score.trend, 'text-body-medium', false, 'inherit')}\n </div>\n <ds-text\n as=\"span\"\n class=\"card-overview__score-value ds-control-label-box\"\n variant=\"text-display-medium\"\n emphasis\n color=\"inherit\"\n fontFeature=\"tabular-nums\"\n >\n {score.value}\n </ds-text>\n </div>\n </div>\n );\n }\n\n private renderMetric(metric: OverviewMetric, index: number) {\n const selectable = !metric.isInactive;\n const label = (\n <ds-text\n as=\"span\"\n class=\"card-overview__metric-label ds-control-label-box\"\n variant=\"text-body-small\"\n color={ALWAYS_DARK_SECONDARY}\n >\n {metric.label}\n </ds-text>\n );\n\n return (\n <div class=\"card-overview__metric\" part=\"metric\">\n <div\n class={{\n 'card-overview__metric-action': true,\n 'card-overview__metric-action--inactive': !selectable,\n // Selection targets get the shared wash; press scaling is not used here\n // so the grid keeps its columns aligned. See docs/control-press-policy.md.\n 'ds-interaction-fill': selectable,\n 'ds-interaction-fill--on-always-dark': selectable,\n 'ds-focus-ring-inset': selectable,\n }}\n role={selectable ? 'button' : undefined}\n tabIndex={selectable && index === this.rovingIndex ? 0 : -1}\n onClick={() => this.selectMetric(metric, index)}\n onKeyDown={event => this.handleMetricKeyDown(event, index)}\n onFocusin={() => {\n if (selectable) this.focusedMetricIndex = index;\n }}\n >\n <div class=\"ds-interaction-fill__content card-overview__metric-content\">\n {metric.labelTooltip ? (\n <ds-tooltip label={metric.labelTooltip} side=\"top\" size=\"sm\">\n {label}\n </ds-tooltip>\n ) : (\n label\n )}\n <div class=\"card-overview__metric-figure\">\n <ds-text\n as=\"span\"\n class=\"card-overview__metric-value ds-control-label-box\"\n variant=\"text-body-medium\"\n color={ALWAYS_DARK_PRIMARY}\n fontFeature=\"tabular-nums\"\n >\n {metric.value}\n </ds-text>\n {this.renderTrend(metric.trend, 'text-body-medium')}\n </div>\n </div>\n </div>\n </div>\n );\n }\n\n private renderMetrics() {\n if (this.isLoading && this.metrics.length === 0) {\n return [\n this.renderScore(),\n ...Array.from({ length: LOADING_PLACEHOLDER_COUNT }, (_, index) => (\n <div class=\"card-overview__metric\" key={`loading-${index}`}>\n <div class=\"card-overview__metric-action card-overview__metric-action--inactive\">\n {this.bar('text-body-small', '70%', 'card-overview__metric-label')}\n <div class=\"card-overview__metric-figure\">\n {this.bar('text-body-medium', '36px')}\n {/* text-body-medium, matching renderTrend for a metric — a smaller\n * variant here leaves the trend bar short of the value beside it. */}\n {this.bar('text-body-medium', '40px')}\n </div>\n </div>\n </div>\n )),\n ];\n }\n\n return [\n this.renderScore(),\n ...this.visibleMetrics.map((metric, index) => this.renderMetric(metric, index)),\n ];\n }\n\n render() {\n const compact = this.variant === 'compact';\n const collapse = this.scrollCollapseGeometry;\n\n return (\n <Host\n class={{\n 'card-overview': true,\n 'card-overview--compact': compact,\n 'card-overview--stacked': !compact && this.layout === 'stacked',\n 'card-overview--scroll-collapsing': collapse.active,\n }}\n role=\"region\"\n aria-label={this.overviewLabel}\n aria-busy={this.isLoading ? 'true' : undefined}\n style={{\n '--ds-card-overview-metric-min': this.metricMinWidth,\n '--ds-card-overview-grid-columns': this.gridColumns\n ? String(this.gridColumns)\n : undefined,\n '--ds-card-overview-expanded-height': collapse.active\n ? `${collapse.expandedHeight}px`\n : undefined,\n '--ds-card-overview-visible-height': collapse.active\n ? `${collapse.visibleHeight}px`\n : undefined,\n '--ds-card-overview-content-offset': collapse.active\n ? `${collapse.offset}px`\n : undefined,\n }}\n >\n <div\n class={{\n 'card-overview__surface': true,\n // Split shadow and inset highlight, so the opaque surface cannot cover\n // the highlight the way a combined elevation shadow would.\n 'ds-control-elevation': true,\n 'ds-control-elevation--sm': !compact,\n 'ds-control-elevation--floating': compact,\n }}\n >\n <div class=\"card-overview__clip\">\n <div\n ref={element => {\n this.layoutEl = (element as HTMLElement) ?? undefined;\n }}\n class={{\n 'card-overview__layout': true,\n }}\n >\n <div class=\"card-overview__summary\">\n <div class=\"card-overview__header ds-control--md\">\n {this.isLoading ? (\n <div class=\"card-overview__period\">\n {this.bar('text-body-medium', '184px')}\n {this.bar('text-body-medium', '248px')}\n </div>\n ) : (\n <div class=\"card-overview__period\">\n <div class=\"card-overview__period-current\">\n <slot name=\"period\">\n {this.periodLabel && (\n /* eslint-disable-next-line local/prefer-direct-ds-text -- Fixed copy uses the same structural frame and label inset as a slotted Select. */\n <div class=\"card-overview__period-fixed ds-control-frame\">\n <ds-text\n as=\"span\"\n class=\"ds-control-label-box\"\n variant=\"text-body-medium\"\n emphasis\n color={ALWAYS_DARK_PRIMARY}\n >\n {this.periodLabel}\n </ds-text>\n </div>\n )}\n </slot>\n </div>\n {this.comparisonLabel && (\n <ds-text\n as=\"span\"\n class=\"card-overview__period-comparison ds-control-label-box\"\n variant=\"text-body-medium\"\n color={ALWAYS_DARK_SECONDARY}\n >\n {this.comparisonLabel}\n </ds-text>\n )}\n </div>\n )}\n <div class=\"card-overview__filter\">\n {/*\n Period control is application owned: it varies by product surface.\n While loading it is stood in for by a control-shaped skeleton so the\n header keeps its resolved proportions.\n */}\n {this.isLoading ? (\n <ds-skeleton\n variant=\"control\"\n controlSize=\"md\"\n width=\"128px\"\n background=\"always-dark\"\n />\n ) : (\n <slot name=\"filter\" />\n )}\n </div>\n </div>\n </div>\n\n {!compact && (\n <div class=\"card-overview__body\">\n <div class=\"card-overview__metrics\" part=\"metrics\">\n {this.renderMetrics()}\n </div>\n\n <slot name=\"footer\" />\n </div>\n )}\n </div>\n </div>\n </div>\n </Host>\n );\n }\n}\n"],"mappings":"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","ignoreList":[]}