@nldd/design-system 0.8.96 → 0.8.97

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 (177) hide show
  1. package/README.md +14 -10
  2. package/custom-elements.json +494 -92
  3. package/dist/components/components.js +609 -177
  4. package/dist/components/content/icon/icon-aliases.js +1 -1
  5. package/dist/components/content/icon/icon-aliases.js.map +1 -1
  6. package/dist/components/content/icon/icon-gallery-status.d.ts.map +1 -1
  7. package/dist/components/content/icon/icon-gallery-status.js +15 -4
  8. package/dist/components/content/icon/icon-gallery-status.js.map +1 -1
  9. package/dist/components/content/icon/icon-registry.js +12 -12
  10. package/dist/components/content/icon/icon-registry.js.map +1 -1
  11. package/dist/components/content/image/image.d.ts +19 -3
  12. package/dist/components/content/image/image.d.ts.map +1 -1
  13. package/dist/components/content/image/image.js +25 -4
  14. package/dist/components/content/image/image.js.map +1 -1
  15. package/dist/components/content/image/image.styles.d.ts.map +1 -1
  16. package/dist/components/content/image/image.styles.js +36 -0
  17. package/dist/components/content/image/image.styles.js.map +1 -1
  18. package/dist/components/content/image/image.template.d.ts.map +1 -1
  19. package/dist/components/content/image/image.template.js +13 -1
  20. package/dist/components/content/image/image.template.js.map +1 -1
  21. package/dist/components/content/rich-text/rich-text.d.ts +25 -12
  22. package/dist/components/content/rich-text/rich-text.d.ts.map +1 -1
  23. package/dist/components/content/rich-text/rich-text.js +25 -12
  24. package/dist/components/content/rich-text/rich-text.js.map +1 -1
  25. package/dist/components/{icon-DQHT2C7z.js → icon-D_ZGezHx.js} +13 -13
  26. package/dist/components/{icon-button-mevRsl4C.js → icon-button-NN0SrgS3.js} +1 -1
  27. package/dist/components/index.d.ts +1 -1
  28. package/dist/components/index.d.ts.map +1 -1
  29. package/dist/components/index.js +1 -1
  30. package/dist/components/index.js.map +1 -1
  31. package/dist/components/layout/box/box.d.ts +1 -1
  32. package/dist/components/layout/box/box.js +1 -1
  33. package/dist/components/layout/container/container.d.ts.map +1 -1
  34. package/dist/components/layout/container/container.js +2 -1
  35. package/dist/components/layout/container/container.js.map +1 -1
  36. package/dist/components/layout/page/page.d.ts +9 -3
  37. package/dist/components/layout/page/page.d.ts.map +1 -1
  38. package/dist/components/layout/page/page.js +36 -13
  39. package/dist/components/layout/page/page.js.map +1 -1
  40. package/dist/components/layout/page/page.styles.js +1 -1
  41. package/dist/components/layout/page-sections/full-bleed-section/full-bleed-section.d.ts +2 -0
  42. package/dist/components/layout/page-sections/full-bleed-section/full-bleed-section.d.ts.map +1 -1
  43. package/dist/components/layout/page-sections/full-bleed-section/full-bleed-section.js +3 -1
  44. package/dist/components/layout/page-sections/full-bleed-section/full-bleed-section.js.map +1 -1
  45. package/dist/components/layout/page-sections/full-bleed-section/full-bleed-section.styles.d.ts.map +1 -1
  46. package/dist/components/layout/page-sections/full-bleed-section/full-bleed-section.styles.js +5 -0
  47. package/dist/components/layout/page-sections/full-bleed-section/full-bleed-section.styles.js.map +1 -1
  48. package/dist/components/layout/page-sections/hero/hero.d.ts +57 -11
  49. package/dist/components/layout/page-sections/hero/hero.d.ts.map +1 -1
  50. package/dist/components/layout/page-sections/hero/hero.js +158 -15
  51. package/dist/components/layout/page-sections/hero/hero.js.map +1 -1
  52. package/dist/components/layout/page-sections/hero/hero.styles.d.ts.map +1 -1
  53. package/dist/components/layout/page-sections/hero/hero.styles.js +95 -41
  54. package/dist/components/layout/page-sections/hero/hero.styles.js.map +1 -1
  55. package/dist/components/layout/page-sections/one-half-one-half-section/one-half-one-half-section.d.ts +4 -0
  56. package/dist/components/layout/page-sections/one-half-one-half-section/one-half-one-half-section.d.ts.map +1 -1
  57. package/dist/components/layout/page-sections/one-half-one-half-section/one-half-one-half-section.js +8 -1
  58. package/dist/components/layout/page-sections/one-half-one-half-section/one-half-one-half-section.js.map +1 -1
  59. package/dist/components/layout/page-sections/one-half-one-half-section/one-half-one-half-section.styles.d.ts.map +1 -1
  60. package/dist/components/layout/page-sections/one-half-one-half-section/one-half-one-half-section.styles.js +13 -0
  61. package/dist/components/layout/page-sections/one-half-one-half-section/one-half-one-half-section.styles.js.map +1 -1
  62. package/dist/components/layout/page-sections/one-third-two-thirds-section/one-third-two-thirds-section.d.ts +4 -0
  63. package/dist/components/layout/page-sections/one-third-two-thirds-section/one-third-two-thirds-section.d.ts.map +1 -1
  64. package/dist/components/layout/page-sections/one-third-two-thirds-section/one-third-two-thirds-section.js +8 -1
  65. package/dist/components/layout/page-sections/one-third-two-thirds-section/one-third-two-thirds-section.js.map +1 -1
  66. package/dist/components/layout/page-sections/one-third-two-thirds-section/one-third-two-thirds-section.styles.d.ts.map +1 -1
  67. package/dist/components/layout/page-sections/one-third-two-thirds-section/one-third-two-thirds-section.styles.js +17 -0
  68. package/dist/components/layout/page-sections/one-third-two-thirds-section/one-third-two-thirds-section.styles.js.map +1 -1
  69. package/dist/components/layout/page-sections/page-section-controls.d.ts +11 -1
  70. package/dist/components/layout/page-sections/page-section-controls.d.ts.map +1 -1
  71. package/dist/components/layout/page-sections/page-section-controls.js +11 -2
  72. package/dist/components/layout/page-sections/page-section-controls.js.map +1 -1
  73. package/dist/components/layout/page-sections/sidebar-section/sidebar-section.d.ts +5 -1
  74. package/dist/components/layout/page-sections/sidebar-section/sidebar-section.d.ts.map +1 -1
  75. package/dist/components/layout/page-sections/sidebar-section/sidebar-section.js +6 -2
  76. package/dist/components/layout/page-sections/sidebar-section/sidebar-section.js.map +1 -1
  77. package/dist/components/layout/page-sections/sidebar-section/sidebar-section.styles.d.ts.map +1 -1
  78. package/dist/components/layout/page-sections/sidebar-section/sidebar-section.styles.js +11 -10
  79. package/dist/components/layout/page-sections/sidebar-section/sidebar-section.styles.js.map +1 -1
  80. package/dist/components/layout/page-sections/simple-section/simple-section.d.ts +2 -0
  81. package/dist/components/layout/page-sections/simple-section/simple-section.d.ts.map +1 -1
  82. package/dist/components/layout/page-sections/simple-section/simple-section.js +3 -2
  83. package/dist/components/layout/page-sections/simple-section/simple-section.js.map +1 -1
  84. package/dist/components/layout/page-sections/simple-section/simple-section.styles.js +2 -2
  85. package/dist/components/layout/page-sections/two-thirds-one-third-section/two-thirds-one-third-section.d.ts +4 -0
  86. package/dist/components/layout/page-sections/two-thirds-one-third-section/two-thirds-one-third-section.d.ts.map +1 -1
  87. package/dist/components/layout/page-sections/two-thirds-one-third-section/two-thirds-one-third-section.js +8 -1
  88. package/dist/components/layout/page-sections/two-thirds-one-third-section/two-thirds-one-third-section.js.map +1 -1
  89. package/dist/components/layout/page-sections/two-thirds-one-third-section/two-thirds-one-third-section.styles.d.ts.map +1 -1
  90. package/dist/components/layout/page-sections/two-thirds-one-third-section/two-thirds-one-third-section.styles.js +17 -0
  91. package/dist/components/layout/page-sections/two-thirds-one-third-section/two-thirds-one-third-section.styles.js.map +1 -1
  92. package/dist/components/layout/sheet/sheet.js +1 -1
  93. package/dist/components/layout/sheet/sheet.js.map +1 -1
  94. package/dist/components/layout/{app-view/app-view.d.ts → shell/shell.d.ts} +11 -11
  95. package/dist/components/layout/shell/shell.d.ts.map +1 -0
  96. package/dist/components/layout/{app-view/app-view.js → shell/shell.js} +24 -24
  97. package/dist/components/layout/shell/shell.js.map +1 -0
  98. package/dist/components/layout/shell/shell.styles.d.ts +2 -0
  99. package/dist/components/layout/shell/shell.styles.d.ts.map +1 -0
  100. package/dist/components/layout/{app-view/app-view.styles.js → shell/shell.styles.js} +8 -8
  101. package/dist/components/layout/shell/shell.styles.js.map +1 -0
  102. package/dist/components/layout/shell/shell.template.d.ts +4 -0
  103. package/dist/components/layout/shell/shell.template.d.ts.map +1 -0
  104. package/dist/components/layout/shell/shell.template.js +9 -0
  105. package/dist/components/layout/shell/shell.template.js.map +1 -0
  106. package/dist/components/layout/split-views/bar-split-view/bar-split-view.js +1 -1
  107. package/dist/components/layout/split-views/bar-split-view/bar-split-view.js.map +1 -1
  108. package/dist/components/layout/split-views/navigation-split-view/navigation-split-view.d.ts +1 -1
  109. package/dist/components/layout/split-views/navigation-split-view/navigation-split-view.js +1 -1
  110. package/dist/components/layout/split-views/side-by-side-split-view/side-by-side-split-view.d.ts +1 -1
  111. package/dist/components/layout/split-views/side-by-side-split-view/side-by-side-split-view.js +1 -1
  112. package/dist/components/lists-and-tables/cells/text-cell/text-cell.styles.d.ts.map +1 -1
  113. package/dist/components/lists-and-tables/cells/text-cell/text-cell.styles.js +2 -0
  114. package/dist/components/lists-and-tables/cells/text-cell/text-cell.styles.js.map +1 -1
  115. package/dist/components/lists-and-tables/cells/title-cell/title-cell.styles.d.ts.map +1 -1
  116. package/dist/components/lists-and-tables/cells/title-cell/title-cell.styles.js +2 -0
  117. package/dist/components/lists-and-tables/cells/title-cell/title-cell.styles.js.map +1 -1
  118. package/dist/components/lists-and-tables/list-item/list-item.d.ts +15 -5
  119. package/dist/components/lists-and-tables/list-item/list-item.d.ts.map +1 -1
  120. package/dist/components/lists-and-tables/list-item/list-item.js +20 -7
  121. package/dist/components/lists-and-tables/list-item/list-item.js.map +1 -1
  122. package/dist/components/lists-and-tables/list-item-segment/list-item-segment.d.ts +4 -1
  123. package/dist/components/lists-and-tables/list-item-segment/list-item-segment.d.ts.map +1 -1
  124. package/dist/components/lists-and-tables/list-item-segment/list-item-segment.js +8 -2
  125. package/dist/components/lists-and-tables/list-item-segment/list-item-segment.js.map +1 -1
  126. package/dist/components/lists-and-tables/list-item-segment/list-item-segment.template.d.ts +1 -1
  127. package/dist/components/lists-and-tables/list-item-segment/list-item-segment.template.d.ts.map +1 -1
  128. package/dist/components/lists-and-tables/list-item-segment/list-item-segment.template.js +1 -1
  129. package/dist/components/lists-and-tables/list-item-segment/list-item-segment.template.js.map +1 -1
  130. package/dist/components/navigation/menu-bar-item/menu-bar-item.d.ts +5 -0
  131. package/dist/components/navigation/menu-bar-item/menu-bar-item.d.ts.map +1 -1
  132. package/dist/components/navigation/menu-bar-item/menu-bar-item.js +13 -1
  133. package/dist/components/navigation/menu-bar-item/menu-bar-item.js.map +1 -1
  134. package/dist/components/navigation/menu-bar-item/menu-bar-item.styles.d.ts.map +1 -1
  135. package/dist/components/navigation/menu-bar-item/menu-bar-item.styles.js +12 -2
  136. package/dist/components/navigation/menu-bar-item/menu-bar-item.styles.js.map +1 -1
  137. package/dist/components/navigation/menu-bar-item/menu-bar-item.template.d.ts.map +1 -1
  138. package/dist/components/navigation/menu-bar-item/menu-bar-item.template.js +11 -10
  139. package/dist/components/navigation/menu-bar-item/menu-bar-item.template.js.map +1 -1
  140. package/dist/components/navigation/top-title-bar/top-title-bar.js +1 -1
  141. package/dist/components/navigation/top-title-bar/top-title-bar.js.map +1 -1
  142. package/dist/components/status-and-feedback/status-bar/status-bar.d.ts +10 -0
  143. package/dist/components/status-and-feedback/status-bar/status-bar.d.ts.map +1 -1
  144. package/dist/components/status-and-feedback/status-bar/status-bar.js +21 -0
  145. package/dist/components/status-and-feedback/status-bar/status-bar.js.map +1 -1
  146. package/dist/css/document-reset.css +3 -3
  147. package/dist/css/rich-text.css +36 -90
  148. package/dist/nldd.min.js +506 -349
  149. package/dist/types/vue.d.ts +67 -24
  150. package/dist/utilities/page-section-mixin.d.ts +5 -0
  151. package/dist/utilities/page-section-mixin.d.ts.map +1 -1
  152. package/dist/utilities/page-section-mixin.js +10 -1
  153. package/dist/utilities/page-section-mixin.js.map +1 -1
  154. package/dist/utilities/scroll-mode-controller.d.ts +29 -13
  155. package/dist/utilities/scroll-mode-controller.d.ts.map +1 -1
  156. package/dist/utilities/scroll-mode-controller.js +48 -13
  157. package/dist/utilities/scroll-mode-controller.js.map +1 -1
  158. package/package.json +4 -4
  159. package/dist/components/layout/app-view/app-view.d.ts.map +0 -1
  160. package/dist/components/layout/app-view/app-view.js.map +0 -1
  161. package/dist/components/layout/app-view/app-view.styles.d.ts +0 -2
  162. package/dist/components/layout/app-view/app-view.styles.d.ts.map +0 -1
  163. package/dist/components/layout/app-view/app-view.styles.js.map +0 -1
  164. package/dist/components/layout/app-view/app-view.template.d.ts +0 -4
  165. package/dist/components/layout/app-view/app-view.template.d.ts.map +0 -1
  166. package/dist/components/layout/app-view/app-view.template.js +0 -9
  167. package/dist/components/layout/app-view/app-view.template.js.map +0 -1
  168. package/dist/components/palettes.html +0 -245
  169. package/dist/components/sample-images/butterfly-1200.jpg +0 -0
  170. package/dist/components/sample-images/butterfly-1600.jpg +0 -0
  171. package/dist/components/sample-images/butterfly-480.jpg +0 -0
  172. package/dist/components/sample-images/butterfly-960.jpg +0 -0
  173. package/dist/palettes.html +0 -245
  174. package/dist/sample-images/butterfly-1200.jpg +0 -0
  175. package/dist/sample-images/butterfly-1600.jpg +0 -0
  176. package/dist/sample-images/butterfly-480.jpg +0 -0
  177. package/dist/sample-images/butterfly-960.jpg +0 -0
@@ -3,8 +3,8 @@ import { n as slottedReset, t as inheritedTextReset } from "./shadow-resets-CPa5
3
3
  import { i as linkRel, n as setTranslations, r as translate, t as withTranslations } from "./with-translations-C8_0-9y8.js";
4
4
  import { t as __decorate } from "./decorate-CO88j7Lc.js";
5
5
  import { t as reflectNonDefault } from "./reflect-non-default-OLaK60rT.js";
6
- import { i as PopupAnchorController, n as NLDDTooltip, r as NLDDActivityIndicator, t as NLDDIconButton } from "./icon-button-mevRsl4C.js";
7
- import { t as NLDDIcon } from "./icon-DQHT2C7z.js";
6
+ import { i as PopupAnchorController, n as NLDDTooltip, r as NLDDActivityIndicator, t as NLDDIconButton } from "./icon-button-NN0SrgS3.js";
7
+ import { t as NLDDIcon } from "./icon-D_ZGezHx.js";
8
8
  import { n as isPointerMode, r as isTouchMode, t as isKeyboardMode } from "./input-modality-DhTeUxKi.js";
9
9
  import { t as breakpoints } from "./breakpoints-CkxsiRgH.js";
10
10
  import { t as VisibilityMixin } from "./visibility-mixin-Crbt8PFP.js";
@@ -2282,6 +2282,7 @@ var textCellStyles = css`
2282
2282
  color: var(--_text-cell-secondary-color);
2283
2283
  font: var(--_text-cell-secondary-font);
2284
2284
  overflow-wrap: anywhere;
2285
+ text-wrap: pretty;
2285
2286
  }
2286
2287
 
2287
2288
  .text-cell__text {
@@ -2309,6 +2310,7 @@ var textCellStyles = css`
2309
2310
  color: var(--_text-cell-secondary-color);
2310
2311
  font: var(--_text-cell-secondary-font);
2311
2312
  overflow-wrap: anywhere;
2313
+ text-wrap: pretty;
2312
2314
  }
2313
2315
  `;
2314
2316
  //#endregion
@@ -8441,8 +8443,8 @@ __decorate([property({
8441
8443
  attribute: "lg-column-count"
8442
8444
  })], NLDDContainer.prototype, "lgColumnCount", void 0);
8443
8445
  __decorate([property({
8444
- type: String,
8445
- reflect: true
8446
+ reflect: true,
8447
+ converter: reflectNonDefault("")
8446
8448
  })], NLDDContainer.prototype, "width", void 0);
8447
8449
  __decorate([property({
8448
8450
  type: String,
@@ -10474,6 +10476,7 @@ var NLDDListItem = (_NLDDListItem2 = class NLDDListItem extends withTranslations
10474
10476
  this.selected = false;
10475
10477
  this.checked = false;
10476
10478
  this.current = false;
10479
+ this.currentType = "page";
10477
10480
  this.disabled = false;
10478
10481
  this._showChildren = false;
10479
10482
  this._parentType = "list";
@@ -10643,7 +10646,7 @@ var NLDDListItem = (_NLDDListItem2 = class NLDDListItem extends withTranslations
10643
10646
  /**
10644
10647
  * A segment marked `current` makes the whole row the current one.
10645
10648
  *
10646
- * A row cut into segments has no control of its own, so `aria-current="page"`
10649
+ * A row cut into segments has no control of its own, so `aria-current`
10647
10650
  * belongs on the segment that holds the link. Written there, the row would
10648
10651
  * stay unpainted and the consumer had to set `current` twice, once for the
10649
10652
  * semantics and once for the color, with nothing to catch the two drifting
@@ -10728,7 +10731,7 @@ var NLDDListItem = (_NLDDListItem2 = class NLDDListItem extends withTranslations
10728
10731
  });
10729
10732
  }
10730
10733
  updated(changed) {
10731
- if (changed.has("selected") || changed.has("current") || changed.has("button") || changed.has("checkbox") || changed.has("radio") || changed.has("href") || changed.has("_parentType")) this._updateAriaState();
10734
+ if (changed.has("selected") || changed.has("current") || changed.has("currentType") || changed.has("button") || changed.has("checkbox") || changed.has("radio") || changed.has("href") || changed.has("_parentType")) this._updateAriaState();
10732
10735
  if (changed.has("button") || changed.has("checkbox") || changed.has("radio") || changed.has("href")) {
10733
10736
  this._updateInteractive();
10734
10737
  this._warnOnNestedControl();
@@ -10822,7 +10825,7 @@ var NLDDListItem = (_NLDDListItem2 = class NLDDListItem extends withTranslations
10822
10825
  this.removeAttribute("aria-selected");
10823
10826
  }
10824
10827
  const action = this._action;
10825
- if (this._parentType === "navigation" && (this.current || this.selected) && action) action.setAttribute("aria-current", "page");
10828
+ if (this._parentType === "navigation" && (this.current || this.selected) && action) action.setAttribute("aria-current", this.currentType);
10826
10829
  else action?.removeAttribute("aria-current");
10827
10830
  }
10828
10831
  /**
@@ -11096,6 +11099,11 @@ __decorate([property({
11096
11099
  type: Boolean,
11097
11100
  reflect: true
11098
11101
  })], NLDDListItem.prototype, "current", void 0);
11102
+ __decorate([property({
11103
+ reflect: true,
11104
+ attribute: "current-type",
11105
+ converter: reflectNonDefault("page")
11106
+ })], NLDDListItem.prototype, "currentType", void 0);
11099
11107
  __decorate([property({
11100
11108
  type: Boolean,
11101
11109
  reflect: true
@@ -12468,9 +12476,13 @@ var imageStyles = css`
12468
12476
  --_image-error-padding: var(--primitives-space-8);
12469
12477
  --_image-error-gap: var(--primitives-space-2);
12470
12478
  --_image-caption-row-gap: var(--primitives-space-8);
12479
+ --_image-pending-background-color: var(--semantics-categories-neutral-tinted-background-color);
12480
+ --_image-empty-icon-size: var(--primitives-space-32);
12481
+ --_image-empty-icon-color: light-dark(var(--primitives-color-neutral-450), var(--primitives-color-neutral-550));
12471
12482
  --_image-object-fit: cover;
12472
12483
  --_image-object-position: center;
12473
12484
  --_image-max-width: 100%;
12485
+ --_image-media-height: var(--context-image-height, auto);
12474
12486
 
12475
12487
  ${inheritedTextReset}
12476
12488
  box-sizing: border-box;
@@ -12531,6 +12543,7 @@ var imageStyles = css`
12531
12543
  position: relative;
12532
12544
  overflow: hidden;
12533
12545
  max-width: 100%;
12546
+ height: var(--_image-media-height);
12534
12547
  border-radius: var(--_image-corner-radius);
12535
12548
  }
12536
12549
 
@@ -12799,6 +12812,37 @@ var imageStyles = css`
12799
12812
  }
12800
12813
 
12801
12814
 
12815
+ /* # Empty and loading */
12816
+
12817
+ .image__media.is-loading {
12818
+ background-color: var(--_image-pending-background-color);
12819
+ }
12820
+
12821
+ .image__media--empty {
12822
+ display: flex;
12823
+ background-color: var(--_image-pending-background-color);
12824
+ width: 100%;
12825
+ height: 100%;
12826
+ aspect-ratio: 16 / 9;
12827
+ align-items: center;
12828
+ justify-content: center;
12829
+ }
12830
+
12831
+ @media (forced-colors: active) {
12832
+ .image__media--empty {
12833
+ outline: 1px solid CanvasText;
12834
+ outline-offset: -1px;
12835
+ }
12836
+ }
12837
+
12838
+ .image__empty-icon {
12839
+ display: block;
12840
+ width: var(--_image-empty-icon-size);
12841
+ height: var(--_image-empty-icon-size);
12842
+ color: var(--_image-empty-icon-color);
12843
+ }
12844
+
12845
+
12802
12846
  /* # Error state
12803
12847
  Centred icon + alt-text shown when the image fails to load. The media is
12804
12848
  painted gray (--_image-background-color) via :host([errored]) so the icon and
@@ -12875,8 +12919,11 @@ function imageTemplate(component) {
12875
12919
  mediaStyles[`--context-lqip-c${i + 1}`] = String(cell);
12876
12920
  });
12877
12921
  }
12922
+ const isEmpty = component._isEmpty;
12878
12923
  const mediaClasses = classMap({
12879
12924
  "image__media": true,
12925
+ "image__media--empty": isEmpty,
12926
+ "is-loading": !isEmpty && !hasLqip && !component._hasSlottedMedia && !component._imageLoaded && !component._imageErrored,
12880
12927
  "image__media--lqip": hasLqip && !component._imageErrored
12881
12928
  });
12882
12929
  const fallbackImg = html`
@@ -12915,8 +12962,10 @@ function imageTemplate(component) {
12915
12962
  const media = html`
12916
12963
  <div class=${mediaClasses}
12917
12964
  style=${styleMap(mediaStyles)}
12965
+ aria-hidden=${isEmpty ? "true" : nothing}
12918
12966
  >
12919
- <slot @slotchange=${component._onMediaSlotChange}>${fallbackImg}</slot>
12967
+ <slot @slotchange=${component._onMediaSlotChange}>${isEmpty ? nothing : fallbackImg}</slot>
12968
+ ${isEmpty ? html`<span class="image__empty-icon"><nldd-icon icon="image"></nldd-icon></span>` : nothing}
12920
12969
  ${errorOverlay}
12921
12970
  ${liveRegion}
12922
12971
  </div>
@@ -12955,6 +13004,13 @@ var nlddImageTranslations = {
12955
13004
  * custom `<img>` or `<picture>` (e.g. with art-direction sources), slot it
12956
13005
  * into the default slot and we'll style and wrap it like our own image.
12957
13006
  *
13007
+ * Without an image (no `src`, `srcset`, `lqip` or slotted media) it shows a
13008
+ * neutral area with an image icon, in the box, shape and caption a real image
13009
+ * would get: a place where an image belongs, for a prototype or a pattern, or
13010
+ * an image someone forgot. Without `aspect-ratio` that area is 16/9. While the
13011
+ * built-in `<img>` loads without an `lqip`, the same area shows without the
13012
+ * icon, and it goes once the image is in.
13013
+ *
12958
13014
  * @element nldd-image
12959
13015
  *
12960
13016
  * @attr {string} src - Image URL
@@ -12982,7 +13038,7 @@ var nlddImageTranslations = {
12982
13038
  * @attr {string} caption - Caption text shown below the image
12983
13039
  * @attr {string} credit - Smaller credit/attribution text shown beside the caption
12984
13040
  * @attr {boolean} decorative - Decorative image: alt is forced empty + aria-hidden
12985
- * @attr {string} lqip - Low-quality image placeholder as a CSV string
13041
+ * @attr {string} lqip - Loading preview (LQIP, low-quality image placeholder) as a CSV string
12986
13042
  * `"base,c1,c2,c3,c4,c5,c6"` — seven 0-255 bytes, each packing an 8-bit
12987
13043
  * Oklab triplet (2 bits L, 3 bits a, 3 bits b). The first is the base
12988
13044
  * color shown outside the cell gradients; the other six are per-cell
@@ -12991,10 +13047,14 @@ var nlddImageTranslations = {
12991
13047
  * Extends Lean Rada's CSS-only LQIP (https://leanrada.com/notes/css-only-lqip/)
12992
13048
  * with per-cell hue — Lean's original format encodes grayscale cells only;
12993
13049
  * ours encodes a color per cell so multi-color subjects survive the
12994
- * placeholder.
13050
+ * preview.
12995
13051
  * @attr {object} translations - Override translation keys (e.g. the message
12996
13052
  * shown when the image fails to load); unset keys fall back to Dutch.
12997
13053
  *
13054
+ * A parent that gives the image a fixed box, such as the media area of
13055
+ * nldd-hero, sets `--context-image-height: 100%` on it, so the image fills that
13056
+ * box instead of taking the height of the photo.
13057
+ *
12998
13058
  * @slot - Custom `<img>`, `<picture>` or inline `<svg>` (overrides the src-based default). An inline svg keeps its own colors and scales by its viewBox, so a drawing gets the same box, ratio and caption as a photo. Slotted media carries its own text alternative: an `alt` on the img (empty when it conveys nothing), or `role="img"` with an `aria-label`, `aria-labelledby` or `<title>` on the svg.
12999
13059
  * The internal `error` listener is attached only to the built-in `<img>`, so
13000
13060
  * slotted content does not trigger the error-state overlay automatically.
@@ -13028,6 +13088,7 @@ var _NLDDImage = class NLDDImage extends LitElement {
13028
13088
  this._warnedWidth = false;
13029
13089
  this._warnedAlt = false;
13030
13090
  this._onMediaSlotChange = () => {
13091
+ this.requestUpdate();
13031
13092
  this._warnMissingAlt();
13032
13093
  };
13033
13094
  this._onImageLoad = () => {
@@ -13131,6 +13192,15 @@ var _NLDDImage = class NLDDImage extends LitElement {
13131
13192
  _slottedMedia() {
13132
13193
  return ((this.shadowRoot?.querySelector("slot:not([name])"))?.assignedElements() ?? []).flatMap((el) => el instanceof HTMLSlotElement ? el.assignedElements({ flatten: true }) : [el]);
13133
13194
  }
13195
+ /** Whether anything sits in the default slot. Read off the light DOM, so
13196
+ * the first render already knows and an image does not flash empty. */
13197
+ get _hasSlottedMedia() {
13198
+ return Array.from(this.children).some((el) => !el.hasAttribute("slot"));
13199
+ }
13200
+ /** No image at all: the component shows where one belongs. */
13201
+ get _isEmpty() {
13202
+ return !this.src && !this.srcset && !this._parsedLqip && !this._hasSlottedMedia;
13203
+ }
13134
13204
  firstUpdated() {
13135
13205
  const img = this.shadowRoot?.querySelector(".image__img");
13136
13206
  if (img?.complete && img.naturalWidth > 0) this._imageLoaded = true;
@@ -13152,8 +13222,8 @@ var _NLDDImage = class NLDDImage extends LitElement {
13152
13222
  };
13153
13223
  var NLDDImage = (_NLDDImage.styles = imageStyles, _NLDDImage);
13154
13224
  __decorate([property({
13155
- type: String,
13156
- reflect: true
13225
+ reflect: true,
13226
+ converter: reflectNonDefault("")
13157
13227
  })], NLDDImage.prototype, "src", void 0);
13158
13228
  __decorate([property({ type: String })], NLDDImage.prototype, "alt", void 0);
13159
13229
  __decorate([property({ type: String })], NLDDImage.prototype, "srcset", void 0);
@@ -13225,18 +13295,30 @@ var nlddRichTextTranslations = { "components.rich-text.table-scroll-label": "Scr
13225
13295
  * The rich text lays out its direct children in a grid: the vertical rhythm
13226
13296
  * between headings, paragraphs and lists, and the width zones below, apply to
13227
13297
  * those children only. A single wrapper `div` without `class`, `style`, `role`
13228
- * or `data-width`, as a markdown renderer or a component root produces it, is
13298
+ * or `data-rich-text-width`, as a markdown renderer or a component root produces it, is
13229
13299
  * passed through with `display: contents`, so its children count as direct.
13230
13300
  * Any other wrapper becomes a single grid item, and the paragraphs inside it
13231
13301
  * lose their spacing.
13232
13302
  *
13303
+ * ## Headings
13304
+ * The headings keep one size on every width, the one they have on a phone. A
13305
+ * heading in running text sits in a column as wide as a line of reading, on
13306
+ * any screen, so its relation to the text beside it does not change and it has
13307
+ * no reason to grow. Growing, an h2 on a wide screen was more than twice the
13308
+ * size of the text, and an article broke into blocks at every heading. Page
13309
+ * and section titles do grow: use nldd-title for those.
13310
+ *
13233
13311
  * ## Width zones
13234
- * Children are placed in three zones: text (headings, paragraphs, lists,
13235
- * blockquote, div/section) reads at the `main` size; media and tables (img,
13236
- * figure, video, iframe, table) get the `wide` accent; everything else, code
13237
- * blocks and every component, gets the full `full` span with
13238
- * `justify-self: start`, so the room is available without being forced.
13239
- * Overridable per child with `data-width="main" | "wide" | "full"`. In the
13312
+ * Children are placed in three zones. A child belongs to the text unless it is
13313
+ * listed, so it reads at the `main` size and is never wider than a line: text
13314
+ * (headings, paragraphs, lists, blockquote, div/section) and every component
13315
+ * that is not named below, such as nldd-box, nldd-card, nldd-banner,
13316
+ * nldd-list and a button, and code (pre, nldd-code-viewer), which scrolls
13317
+ * inside its block when a line is longer. Media, tables and a step bar (img, figure, video, iframe,
13318
+ * table, nldd-table, nldd-image, nldd-step-bar) get the `wide` accent. What
13319
+ * needs the room gets the `full` span: hr, nldd-collection and nldd-container. A child takes the room it needs inside its zone
13320
+ * (`justify-self: start`), so the room is available without being forced.
13321
+ * Overridable per child with `data-rich-text-width="main" | "wide" | "full"`. In the
13240
13322
  * left-aligned layout, wide and full read as a bleed to the right; with
13241
13323
  * `centered` they are symmetrical.
13242
13324
  *
@@ -13252,11 +13334,12 @@ var nlddRichTextTranslations = { "components.rich-text.table-scroll-label": "Scr
13252
13334
  * @attr {boolean} centered - Centers the main column inside the container; without it, content is left-aligned
13253
13335
  * @attr {object} translations - Override translation keys; unset keys fall back to Dutch
13254
13336
  * @attr {boolean} hyphens - Opt-in automatic hyphenation for running text (p,
13255
- * li, dd). Needs a correct `lang` on the page (`lang="nl"` on `<html>`, for
13256
- * instance): without language information the browser does not hyphenate. An
13257
- * `overflow-wrap: break-word` safety net on p/li is always on, independent of
13258
- * this attribute, so long URLs and compounds break neatly instead of
13259
- * overflowing even without a dictionary.
13337
+ * li, dd). Needs a correct
13338
+ * `lang` on the page (`lang="nl"` on `<html>`, for instance): without
13339
+ * language information the browser does not hyphenate. An
13340
+ * `overflow-wrap: break-word` safety net on headings, p and li is always on,
13341
+ * independent of this attribute, so a word wider than the column breaks
13342
+ * instead of overflowing, without a hyphen; headings never get one.
13260
13343
  */
13261
13344
  var MANAGED_LABEL_ATTR = "data-nldd-managed-label";
13262
13345
  var NLDDRichText = class NLDDRichText extends LitElement {
@@ -38126,39 +38209,61 @@ NLDDTokenField = _NLDDTokenField = __decorate([customElement("nldd-token-field")
38126
38209
  //#endregion
38127
38210
  //#region src/utilities/scroll-mode-controller.ts
38128
38211
  /** Bubbling + composed event a horizontal split view fires when it collapses to
38129
- * (or expands out of) a single visible column. nldd-app-view listens for it to
38212
+ * (or expands out of) a single visible column. nldd-shell listens for it to
38130
38213
  * derive the document-vs-nested scroll mode. */
38131
38214
  var SINGLE_COLUMN_CHANGE_EVENT = "nldd-single-column-change";
38132
- /** Nearest ancestor app-view (light-DOM `closest`; slotted layers stay in the
38215
+ var PROVIDER_SELECTOR = "nldd-shell, nldd-sheet, nldd-modal-dialog";
38216
+ /** Nearest ancestor shell (light-DOM `closest`; slotted layers stay in the
38133
38217
  * consumer's light tree so this reaches across the slot boundaries), or null
38134
38218
  * when a layer is used stand-alone (e.g. a bare page in the docs).
38135
38219
  *
38136
38220
  * An overlay ends the search: a sheet or a modal dialog is its own scroll
38137
38221
  * container and its own top edge, so a page inside one owns its scroller
38138
- * whatever the app around it does. Without this the app-view would push its
38222
+ * whatever the app around it does. Without this the shell would push its
38139
38223
  * root mode straight through the overlay and the page's sticky header would
38140
38224
  * stick against the document, over the content of the overlay. The overlays
38141
38225
  * reset --context-scroll-mode as well, which is what the stand-alone read
38142
38226
  * below then finds. */
38143
38227
  function findScrollModeProvider(host) {
38144
- const el = host.closest?.("nldd-app-view, nldd-sheet, nldd-modal-dialog");
38228
+ const el = host.closest?.(PROVIDER_SELECTOR);
38145
38229
  return el && "registerScrollConsumer" in el ? el : null;
38146
38230
  }
38147
38231
  /**
38232
+ * Hands `adopt` the provider above `host` once it is defined, when it was not
38233
+ * yet at the moment `host` connected.
38234
+ *
38235
+ * Custom elements upgrade in the order their modules are defined, and an app
38236
+ * does not control that: importing nldd-sidebar-section defines nldd-page, and
38237
+ * a route that loads before its shell defines the page before the shell. The
38238
+ * provider is then in the DOM but has no `registerScrollConsumer` yet, so
38239
+ * findScrollModeProvider returns null and the layer starts out stand-alone.
38240
+ * This lets it register as soon as the provider is defined. Nothing happens
38241
+ * when the host has left the DOM by then, or sits under another provider.
38242
+ */
38243
+ function whenScrollModeProviderDefined(host, adopt) {
38244
+ const el = host.closest?.(PROVIDER_SELECTOR);
38245
+ if (!el || "registerScrollConsumer" in el) return;
38246
+ customElements.whenDefined(el.localName).then(() => {
38247
+ if (!host.isConnected) return;
38248
+ const provider = findScrollModeProvider(host);
38249
+ if (provider && provider === el) adopt(provider);
38250
+ });
38251
+ }
38252
+ /**
38148
38253
  * Reads the inherited `--context-scroll-mode` and reflects it to the host's
38149
38254
  * `[data-scroll]` attribute so CSS can branch.
38150
38255
  *
38151
- * In root-scroll mode the DOCUMENT scrolls (see nldd-app-view): every layout
38152
- * layer between the document and an nldd-page — app-view, the split views and
38256
+ * In root-scroll mode the DOCUMENT scrolls (see nldd-shell): every layout
38257
+ * layer between the document and an nldd-page — shell, the split views and
38153
38258
  * their panes — must flow (overflow: visible) instead of clipping, so the page's
38154
38259
  * sticky header/footer can stick against the document. Rather than duplicate the
38155
38260
  * read-and-reflect logic in each of those components, they share this controller.
38156
38261
  *
38157
- * The mode is derived upstream by nldd-app-view. When an app-view is present the
38158
- * host registers as a consumer and app-view pushes an authoritative re-read on
38262
+ * The mode is derived upstream by nldd-shell. When a shell is present the
38263
+ * host registers as a consumer and shell pushes an authoritative re-read on
38159
38264
  * every change (a bare `--context-scroll-mode` update would otherwise not reach
38160
38265
  * the resize-polling layers in time — rAF runs before ResizeObserver). Without
38161
- * an app-view (a stand-alone page), it falls back to re-reading on window resize
38266
+ * a shell (a stand-alone page), it falls back to re-reading on window resize
38162
38267
  * so a manual/media-query override still works. `nldd-page` keeps its own inline
38163
38268
  * logic because it also has to re-wire scroll listeners.
38164
38269
  */
@@ -38167,6 +38272,12 @@ var ScrollModeController = class {
38167
38272
  this.mode = "nested";
38168
38273
  this._raf = 0;
38169
38274
  this._provider = null;
38275
+ this._adopt = (provider) => {
38276
+ if (this._provider) return;
38277
+ window.removeEventListener("resize", this._onResize);
38278
+ this._provider = provider;
38279
+ provider.registerScrollConsumer(this);
38280
+ };
38170
38281
  this._onResize = () => {
38171
38282
  if (this._raf) return;
38172
38283
  this._raf = requestAnimationFrame(() => {
@@ -38184,6 +38295,7 @@ var ScrollModeController = class {
38184
38295
  else {
38185
38296
  window.addEventListener("resize", this._onResize, { passive: true });
38186
38297
  this.read();
38298
+ whenScrollModeProviderDefined(this._host, this._adopt);
38187
38299
  }
38188
38300
  }
38189
38301
  hostDisconnected() {
@@ -38194,11 +38306,11 @@ var ScrollModeController = class {
38194
38306
  if (this._raf) cancelAnimationFrame(this._raf);
38195
38307
  }
38196
38308
  /**
38197
- * ScrollModeConsumer — nldd-app-view pushes the mode it derived. When a mode is
38309
+ * ScrollModeConsumer — nldd-shell pushes the mode it derived. When a mode is
38198
38310
  * passed it is applied directly; this is race-free, whereas re-reading
38199
38311
  * `getComputedStyle` during a synchronous push can return a stale value for a
38200
38312
  * deeply-nested host (the var may not have propagated through an ancestor's
38201
- * pending re-render yet). With no argument (resize / no app-view) the inherited
38313
+ * pending re-render yet). With no argument (resize / no shell) the inherited
38202
38314
  * var is re-read instead.
38203
38315
  */
38204
38316
  readScrollMode(mode) {
@@ -38217,8 +38329,8 @@ var ScrollModeController = class {
38217
38329
  }
38218
38330
  };
38219
38331
  //#endregion
38220
- //#region src/components/layout/app-view/app-view.styles.ts
38221
- var appViewStyles = css`
38332
+ //#region src/components/layout/shell/shell.styles.ts
38333
+ var shellStyles = css`
38222
38334
  :host {
38223
38335
  box-sizing: border-box;
38224
38336
  }
@@ -38228,10 +38340,10 @@ var appViewStyles = css`
38228
38340
 
38229
38341
  :host {
38230
38342
  --context-parent-background-color: var(--semantics-surfaces-base-background-color);
38231
- --_app-view-background-color: var(--context-parent-background-color);
38343
+ --_shell-background-color: var(--context-parent-background-color);
38232
38344
 
38233
38345
  display: flex;
38234
- background-color: var(--_app-view-background-color);
38346
+ background-color: var(--_shell-background-color);
38235
38347
  width: 100%;
38236
38348
  height: 100%;
38237
38349
  }
@@ -38242,11 +38354,11 @@ var appViewStyles = css`
38242
38354
 
38243
38355
  :host([background="tinted"]) {
38244
38356
  --context-parent-background-color: var(--semantics-surfaces-tinted-background-color);
38245
- --_app-view-background-color: var(--semantics-surfaces-tinted-background-color);
38357
+ --_shell-background-color: var(--semantics-surfaces-tinted-background-color);
38246
38358
  }
38247
38359
 
38248
38360
  /* Root-scroll mode — the DOCUMENT scrolls (see ScrollModeController +
38249
- --context-scroll-mode). The app-view is the outermost DS layer, so it grows
38361
+ --context-scroll-mode). The shell is the outermost DS layer, so it grows
38250
38362
  with its content (min-height fills the viewport for short pages), letting a
38251
38363
  descendant nldd-page's sticky layers stick against the document. */
38252
38364
  :host([data-scroll="root"]) {
@@ -38257,7 +38369,7 @@ var appViewStyles = css`
38257
38369
 
38258
38370
  /* # Block */
38259
38371
 
38260
- .app-view {
38372
+ .shell {
38261
38373
  display: flex;
38262
38374
  min-width: 0;
38263
38375
  min-height: 0;
@@ -38270,7 +38382,7 @@ var appViewStyles = css`
38270
38382
 
38271
38383
  /* Root-scroll mode — row axis untouched (this is a column block but a row item
38272
38384
  of the host); only stop clipping so descendant sticky layers can escape. */
38273
- :host([data-scroll="root"]) .app-view {
38385
+ :host([data-scroll="root"]) .shell {
38274
38386
  overflow: visible;
38275
38387
  }
38276
38388
 
@@ -38295,18 +38407,18 @@ var appViewStyles = css`
38295
38407
  }
38296
38408
  `;
38297
38409
  //#endregion
38298
- //#region src/components/layout/app-view/app-view.template.ts
38299
- function appViewTemplate(_component) {
38410
+ //#region src/components/layout/shell/shell.template.ts
38411
+ function shellTemplate(_component) {
38300
38412
  return html`
38301
- <div class="app-view">
38413
+ <div class="shell">
38302
38414
  <slot></slot>
38303
38415
  </div>
38304
38416
  `;
38305
38417
  }
38306
38418
  //#endregion
38307
- //#region src/components/layout/app-view/app-view.ts
38419
+ //#region src/components/layout/shell/shell.ts
38308
38420
  /**
38309
- * Nederlandse Digitale Dienst App View Component (Lit + TypeScript)
38421
+ * Nederlandse Digitale Dienst Shell Component (Lit + TypeScript)
38310
38422
  *
38311
38423
  * The required root shell of a Nederlandse Digitale Dienst application. Always contains
38312
38424
  * a split view or an nldd-page as direct content.
@@ -38314,20 +38426,20 @@ function appViewTemplate(_component) {
38314
38426
  * ## Typography
38315
38427
  * The document font comes from the package stylesheet
38316
38428
  * (`@nldd/design-system/styles`), not from this component: it gives `body` the
38317
- * body font and content color as soon as an app-view is on the page, inside
38429
+ * body font and content color as soon as a shell is on the page, inside
38318
38430
  * `@layer reset` so any rule of your own wins. Import only the tokens
38319
38431
  * (`/styles/tokens`) and text you write in the light DOM keeps the browser
38320
38432
  * default.
38321
38433
  *
38322
38434
  * ## Background color
38323
38435
  * Set background="tinted" to give the whole application a tinted background.
38324
- * All descendants read --context-parent-background-color via --_app-view-background-color automatically.
38436
+ * All descendants read --context-parent-background-color via --_shell-background-color automatically.
38325
38437
  * Individual components can override locally with their own background attribute.
38326
38438
  *
38327
38439
  * The same background color is forced on `document.body` so that browser-
38328
38440
  * chrome surfaces (iOS overscroll bounce, status bar, page-margin areas)
38329
38441
  * blend with the app instead of revealing the user-agent's default white.
38330
- * Cleared when the app-view disconnects.
38442
+ * Cleared when the shell disconnects.
38331
38443
  *
38332
38444
  * ## Scroll mode
38333
38445
  * The app scrolls the DOCUMENT (root mode) or lets each `nldd-page` scroll
@@ -38336,31 +38448,31 @@ function appViewTemplate(_component) {
38336
38448
  * mean the panes do. An app without such a split view is a single column at
38337
38449
  * every width and therefore scrolls the document too — nested scrolling would
38338
38450
  * cost it the rubber-band and the collapsing browser toolbar on iOS for nothing.
38339
- * Set `--context-scroll-mode` on the `nldd-app-view` itself to override the
38451
+ * Set `--context-scroll-mode` on the `nldd-shell` itself to override the
38340
38452
  * derived mode; an inherited value loses from it.
38341
38453
  *
38342
38454
  * ## Overscroll
38343
38455
  * In nested scroll mode `overscroll-behavior: none` is set on
38344
- * `document.documentElement` and `document.body` while the app-view is
38456
+ * `document.documentElement` and `document.body` while the shell is
38345
38457
  * connected. Combined with `overscroll-behavior: contain` on `nldd-page`'s
38346
38458
  * scroll target, this prevents iOS rubber-band on the viewport when scroll
38347
38459
  * gestures land outside an `nldd-page` (e.g. on a top-bar). In root scroll mode
38348
38460
  * the document itself is the scroller, so this is lifted to let the native
38349
38461
  * rubber-band happen. Cleared on last disconnect.
38350
38462
  *
38351
- * @element nldd-app-view
38463
+ * @element nldd-shell
38352
38464
  *
38353
38465
  * @attr {'base'|'tinted'} background - Background color (cascades to descendants)
38354
38466
  *
38355
38467
  * @slot - Default slot for the application content
38356
38468
  */
38357
- var _NLDDAppView;
38469
+ var _NLDDShell;
38358
38470
  var _connectedStack = [];
38359
38471
  function _currentOwner() {
38360
38472
  for (let i = _connectedStack.length - 1; i >= 0; i--) if (_connectedStack[i].isConnected) return _connectedStack[i];
38361
38473
  return null;
38362
38474
  }
38363
- var NLDDAppView = (_NLDDAppView = class NLDDAppView extends LitElement {
38475
+ var NLDDShell = (_NLDDShell = class NLDDShell extends LitElement {
38364
38476
  constructor(..._args) {
38365
38477
  super(..._args);
38366
38478
  this.background = "base";
@@ -38390,7 +38502,7 @@ var NLDDAppView = (_NLDDAppView = class NLDDAppView extends LitElement {
38390
38502
  * split view and push it to every registered layer. Without such a split view
38391
38503
  * the app is a single column at any width, so it scrolls the document: nested
38392
38504
  * scrolling costs you the rubber-band and the collapsing browser toolbar on
38393
- * iOS for nothing. Set `--context-scroll-mode: nested` on the `nldd-app-view`
38505
+ * iOS for nothing. Set `--context-scroll-mode: nested` on the `nldd-shell`
38394
38506
  * itself to override (an inherited value loses from the derived one).
38395
38507
  */
38396
38508
  _evaluateScrollMode() {
@@ -38443,14 +38555,14 @@ var NLDDAppView = (_NLDDAppView = class NLDDAppView extends LitElement {
38443
38555
  document.body.style.backgroundColor = `var(${token})`;
38444
38556
  }
38445
38557
  render() {
38446
- return appViewTemplate(this);
38558
+ return shellTemplate(this);
38447
38559
  }
38448
- }, _NLDDAppView.styles = appViewStyles, _NLDDAppView);
38560
+ }, _NLDDShell.styles = shellStyles, _NLDDShell);
38449
38561
  __decorate([property({
38450
38562
  reflect: true,
38451
38563
  converter: reflectNonDefault("base")
38452
- })], NLDDAppView.prototype, "background", void 0);
38453
- NLDDAppView = __decorate([customElement("nldd-app-view")], NLDDAppView);
38564
+ })], NLDDShell.prototype, "background", void 0);
38565
+ NLDDShell = __decorate([customElement("nldd-shell")], NLDDShell);
38454
38566
  //#endregion
38455
38567
  //#region src/components/layout/split-views/bar-split-view/bar-split-view.styles.ts
38456
38568
  var barSplitViewStyles = css`
@@ -39446,7 +39558,7 @@ var _NLDDNavigationSplitView = class NLDDNavigationSplitView extends LitElement
39446
39558
  return this.querySelector(":scope > [slot=\"inspector\"]") !== null;
39447
39559
  }
39448
39560
  /**
39449
- * True when collapsed to a single visible pane (full-stack). nldd-app-view
39561
+ * True when collapsed to a single visible pane (full-stack). nldd-shell
39450
39562
  * reads this — and listens for the `single-column-change` event below — to
39451
39563
  * switch the whole app to document-level scroll.
39452
39564
  * @internal
@@ -39892,7 +40004,7 @@ var _NLDDSideBySideSplitView = class NLDDSideBySideSplitView extends LitElement
39892
40004
  if (changed.has("panes")) this._updateVisiblePanes();
39893
40005
  }
39894
40006
  /**
39895
- * True when only one pane fits. nldd-app-view reads this — and listens for the
40007
+ * True when only one pane fits. nldd-shell reads this — and listens for the
39896
40008
  * `single-column-change` event below — to switch to document-level scroll.
39897
40009
  * @internal
39898
40010
  */
@@ -40339,7 +40451,7 @@ var pageStyles = css`
40339
40451
  overflow: hidden;
40340
40452
  }
40341
40453
 
40342
- /* Root-scroll mode: the DOCUMENT scrolls (see nldd-app-view), not the page.
40454
+ /* Root-scroll mode: the DOCUMENT scrolls (see nldd-shell), not the page.
40343
40455
  The page stops owning an inner scroll container and its sticky-header/footer
40344
40456
  stick against the document, offset by the insets above and below
40345
40457
  (--context-inset-top/bottom, published by any bars outside the page). The mode is derived upstream and
@@ -40548,7 +40660,7 @@ function pageTemplate(component) {
40548
40660
  * content up under the cursor.
40549
40661
  *
40550
40662
  * In root-scroll mode (--context-scroll-mode: root, derived upstream by
40551
- * nldd-app-view) the page stops owning a scroller: the document scrolls and the
40663
+ * nldd-shell) the page stops owning a scroller: the document scrolls and the
40552
40664
  * sticky header/footer stick against the document, offset by
40553
40665
  * --context-inset-top/bottom. The mode is read on connect/resize and reflected
40554
40666
  * to [data-scroll] so the CSS can branch.
@@ -40632,7 +40744,15 @@ var NLDDPage = (_NLDDPage = class NLDDPage extends LitElement {
40632
40744
  this._insetObserver = null;
40633
40745
  this._headerFullHeight = 0;
40634
40746
  this._mainSlot = null;
40747
+ this._mainAttrObserver = null;
40635
40748
  this._resizeRaf = 0;
40749
+ this._adoptScrollProvider = (provider) => {
40750
+ if (this._scrollProvider) return;
40751
+ window.removeEventListener("resize", this._onResize);
40752
+ this._scrollProvider = provider;
40753
+ provider.registerScrollConsumer(this);
40754
+ if (this.hasUpdated) this._configureScroll();
40755
+ };
40636
40756
  this._onResize = () => {
40637
40757
  if (this._resizeRaf) return;
40638
40758
  this._resizeRaf = requestAnimationFrame(() => {
@@ -40648,8 +40768,9 @@ var NLDDPage = (_NLDDPage = class NLDDPage extends LitElement {
40648
40768
  if (!slot) return;
40649
40769
  const items = slot.assignedElements();
40650
40770
  const visible = items.filter((el) => !el.hasAttribute("hidden"));
40651
- const last = visible[visible.length - 1];
40652
- items.forEach((el) => el.classList.toggle("is-last", el === last));
40771
+ const chosen = visible.filter((el) => el.hasAttribute("grow"));
40772
+ const growing = chosen.length > 0 ? chosen : visible.slice(-1);
40773
+ items.forEach((el) => el.toggleAttribute("data-growing", growing.includes(el)));
40653
40774
  };
40654
40775
  }
40655
40776
  /** True when this page renders a section instead of the document landmarks. @internal */
@@ -40725,6 +40846,7 @@ var NLDDPage = (_NLDDPage = class NLDDPage extends LitElement {
40725
40846
  this._readScrollMode();
40726
40847
  this._configureScroll();
40727
40848
  }
40849
+ whenScrollModeProviderDefined(this, this._adoptScrollProvider);
40728
40850
  }
40729
40851
  }
40730
40852
  disconnectedCallback() {
@@ -40748,8 +40870,8 @@ var NLDDPage = (_NLDDPage = class NLDDPage extends LitElement {
40748
40870
  this._warnOnSecondMain();
40749
40871
  }
40750
40872
  /**
40751
- * ScrollModeConsumer — nldd-app-view pushes the derived mode here; called with
40752
- * no argument (resize / no app-view) it re-reads the inherited var. @internal
40873
+ * ScrollModeConsumer — nldd-shell pushes the derived mode here; called with
40874
+ * no argument (resize / no shell) it re-reads the inherited var. @internal
40753
40875
  */
40754
40876
  readScrollMode(mode) {
40755
40877
  if (this._readScrollMode(mode)) this._configureScroll();
@@ -40844,6 +40966,14 @@ var NLDDPage = (_NLDDPage = class NLDDPage extends LitElement {
40844
40966
  this._mainSlot = slot;
40845
40967
  if (!slot) return;
40846
40968
  slot.addEventListener("slotchange", this._updateMainItems);
40969
+ this._mainAttrObserver = new MutationObserver((records) => {
40970
+ if (records.some((record) => record.target.parentElement === this)) this._updateMainItems();
40971
+ });
40972
+ this._mainAttrObserver.observe(this, {
40973
+ attributes: true,
40974
+ attributeFilter: ["grow", "hidden"],
40975
+ subtree: true
40976
+ });
40847
40977
  this._updateMainItems();
40848
40978
  }
40849
40979
  _teardownMainSlotListener() {
@@ -40851,6 +40981,8 @@ var NLDDPage = (_NLDDPage = class NLDDPage extends LitElement {
40851
40981
  this._mainSlot.removeEventListener("slotchange", this._updateMainItems);
40852
40982
  this._mainSlot = null;
40853
40983
  }
40984
+ this._mainAttrObserver?.disconnect();
40985
+ this._mainAttrObserver = null;
40854
40986
  }
40855
40987
  render() {
40856
40988
  return pageTemplate(this);
@@ -40932,6 +41064,10 @@ var PADDING_KEYS = [
40932
41064
  * - **height**: any CSS length (e.g. '400px', '100dvh') applied as the host's
40933
41065
  * min-height (so the section is at least that tall) — mirroring how `width`
40934
41066
  * maps to the body max-width.
41067
+ * - **grow**: the section takes the height the page has left, so the footer
41068
+ * sits at the bottom of a short page. Without it, nldd-page lets its last
41069
+ * section grow. nldd-page reads this and marks the growing section with
41070
+ * `data-growing`; it never writes `grow`, which stays the author's.
40935
41071
  *
40936
41072
  * @example
40937
41073
  * ```ts
@@ -40943,6 +41079,7 @@ function PageSectionMixin(Base) {
40943
41079
  constructor(..._args) {
40944
41080
  super(..._args);
40945
41081
  this.background = "inherit";
41082
+ this.grow = false;
40946
41083
  }
40947
41084
  updated(changed) {
40948
41085
  super.updated(changed);
@@ -40989,13 +41126,17 @@ function PageSectionMixin(Base) {
40989
41126
  }
40990
41127
  }
40991
41128
  __decorate([property({
40992
- type: String,
40993
- reflect: true
41129
+ reflect: true,
41130
+ converter: reflectNonDefault("inherit")
40994
41131
  })], WithPageSection.prototype, "background", void 0);
40995
41132
  __decorate([property({
40996
41133
  type: String,
40997
41134
  reflect: true
40998
41135
  })], WithPageSection.prototype, "height", void 0);
41136
+ __decorate([property({
41137
+ type: Boolean,
41138
+ reflect: true
41139
+ })], WithPageSection.prototype, "grow", void 0);
40999
41140
  __decorate([property({
41000
41141
  type: String,
41001
41142
  reflect: true,
@@ -41097,8 +41238,8 @@ var simpleSectionStyles = css`
41097
41238
  display: none;
41098
41239
  }
41099
41240
 
41100
- :host(:last-child),
41101
- :host(.is-last) {
41241
+ :host([data-growing]),
41242
+ :host([grow]) {
41102
41243
  flex-grow: 1;
41103
41244
  }
41104
41245
 
@@ -41244,6 +41385,7 @@ function simpleSectionTemplate(component) {
41244
41385
  * @attr {'inherit'|'base'|'tinted'} [background] - Surface background ('inherit' default; 'base'/'tinted' paint and cascade a surface).
41245
41386
  * @attr {string} [width] - Body max-width: 'full' removes the constraint so the section spans the full available width. Any CSS length (e.g. '480px') overrides the default max-width.
41246
41387
  * @attr {string} [height] - Minimum section height (any CSS length, e.g. '400px', '100dvh') (mirrors width, which sets the body max-width).
41388
+ * @attr {boolean} grow - Takes the height the page has left, so the footer sits at the bottom of a short page. Without it, nldd-page lets its last section grow.
41247
41389
  * @attr {string} [padding-block] - Block (top and bottom) padding override (token 0-96; '0' strips it).
41248
41390
  * @attr {string} [padding-top] - Top padding override.
41249
41391
  * @attr {string} [padding-bottom] - Bottom padding override.
@@ -41277,8 +41419,8 @@ var _NLDDSimpleSection = class NLDDSimpleSection extends PageSectionMixin(LitEle
41277
41419
  };
41278
41420
  var NLDDSimpleSection = (_NLDDSimpleSection.styles = simpleSectionStyles, _NLDDSimpleSection);
41279
41421
  __decorate([property({
41280
- type: String,
41281
- reflect: true
41422
+ reflect: true,
41423
+ converter: reflectNonDefault("")
41282
41424
  })], NLDDSimpleSection.prototype, "width", void 0);
41283
41425
  __decorate([property({
41284
41426
  reflect: true,
@@ -41320,10 +41462,19 @@ var heroStyles = css`
41320
41462
  --_hero-lg-padding-bottom: initial;
41321
41463
  --_hero-max-width: var(--semantics-page-sections-body-max-width);
41322
41464
  --_hero-media-aspect-ratio: 21 / 9;
41323
- --_hero-main-width: 50%;
41465
+ --_hero-media-height: auto;
41466
+ --_hero-main-min-width: var(--primitives-area-480);
41467
+ --_hero-main-max-width: var(--primitives-area-640);
41468
+ --_hero-main-width: auto;
41324
41469
  --_hero-main-background-color: var(--semantics-categories-accent-reference-background-color);
41325
41470
  --_hero-main-content-color: var(--semantics-categories-accent-reference-content-color);
41326
41471
  --_hero-main-padding: var(--primitives-space-16);
41472
+ --_hero-main-inset: var(--primitives-space-0);
41473
+ --_hero-sm-main-inset: var(--semantics-page-sections-sm-gap);
41474
+ --_hero-sm-main-overlap: var(--primitives-space-48);
41475
+ --_hero-overlap-size: initial;
41476
+ --_hero-default-overlap-size: var(--primitives-space-0);
41477
+ --_hero-default-media-height: auto;
41327
41478
 
41328
41479
  ${inheritedTextReset}
41329
41480
  display: flex;
@@ -41336,8 +41487,8 @@ var heroStyles = css`
41336
41487
  display: none;
41337
41488
  }
41338
41489
 
41339
- :host(:last-child),
41340
- :host(.is-last) {
41490
+ :host([data-growing]),
41491
+ :host([grow]) {
41341
41492
  flex-grow: 1;
41342
41493
  }
41343
41494
 
@@ -41345,18 +41496,6 @@ var heroStyles = css`
41345
41496
  --_hero-max-width: none;
41346
41497
  }
41347
41498
 
41348
- :host([main-width="2/3"]) {
41349
- --_hero-main-width: 66.667%;
41350
- }
41351
-
41352
- :host([main-width="3/4"]) {
41353
- --_hero-main-width: 75%;
41354
- }
41355
-
41356
- :host([main-width="full"]) {
41357
- --_hero-main-width: 100%;
41358
- }
41359
-
41360
41499
  :host([main-background="base"]) {
41361
41500
  --_hero-main-background-color: var(--semantics-surfaces-base-background-color);
41362
41501
  --_hero-main-content-color: var(--semantics-content-color);
@@ -41469,21 +41608,27 @@ var heroStyles = css`
41469
41608
 
41470
41609
  @container (max-width: ${smMax$11}) {
41471
41610
  padding-inline: var(--semantics-page-sections-sm-margin-inline);
41472
- padding-top: var(--_hero-sm-padding-top, var(--_hero-padding-top, var(--semantics-page-sections-sm-margin-block)));
41611
+ padding-top: var(--_hero-sm-padding-top, var(--_hero-padding-top, calc(var(--semantics-page-sections-sm-margin-block) / 2)));
41473
41612
  padding-bottom: var(--_hero-sm-padding-bottom, var(--_hero-padding-bottom, var(--semantics-page-sections-sm-margin-block)));
41474
41613
  }
41475
41614
 
41476
41615
  @container (min-width: ${mdMin$10}) and (max-width: ${mdMax$8}) {
41477
41616
  --_hero-main-padding: var(--primitives-space-24);
41617
+ --_hero-main-inset: var(--semantics-page-sections-md-gap);
41618
+ --_hero-default-overlap-size: var(--primitives-area-160);
41619
+ --_hero-default-media-height: var(--primitives-area-320);
41478
41620
  padding-inline: var(--semantics-page-sections-md-margin-inline);
41479
- padding-top: var(--_hero-md-padding-top, var(--_hero-padding-top, var(--semantics-page-sections-md-margin-block)));
41621
+ padding-top: var(--_hero-md-padding-top, var(--_hero-padding-top, calc(var(--semantics-page-sections-md-margin-block) / 2)));
41480
41622
  padding-bottom: var(--_hero-md-padding-bottom, var(--_hero-padding-bottom, var(--semantics-page-sections-md-margin-block)));
41481
41623
  }
41482
41624
 
41483
41625
  @container (min-width: ${lgMin$9}) {
41484
41626
  --_hero-main-padding: var(--primitives-space-32);
41627
+ --_hero-main-inset: var(--semantics-page-sections-lg-gap);
41628
+ --_hero-default-overlap-size: var(--primitives-area-160);
41629
+ --_hero-default-media-height: var(--primitives-area-400);
41485
41630
  padding-inline: var(--semantics-page-sections-lg-margin-inline);
41486
- padding-top: var(--_hero-lg-padding-top, var(--_hero-padding-top, var(--semantics-page-sections-lg-margin-block)));
41631
+ padding-top: var(--_hero-lg-padding-top, var(--_hero-padding-top, calc(var(--semantics-page-sections-lg-margin-block) / 2)));
41487
41632
  padding-bottom: var(--_hero-lg-padding-bottom, var(--_hero-padding-bottom, var(--semantics-page-sections-lg-margin-block)));
41488
41633
  }
41489
41634
  }
@@ -41499,13 +41644,16 @@ var heroStyles = css`
41499
41644
  .hero__body {
41500
41645
  display: grid;
41501
41646
  position: relative;
41502
- background-color: var(--_hero-main-background-color);
41503
41647
  width: 100%;
41504
41648
  max-width: var(--_hero-max-width);
41505
41649
  flex-grow: 1;
41506
41650
  grid-template-columns: 100%;
41507
41651
  }
41508
41652
 
41653
+ :host(:not([data-has-media])) .hero__body {
41654
+ background-color: var(--_hero-main-background-color);
41655
+ }
41656
+
41509
41657
  /* Without media a base-colored panel would be invisible on the base surface;
41510
41658
  give it a full border so the rectangle reads. */
41511
41659
  :host(:not([data-has-media])[main-background="base"]) .hero__body {
@@ -41518,9 +41666,10 @@ var heroStyles = css`
41518
41666
  (instead of aspect-ratio on the body) keeps growth content-driven
41519
41667
  rather than rigidly tied to the width. align-self: start stops the
41520
41668
  stretch fit from cancelling the ratio. */
41521
- :host([data-has-media]:not([main-width="full"])) .hero__body::before {
41669
+ :host([data-has-media]) .hero__body::before {
41522
41670
  @container (min-width: ${mdMin$10}) {
41523
41671
  content: '';
41672
+ height: var(--_hero-media-height);
41524
41673
  aspect-ratio: var(--_hero-media-aspect-ratio);
41525
41674
  grid-area: 1 / 1;
41526
41675
  align-self: start;
@@ -41554,7 +41703,11 @@ var heroStyles = css`
41554
41703
  object-fit: cover !important;
41555
41704
  }
41556
41705
 
41706
+ /* Two heights: the host fills the media area, and the variable makes the
41707
+ image inside the host fill the host. Without either one it collapses. */
41557
41708
  .hero__media ::slotted(nldd-image) {
41709
+ --context-image-height: 100%;
41710
+
41558
41711
  display: block !important;
41559
41712
  width: 100% !important;
41560
41713
  height: 100% !important;
@@ -41583,7 +41736,9 @@ var heroStyles = css`
41583
41736
  align-self: end;
41584
41737
  justify-self: start;
41585
41738
  background-color: var(--_hero-main-background-color);
41586
- width: var(--_hero-main-width);
41739
+ width: fit-content;
41740
+ min-width: min(var(--_hero-main-min-width), 100% - 2 * var(--_hero-main-inset));
41741
+ max-width: min(var(--_hero-main-max-width), 100% - 2 * var(--_hero-main-inset));
41587
41742
  padding: var(--_hero-main-padding);
41588
41743
  flex-direction: column;
41589
41744
  color: var(--_hero-main-content-color);
@@ -41591,6 +41746,26 @@ var heroStyles = css`
41591
41746
 
41592
41747
  :host(:not([data-has-media])) .hero__main {
41593
41748
  width: 100%;
41749
+ min-width: 0;
41750
+ max-width: none;
41751
+ }
41752
+
41753
+ :host([data-has-media]) .hero__main {
41754
+ margin: var(--_hero-main-inset);
41755
+ }
41756
+
41757
+ :host([data-has-media][data-main-width-length]) .hero__main {
41758
+ @container (min-width: ${mdMin$10}) {
41759
+ width: var(--_hero-main-width);
41760
+ min-width: 0;
41761
+ max-width: calc(100% - 2 * var(--_hero-main-inset));
41762
+ }
41763
+ }
41764
+
41765
+ :host([data-has-media][main-width="full"]) .hero__main {
41766
+ width: auto;
41767
+ max-width: none;
41768
+ justify-self: stretch;
41594
41769
  }
41595
41770
 
41596
41771
  :host([main-position="top-left"]) .hero__main {
@@ -41606,6 +41781,15 @@ var heroStyles = css`
41606
41781
  justify-self: end;
41607
41782
  }
41608
41783
 
41784
+ :host([main-position="bottom-center"]) .hero__main {
41785
+ justify-self: center;
41786
+ }
41787
+
41788
+ :host([main-position="top-center"]) .hero__main {
41789
+ align-self: start;
41790
+ justify-self: center;
41791
+ }
41792
+
41609
41793
  :host([main-position="left"]) .hero__main {
41610
41794
  align-self: stretch;
41611
41795
  }
@@ -41622,32 +41806,38 @@ var heroStyles = css`
41622
41806
  }
41623
41807
 
41624
41808
 
41625
- /* # Full-width strip (md+)
41626
- With main-width="full" the panel is a full top or bottom strip and the
41627
- media stacks on the opposite side instead of sitting behind it. Switch the
41628
- body to a column so the two blocks stack: a bottom panel keeps the media on
41629
- top, a top panel (column-reverse) drops it below. The media keeps the
41630
- overlay's 21/9 strip. Below sm every layout already stacks, so this only
41631
- targets md and up. */
41809
+ /* # Overlap (md+) — the media keeps a fixed height; the panel sits in the
41810
+ row below it, pulled up over it by the overlap size. */
41632
41811
 
41633
41812
  @container (min-width: ${mdMin$10}) {
41634
- :host([data-has-media][main-width="full"]) .hero__body {
41635
- display: flex;
41636
- flex-direction: column;
41813
+ :host([data-has-media]:not([layout="contained"])) .hero__body::before {
41814
+ content: none;
41815
+ }
41816
+
41817
+ :host([data-has-media]:not([layout="contained"])) .hero__media {
41818
+ position: relative;
41819
+ width: 100%;
41820
+ height: var(--_hero-media-height);
41821
+ aspect-ratio: var(--_hero-media-aspect-ratio);
41822
+ grid-area: 1 / 1;
41823
+ align-self: start;
41637
41824
  }
41638
41825
 
41639
- :host([data-has-media][main-width="full"]:is([main-position="top-left"], [main-position="top-right"])) .hero__body {
41640
- flex-direction: column-reverse;
41826
+ :host([data-has-media]:not([layout="contained"]):not([media-height], [media-aspect-ratio])) .hero__media {
41827
+ height: var(--_hero-default-media-height);
41641
41828
  }
41642
41829
 
41643
- :host([data-has-media][main-width="full"]) .hero__media {
41644
- position: static;
41645
- aspect-ratio: var(--_hero-media-aspect-ratio);
41830
+ :host([data-has-media]:not([layout="contained"])) .hero__main {
41831
+ margin-top: calc(-1 * var(--_hero-overlap-size, var(--_hero-default-overlap-size)));
41832
+ margin-bottom: 0;
41833
+ grid-area: 2 / 1;
41834
+ align-self: start;
41646
41835
  }
41647
41836
  }
41648
41837
 
41649
41838
 
41650
- /* # Mobile — stack media over a full-width panel. */
41839
+ /* # Mobile — the media on top, the panel below it, indented and overlapping
41840
+ it a little. */
41651
41841
 
41652
41842
  @container (max-width: ${smMax$11}) {
41653
41843
  .hero__body {
@@ -41655,18 +41845,24 @@ var heroStyles = css`
41655
41845
  flex-direction: column;
41656
41846
  }
41657
41847
 
41658
- :host(:is([main-position="top-left"], [main-position="top-right"])) .hero__body {
41659
- flex-direction: column-reverse;
41660
- }
41661
-
41662
41848
  .hero__media {
41663
41849
  position: static;
41850
+ width: 100%;
41851
+ height: var(--_hero-media-height);
41664
41852
  overflow: hidden;
41665
41853
  aspect-ratio: var(--_hero-media-aspect-ratio);
41666
41854
  }
41667
41855
 
41668
41856
  .hero__main {
41669
41857
  width: 100%;
41858
+ min-width: 0;
41859
+ max-width: none;
41860
+ }
41861
+
41862
+ :host([data-has-media]) .hero__main {
41863
+ margin: calc(-1 * var(--_hero-sm-main-overlap)) var(--_hero-sm-main-inset) 0;
41864
+ width: auto;
41865
+ align-self: stretch;
41670
41866
  }
41671
41867
  }
41672
41868
  `;
@@ -41705,15 +41901,40 @@ function heroTemplate(component) {
41705
41901
  /**
41706
41902
  * Nederlandse Digitale Dienst Hero Component (Lit + TypeScript)
41707
41903
  *
41708
- * A page header with a media area and a text panel (the main) that can stand in
41709
- * six positions. Every area is rectangular.
41710
- *
41711
- * With `main-width="full"` the media area sits as its own strip above or below
41712
- * the panel rather than behind it. On mobile the media always stacks above the
41713
- * full-width panel. Without media the main fills the whole area; with
41904
+ * The section that says what a page is for: it names the main goal of what
41905
+ * you can find there, draws the eye and is the visual welcome. It has a media
41906
+ * area and a text panel (the main) that can stand in eight positions. Every
41907
+ * area is rectangular. Use it on pages where a visitor first has to know where
41908
+ * they are, such as a home or a topic page; where the title already does
41909
+ * that, a section with a title is enough.
41910
+ *
41911
+ * The image in a hero sets the mood and is never the main content, so the
41912
+ * panel always stands on it. Over an image the panel keeps a section gap from
41913
+ * its edges, so it reads as a panel on the image rather than a frame cut out of
41914
+ * it; with `main-width="full"` it is a strip across the whole image, the same
41915
+ * gap from the sides. On mobile the image comes first and the panel below it,
41916
+ * indented by the section gap and overlapping the image by 48px. For an
41917
+ * image beside text without that relation, use a section with an image beside
41918
+ * text instead. Without media the main fills the whole area; with
41714
41919
  * `main-background="base"` that area gets a border so it stays visible on the
41715
41920
  * base surface.
41716
41921
  *
41922
+ * The hero is the head of a page and sits right under the top bar, so its top
41923
+ * padding is half that of the other page sections: the full distance is meant
41924
+ * to separate two sections, and under the top bar it reads as a gap. The
41925
+ * bottom keeps the full distance to the section below. Set `padding-top` to
41926
+ * place a hero elsewhere.
41927
+ *
41928
+ * By default the panel falls over the bottom of the image and runs on below it
41929
+ * (`layout="overlap"`), so the image keeps its height whatever the content.
41930
+ * `layout="contained"` keeps the panel on the image, for a short panel or one
41931
+ * that stands at the top or along a side.
41932
+ *
41933
+ * The height of a hero comes from its image: `media-aspect-ratio`, or a fixed
41934
+ * `media-height`. The `height` of the other page sections is not used here: as
41935
+ * a minimum height for the whole hero it stretched the panel once that sat
41936
+ * below the image. A hero given `height` says so in development.
41937
+ *
41717
41938
  * `main-background` gives the panel a surface color from the filled categories.
41718
41939
  * Those carry a pure white or black content color along, so components with
41719
41940
  * `color="inherit"` (title, rich-text) are guaranteed to keep their contrast.
@@ -41722,17 +41943,19 @@ function heroTemplate(component) {
41722
41943
  *
41723
41944
  * @attr {'inherit'|'base'|'tinted'} background - Surface behind the hero (section API)
41724
41945
  * @attr {string} width - Body max-width; 'full' removes the bound (section API)
41725
- * @attr {string} height - Minimum height of the section (section API)
41946
+ * @attr {boolean} grow - Takes the height the page has left, so the footer sits at the bottom of a short page. Without it, nldd-page lets its last section grow.
41726
41947
  * @attr {string} padding-block - Block padding override, also per edge and responsive (section API)
41948
+ * @attr {'contained'|'overlap'} layout - How the panel relates to the image (default: 'overlap'). 'contained' keeps it on the image, in any of the eight positions; 'overlap' lets it fall `overlap-size` over the bottom of the image and run on below as far as its content needs, so the image keeps its height whatever the content. In 'overlap' the image has a fixed height (320px on md, 400px on lg) unless `media-height` or `media-aspect-ratio` is set, and only the horizontal side of `main-position` counts. A panel shorter than `overlap-size` ends inside the image and says so in development
41727
41949
  * @attr {string} main-background - Surface color of the panel: 'base' (the base surface)
41728
41950
  * or a category color — 'accent' (default) or a Rijkshuisstijl color such as
41729
41951
  * 'lintblauw'|'donkerblauw'|'oranje'
41730
- * @attr {'1/2'|'2/3'|'3/4'|'full'} main-width - Width of the panel (default: '1/2');
41731
- * 'full' makes a full top or bottom strip and is ignored with 'left'/'right'
41732
- * @attr {'top-left'|'top-right'|'bottom-left'|'bottom-right'|'left'|'right'} main-position -
41952
+ * @attr {string} main-width - Width of the panel (default: 'auto'). 'auto' follows the content, between 480px and 640px and never wider than the image allows: a short title gets a narrow panel, a paragraph runs on to a readable line length. 'full' makes a strip across the whole image, at the top or the bottom, and is ignored with 'left'/'right'. Any CSS width (e.g. '560px', '60%') sets it exactly on md and lg, still never wider than the image allows; an invalid value falls back to 'auto'
41953
+ * @attr {'top-left'|'top-center'|'top-right'|'bottom-left'|'bottom-center'|'bottom-right'|'left'|'right'} main-position -
41733
41954
  * Position of the text panel (default: 'bottom-left'); 'left'/'right' span the full height
41955
+ * @attr {string} overlap-size - With layout="overlap": how far the panel falls over the bottom of the image, any CSS length (default: 160px). The overlap stays the same whatever the height of the image; a panel shorter than this ends inside the image
41734
41956
  * @attr {string} media-aspect-ratio - Aspect ratio of the media area (CSS form, '16/9' or '16:9');
41735
41957
  * default '21/9'. On md/lg it sets the height of the hero, on sm the height of the media area
41958
+ * @attr {string} media-height - Fixed height of the media area, any CSS length (e.g. '320px', '40vh'); wins over media-aspect-ratio. An invalid value falls back to the ratio
41736
41959
  * @attr {string} media-src - Source of the media area (an alternative to the media slot);
41737
41960
  * ignored as soon as the media slot is filled
41738
41961
  * @attr {string} media-srcset - Responsive source set for media-src
@@ -41744,19 +41967,42 @@ function heroTemplate(component) {
41744
41967
  * otherwise give a describing alt text.
41745
41968
  * @slot - Content of the text panel (nldd-title and nldd-rich-text with color="inherit", for instance)
41746
41969
  */
41747
- var _NLDDHero = class NLDDHero extends PageSectionMixin(LitElement) {
41970
+ var _NLDDHero;
41971
+ var CSS_WIDE_KEYWORDS = /* @__PURE__ */ new Set([
41972
+ "inherit",
41973
+ "initial",
41974
+ "unset",
41975
+ "revert",
41976
+ "revert-layer"
41977
+ ]);
41978
+ /**
41979
+ * Whether `property` takes `value` as a value of its own. CSS.supports alone
41980
+ * also says yes to the CSS-wide keywords, for any property; written into a
41981
+ * custom property those would not fall back to the default but resolve to
41982
+ * something else.
41983
+ */
41984
+ function takesValue(property, value) {
41985
+ return !CSS_WIDE_KEYWORDS.has(value.trim().toLowerCase()) && CSS.supports(property, value);
41986
+ }
41987
+ var NLDDHero = (_NLDDHero = class NLDDHero extends PageSectionMixin(LitElement) {
41748
41988
  constructor(..._args) {
41749
41989
  super(..._args);
41750
41990
  this.width = "";
41991
+ this.layout = "overlap";
41751
41992
  this.mainBackground = "accent";
41752
- this.mainWidth = "1/2";
41993
+ this.mainWidth = "auto";
41753
41994
  this.mainPosition = "bottom-left";
41754
41995
  this.mediaAspectRatio = "";
41996
+ this.overlapSize = "";
41997
+ this.mediaHeight = "";
41755
41998
  this.mediaSrc = "";
41756
41999
  this.mediaSrcset = "";
41757
42000
  this.mediaSizes = "";
41758
42001
  this.mediaAlt = "";
41759
42002
  this._slotHasMedia = false;
42003
+ this._warnedHeight = false;
42004
+ this._overlapObserver = null;
42005
+ this._warnedOverlap = false;
41760
42006
  }
41761
42007
  /** Media is present when the slot has content or media-src is set. */
41762
42008
  get _hasMedia() {
@@ -41766,19 +42012,75 @@ var _NLDDHero = class NLDDHero extends PageSectionMixin(LitElement) {
41766
42012
  super.willUpdate(changed);
41767
42013
  this.toggleAttribute("data-has-media", this._hasMedia);
41768
42014
  }
42015
+ connectedCallback() {
42016
+ super.connectedCallback();
42017
+ }
42018
+ disconnectedCallback() {
42019
+ super.disconnectedCallback();
42020
+ this._overlapObserver?.disconnect();
42021
+ this._overlapObserver = null;
42022
+ this._warnedOverlap = false;
42023
+ }
41769
42024
  updated(changed) {
41770
42025
  super.updated(changed);
41771
42026
  if (changed.has("width")) {
41772
42027
  const w = this.width;
41773
- if (w && w !== "full" && CSS.supports("max-width", w)) this.style.setProperty("--_hero-max-width", w);
42028
+ if (w && w !== "full" && takesValue("max-width", w)) this.style.setProperty("--_hero-max-width", w);
41774
42029
  else this.style.removeProperty("--_hero-max-width");
41775
42030
  }
42031
+ if (changed.has("mainWidth")) {
42032
+ const width = (this.mainWidth ?? "").trim();
42033
+ const valid = width !== "" && width !== "auto" && width !== "full" && takesValue("width", width);
42034
+ if (valid) this.style.setProperty("--_hero-main-width", width);
42035
+ else this.style.removeProperty("--_hero-main-width");
42036
+ this.toggleAttribute("data-main-width-length", valid);
42037
+ }
42038
+ if (changed.has("overlapSize")) {
42039
+ const size = (this.overlapSize ?? "").trim();
42040
+ if (size && takesValue("margin-top", size)) this.style.setProperty("--_hero-overlap-size", size);
42041
+ else this.style.removeProperty("--_hero-overlap-size");
42042
+ }
42043
+ if (changed.has("mediaHeight")) {
42044
+ const height = (this.mediaHeight ?? "").trim();
42045
+ if (height && takesValue("height", height)) this.style.setProperty("--_hero-media-height", height);
42046
+ else this.style.removeProperty("--_hero-media-height");
42047
+ }
42048
+ if (changed.has("height") && this.height) this.style.removeProperty("min-height");
41776
42049
  if (changed.has("mediaAspectRatio")) {
41777
42050
  const ratio = (this.mediaAspectRatio ?? "").replace(":", "/").trim();
41778
- if (ratio && CSS.supports("aspect-ratio", ratio)) this.style.setProperty("--_hero-media-aspect-ratio", ratio);
42051
+ if (ratio && takesValue("aspect-ratio", ratio)) this.style.setProperty("--_hero-media-aspect-ratio", ratio);
41779
42052
  else this.style.removeProperty("--_hero-media-aspect-ratio");
41780
42053
  }
41781
42054
  }
42055
+ _watchOverlap() {
42056
+ if (!(this.layout !== "contained" && typeof ResizeObserver !== "undefined")) {
42057
+ this._overlapObserver?.disconnect();
42058
+ this._overlapObserver = null;
42059
+ return;
42060
+ }
42061
+ if (this._overlapObserver) return;
42062
+ const media = this.shadowRoot?.querySelector(".hero__media");
42063
+ const main = this.shadowRoot?.querySelector(".hero__main");
42064
+ if (!media || !main) return;
42065
+ this._overlapObserver = new ResizeObserver(() => this._checkOverlap(media, main));
42066
+ this._overlapObserver.observe(media);
42067
+ this._overlapObserver.observe(main);
42068
+ }
42069
+ /**
42070
+ * In an overlap hero the panel is meant to run on below the image. When it
42071
+ * ends inside it, the content is shorter than `overlap-size`; the consumer
42072
+ * decides how far it runs on, so this only says so, in development.
42073
+ */
42074
+ _checkOverlap(media, main) {
42075
+ if (!this._hasMedia || getComputedStyle(media).position === "static") return;
42076
+ if (!(main.getBoundingClientRect().bottom <= media.getBoundingClientRect().bottom)) {
42077
+ this._warnedOverlap = false;
42078
+ return;
42079
+ }
42080
+ if (this._warnedOverlap) return;
42081
+ this._warnedOverlap = true;
42082
+ console.warn("<nldd-hero>: With layout=\"overlap\" the panel is shorter than `overlap-size` and ends inside the image. Give it more content or a smaller `overlap-size`, or set layout=\"contained\" to keep the panel on the image.", this);
42083
+ }
41782
42084
  /** @internal Tracks the media slot so the no-media mode can collapse it. */
41783
42085
  _onMediaSlotChange(e) {
41784
42086
  const slot = e.target;
@@ -41787,12 +42089,15 @@ var _NLDDHero = class NLDDHero extends PageSectionMixin(LitElement) {
41787
42089
  render() {
41788
42090
  return heroTemplate(this);
41789
42091
  }
41790
- };
41791
- var NLDDHero = (_NLDDHero.styles = heroStyles, _NLDDHero);
42092
+ }, _NLDDHero.styles = heroStyles, _NLDDHero);
41792
42093
  __decorate([property({
41793
- type: String,
41794
- reflect: true
42094
+ reflect: true,
42095
+ converter: reflectNonDefault("")
41795
42096
  })], NLDDHero.prototype, "width", void 0);
42097
+ __decorate([property({
42098
+ reflect: true,
42099
+ converter: reflectNonDefault("overlap")
42100
+ })], NLDDHero.prototype, "layout", void 0);
41796
42101
  __decorate([property({
41797
42102
  reflect: true,
41798
42103
  attribute: "main-background",
@@ -41801,7 +42106,7 @@ __decorate([property({
41801
42106
  __decorate([property({
41802
42107
  reflect: true,
41803
42108
  attribute: "main-width",
41804
- converter: reflectNonDefault("1/2")
42109
+ converter: reflectNonDefault("auto")
41805
42110
  })], NLDDHero.prototype, "mainWidth", void 0);
41806
42111
  __decorate([property({
41807
42112
  reflect: true,
@@ -41809,10 +42114,20 @@ __decorate([property({
41809
42114
  converter: reflectNonDefault("bottom-left")
41810
42115
  })], NLDDHero.prototype, "mainPosition", void 0);
41811
42116
  __decorate([property({
41812
- type: String,
41813
42117
  reflect: true,
41814
- attribute: "media-aspect-ratio"
42118
+ attribute: "media-aspect-ratio",
42119
+ converter: reflectNonDefault("")
41815
42120
  })], NLDDHero.prototype, "mediaAspectRatio", void 0);
42121
+ __decorate([property({
42122
+ reflect: true,
42123
+ attribute: "overlap-size",
42124
+ converter: reflectNonDefault("")
42125
+ })], NLDDHero.prototype, "overlapSize", void 0);
42126
+ __decorate([property({
42127
+ reflect: true,
42128
+ attribute: "media-height",
42129
+ converter: reflectNonDefault("")
42130
+ })], NLDDHero.prototype, "mediaHeight", void 0);
41816
42131
  __decorate([property({
41817
42132
  type: String,
41818
42133
  attribute: "media-src"
@@ -41869,6 +42184,11 @@ var fullBleedSectionStyles = css`
41869
42184
  display: none;
41870
42185
  }
41871
42186
 
42187
+ :host([data-growing]),
42188
+ :host([grow]) {
42189
+ flex-grow: 1;
42190
+ }
42191
+
41872
42192
  :host([width="full"]) {
41873
42193
  --_full-bleed-section-max-width: none;
41874
42194
  }
@@ -41981,6 +42301,7 @@ function fullBleedSectionTemplate(component) {
41981
42301
  * @attr {'inherit'|'base'|'tinted'} [background] - Surface background ('inherit' default; 'base'/'tinted' paint and cascade a surface).
41982
42302
  * @attr {string} [width] - Body max-width: 'full' removes the constraint so the section spans the full available width. Any CSS length (e.g. '480px') overrides the default max-width.
41983
42303
  * @attr {string} [height] - Minimum section height (any CSS length, e.g. '400px', '100dvh') (mirrors width, which sets the body max-width).
42304
+ * @attr {boolean} grow - Takes the height the page has left, so the footer sits at the bottom of a short page. Without it, nldd-page lets its last section grow.
41984
42305
  * @attr {string} [padding-block] - Block (top and bottom) padding override (token 0-96; '0' strips it).
41985
42306
  * @attr {string} [padding-top] - Top padding override.
41986
42307
  * @attr {string} [padding-bottom] - Bottom padding override.
@@ -42009,8 +42330,8 @@ var _NLDDFullBleedSection = class NLDDFullBleedSection extends PageSectionMixin(
42009
42330
  };
42010
42331
  var NLDDFullBleedSection = (_NLDDFullBleedSection.styles = fullBleedSectionStyles, _NLDDFullBleedSection);
42011
42332
  __decorate([property({
42012
- type: String,
42013
- reflect: true
42333
+ reflect: true,
42334
+ converter: reflectNonDefault("")
42014
42335
  })], NLDDFullBleedSection.prototype, "width", void 0);
42015
42336
  NLDDFullBleedSection = __decorate([customElement("nldd-full-bleed-section")], NLDDFullBleedSection);
42016
42337
  //#endregion
@@ -42051,6 +42372,11 @@ var oneThirdTwoThirdsSectionStyles = css`
42051
42372
  display: none;
42052
42373
  }
42053
42374
 
42375
+ :host([data-growing]),
42376
+ :host([grow]) {
42377
+ flex-grow: 1;
42378
+ }
42379
+
42054
42380
  :host([width="full"]) {
42055
42381
  --_one-third-two-thirds-section-max-width: none;
42056
42382
  }
@@ -42138,6 +42464,18 @@ var oneThirdTwoThirdsSectionStyles = css`
42138
42464
  }
42139
42465
  }
42140
42466
 
42467
+ :host([vertical-alignment="center"]) .one-third-two-thirds-section__columns {
42468
+ @container (min-width: 769px) {
42469
+ align-items: center;
42470
+ }
42471
+ }
42472
+
42473
+ :host([vertical-alignment="bottom"]) .one-third-two-thirds-section__columns {
42474
+ @container (min-width: 769px) {
42475
+ align-items: flex-end;
42476
+ }
42477
+ }
42478
+
42141
42479
  .one-third-two-thirds-section__left-column {
42142
42480
  min-width: var(--primitives-area-280);
42143
42481
  flex-grow: 1;
@@ -42201,10 +42539,12 @@ function oneThirdTwoThirdsSectionTemplate(component) {
42201
42539
  * @attr {'inherit'|'base'|'tinted'} [background] - Surface background ('inherit' default; 'base'/'tinted' paint and cascade a surface).
42202
42540
  * @attr {string} [width] - Body max-width: 'full' removes the constraint so the section spans the full available width. Any CSS length (e.g. '480px') overrides the default max-width.
42203
42541
  * @attr {string} [height] - Minimum section height (any CSS length, e.g. '400px', '100dvh') (mirrors width, which sets the body max-width).
42542
+ * @attr {boolean} grow - Takes the height the page has left, so the footer sits at the bottom of a short page. Without it, nldd-page lets its last section grow.
42204
42543
  * @attr {string} [padding-block] - Block (top and bottom) padding override (token 0-96; '0' strips it).
42205
42544
  * @attr {string} [padding-top] - Top padding override.
42206
42545
  * @attr {string} [padding-bottom] - Bottom padding override.
42207
42546
  * @attr {string} [sm-padding-block] - Responsive block padding (sm/md/lg, also per edge: {sm,md,lg}-padding-{top,bottom}).
42547
+ * @attr {'top'|'center'|'bottom'} [vertical-alignment] - Where the shorter column sits next to the longer one ('top' default). Only where the columns stand side by side; stacked, they follow each other.
42208
42548
  *
42209
42549
  * @slot header - Content above the columns
42210
42550
  * @slot left - Left column (1/3)
@@ -42216,6 +42556,7 @@ var _NLDDOneThirdTwoThirdsSection = class NLDDOneThirdTwoThirdsSection extends P
42216
42556
  constructor(..._args) {
42217
42557
  super(..._args);
42218
42558
  this.width = "";
42559
+ this.verticalAlignment = "top";
42219
42560
  }
42220
42561
  updated(changedProperties) {
42221
42562
  super.updated(changedProperties);
@@ -42231,9 +42572,14 @@ var _NLDDOneThirdTwoThirdsSection = class NLDDOneThirdTwoThirdsSection extends P
42231
42572
  };
42232
42573
  var NLDDOneThirdTwoThirdsSection = (_NLDDOneThirdTwoThirdsSection.styles = oneThirdTwoThirdsSectionStyles, _NLDDOneThirdTwoThirdsSection);
42233
42574
  __decorate([property({
42234
- type: String,
42235
- reflect: true
42575
+ reflect: true,
42576
+ converter: reflectNonDefault("")
42236
42577
  })], NLDDOneThirdTwoThirdsSection.prototype, "width", void 0);
42578
+ __decorate([property({
42579
+ reflect: true,
42580
+ attribute: "vertical-alignment",
42581
+ converter: reflectNonDefault("top")
42582
+ })], NLDDOneThirdTwoThirdsSection.prototype, "verticalAlignment", void 0);
42237
42583
  NLDDOneThirdTwoThirdsSection = __decorate([customElement("nldd-one-third-two-thirds-section")], NLDDOneThirdTwoThirdsSection);
42238
42584
  //#endregion
42239
42585
  //#region src/components/layout/page-sections/two-thirds-one-third-section/two-thirds-one-third-section.styles.ts
@@ -42273,6 +42619,11 @@ var twoThirdsOneThirdSectionStyles = css`
42273
42619
  display: none;
42274
42620
  }
42275
42621
 
42622
+ :host([data-growing]),
42623
+ :host([grow]) {
42624
+ flex-grow: 1;
42625
+ }
42626
+
42276
42627
  :host([width="full"]) {
42277
42628
  --_two-thirds-one-third-section-max-width: none;
42278
42629
  }
@@ -42360,6 +42711,18 @@ var twoThirdsOneThirdSectionStyles = css`
42360
42711
  }
42361
42712
  }
42362
42713
 
42714
+ :host([vertical-alignment="center"]) .two-thirds-one-third-section__columns {
42715
+ @container (min-width: 769px) {
42716
+ align-items: center;
42717
+ }
42718
+ }
42719
+
42720
+ :host([vertical-alignment="bottom"]) .two-thirds-one-third-section__columns {
42721
+ @container (min-width: 769px) {
42722
+ align-items: flex-end;
42723
+ }
42724
+ }
42725
+
42363
42726
  .two-thirds-one-third-section__left-column {
42364
42727
  min-width: var(--primitives-area-280);
42365
42728
  flex-grow: 2;
@@ -42423,10 +42786,12 @@ function twoThirdsOneThirdSectionTemplate(component) {
42423
42786
  * @attr {'inherit'|'base'|'tinted'} [background] - Surface background ('inherit' default; 'base'/'tinted' paint and cascade a surface).
42424
42787
  * @attr {string} [width] - Body max-width: 'full' removes the constraint so the section spans the full available width. Any CSS length (e.g. '480px') overrides the default max-width.
42425
42788
  * @attr {string} [height] - Minimum section height (any CSS length, e.g. '400px', '100dvh') (mirrors width, which sets the body max-width).
42789
+ * @attr {boolean} grow - Takes the height the page has left, so the footer sits at the bottom of a short page. Without it, nldd-page lets its last section grow.
42426
42790
  * @attr {string} [padding-block] - Block (top and bottom) padding override (token 0-96; '0' strips it).
42427
42791
  * @attr {string} [padding-top] - Top padding override.
42428
42792
  * @attr {string} [padding-bottom] - Bottom padding override.
42429
42793
  * @attr {string} [sm-padding-block] - Responsive block padding (sm/md/lg, also per edge: {sm,md,lg}-padding-{top,bottom}).
42794
+ * @attr {'top'|'center'|'bottom'} [vertical-alignment] - Where the shorter column sits next to the longer one ('top' default). Only where the columns stand side by side; stacked, they follow each other.
42430
42795
  *
42431
42796
  * @slot header - Content above the columns
42432
42797
  * @slot - Left column (2/3), alternative for slot="left"
@@ -42438,6 +42803,7 @@ var _NLDDTwoThirdsOneThirdSection = class NLDDTwoThirdsOneThirdSection extends P
42438
42803
  constructor(..._args) {
42439
42804
  super(..._args);
42440
42805
  this.width = "";
42806
+ this.verticalAlignment = "top";
42441
42807
  }
42442
42808
  updated(changedProperties) {
42443
42809
  super.updated(changedProperties);
@@ -42453,9 +42819,14 @@ var _NLDDTwoThirdsOneThirdSection = class NLDDTwoThirdsOneThirdSection extends P
42453
42819
  };
42454
42820
  var NLDDTwoThirdsOneThirdSection = (_NLDDTwoThirdsOneThirdSection.styles = twoThirdsOneThirdSectionStyles, _NLDDTwoThirdsOneThirdSection);
42455
42821
  __decorate([property({
42456
- type: String,
42457
- reflect: true
42822
+ reflect: true,
42823
+ converter: reflectNonDefault("")
42458
42824
  })], NLDDTwoThirdsOneThirdSection.prototype, "width", void 0);
42825
+ __decorate([property({
42826
+ reflect: true,
42827
+ attribute: "vertical-alignment",
42828
+ converter: reflectNonDefault("top")
42829
+ })], NLDDTwoThirdsOneThirdSection.prototype, "verticalAlignment", void 0);
42459
42830
  NLDDTwoThirdsOneThirdSection = __decorate([customElement("nldd-two-thirds-one-third-section")], NLDDTwoThirdsOneThirdSection);
42460
42831
  //#endregion
42461
42832
  //#region src/components/layout/page-sections/one-half-one-half-section/one-half-one-half-section.styles.ts
@@ -42495,6 +42866,11 @@ var oneHalfOneHalfSectionStyles = css`
42495
42866
  display: none;
42496
42867
  }
42497
42868
 
42869
+ :host([data-growing]),
42870
+ :host([grow]) {
42871
+ flex-grow: 1;
42872
+ }
42873
+
42498
42874
  :host([width="full"]) {
42499
42875
  --_one-half-one-half-section-max-width: none;
42500
42876
  }
@@ -42573,6 +42949,14 @@ var oneHalfOneHalfSectionStyles = css`
42573
42949
  }
42574
42950
  }
42575
42951
 
42952
+ :host([vertical-alignment="center"]) .one-half-one-half-section__columns {
42953
+ align-items: center;
42954
+ }
42955
+
42956
+ :host([vertical-alignment="bottom"]) .one-half-one-half-section__columns {
42957
+ align-items: flex-end;
42958
+ }
42959
+
42576
42960
  .one-half-one-half-section__left-column {
42577
42961
  min-width: var(--primitives-area-280);
42578
42962
  flex-grow: 1;
@@ -42636,10 +43020,12 @@ function oneHalfOneHalfSectionTemplate(component) {
42636
43020
  * @attr {'inherit'|'base'|'tinted'} [background] - Surface background ('inherit' default; 'base'/'tinted' paint and cascade a surface).
42637
43021
  * @attr {string} [width] - Body max-width: 'full' removes the constraint so the section spans the full available width. Any CSS length (e.g. '480px') overrides the default max-width.
42638
43022
  * @attr {string} [height] - Minimum section height (any CSS length, e.g. '400px', '100dvh') (mirrors width, which sets the body max-width).
43023
+ * @attr {boolean} grow - Takes the height the page has left, so the footer sits at the bottom of a short page. Without it, nldd-page lets its last section grow.
42639
43024
  * @attr {string} [padding-block] - Block (top and bottom) padding override (token 0-96; '0' strips it).
42640
43025
  * @attr {string} [padding-top] - Top padding override.
42641
43026
  * @attr {string} [padding-bottom] - Bottom padding override.
42642
43027
  * @attr {string} [sm-padding-block] - Responsive block padding (sm/md/lg, also per edge: {sm,md,lg}-padding-{top,bottom}).
43028
+ * @attr {'top'|'center'|'bottom'} [vertical-alignment] - Where the shorter column sits next to the longer one ('top' default). Only where the columns stand side by side; stacked, they follow each other.
42643
43029
  *
42644
43030
  * @slot header - Content above the columns
42645
43031
  * @slot - Left column (1/2), alternative for slot="left"
@@ -42651,6 +43037,7 @@ var _NLDDOneHalfOneHalfSection = class NLDDOneHalfOneHalfSection extends PageSec
42651
43037
  constructor(..._args) {
42652
43038
  super(..._args);
42653
43039
  this.width = "";
43040
+ this.verticalAlignment = "top";
42654
43041
  }
42655
43042
  updated(changedProperties) {
42656
43043
  super.updated(changedProperties);
@@ -42666,9 +43053,14 @@ var _NLDDOneHalfOneHalfSection = class NLDDOneHalfOneHalfSection extends PageSec
42666
43053
  };
42667
43054
  var NLDDOneHalfOneHalfSection = (_NLDDOneHalfOneHalfSection.styles = oneHalfOneHalfSectionStyles, _NLDDOneHalfOneHalfSection);
42668
43055
  __decorate([property({
42669
- type: String,
42670
- reflect: true
43056
+ reflect: true,
43057
+ converter: reflectNonDefault("")
42671
43058
  })], NLDDOneHalfOneHalfSection.prototype, "width", void 0);
43059
+ __decorate([property({
43060
+ reflect: true,
43061
+ attribute: "vertical-alignment",
43062
+ converter: reflectNonDefault("top")
43063
+ })], NLDDOneHalfOneHalfSection.prototype, "verticalAlignment", void 0);
42672
43064
  NLDDOneHalfOneHalfSection = __decorate([customElement("nldd-one-half-one-half-section")], NLDDOneHalfOneHalfSection);
42673
43065
  //#endregion
42674
43066
  //#region src/components/layout/page-sections/sidebar-section/sidebar-section.styles.ts
@@ -42708,8 +43100,8 @@ var sidebarSectionStyles = css`
42708
43100
  --_sidebar-section-sticky-top: calc(var(--context-inset-top, 0px) + var(--primitives-space-24));
42709
43101
  --_sidebar-section-sticky-bottom: calc(var(--context-inset-bottom, 0px) + var(--primitives-space-24));
42710
43102
  --_sidebar-section-width: var(--primitives-area-320);
42711
- --_sidebar-section-sidebar-box-background-color: var(--semantics-surfaces-tinted-background-color);
42712
- --_sidebar-section-sidebar-box-highlight-border-color: var(--semantics-surfaces-tinted-border-color);
43103
+ --_sidebar-section-sidebar-box-background-color: var(--context-parent-background-color, var(--semantics-surfaces-base-background-color));
43104
+ --_sidebar-section-sidebar-box-border-color: var(--semantics-dividers-color);
42713
43105
 
42714
43106
  display: flex;
42715
43107
  width: 100%;
@@ -42725,14 +43117,14 @@ var sidebarSectionStyles = css`
42725
43117
  --_sidebar-section-max-width: none;
42726
43118
  }
42727
43119
 
42728
- /* # Growth — mirrors simple-section. The host only grows as the last
42729
- (visible) section in an nldd-page; the chain below (block -> body ->
43120
+ /* # Growth — mirrors simple-section. The host only grows when it is the
43121
+ growing section of an nldd-page, or has grow itself; the chain below (block -> body ->
42730
43122
  columns -> main) is unconditional, so whatever height the host gets
42731
43123
  always reaches the main column. An nldd-inline-dialog there (itself
42732
43124
  flex-grow: 1) then fills and centers in the leftover space. */
42733
43125
 
42734
- :host(:last-child),
42735
- :host(.is-last) {
43126
+ :host([data-growing]),
43127
+ :host([grow]) {
42736
43128
  flex-grow: 1;
42737
43129
  }
42738
43130
 
@@ -42827,15 +43219,16 @@ var sidebarSectionStyles = css`
42827
43219
  }
42828
43220
  }
42829
43221
 
42830
- /* # Box — tinted always. Sticky + scrollable only beside the main (wide); when
42831
- stacked it's a plain full-width tinted box above the main, so no sticky (which
42832
- would scroll over the main) and no viewport height cap. */
43222
+ /* # Box — the surface around it, edged by a divider. Sticky + scrollable only
43223
+ beside the main (wide); when stacked it's a plain full-width box above the
43224
+ main, so no sticky (which would scroll over the main) and no viewport
43225
+ height cap. */
42833
43226
 
42834
43227
  .sidebar-section__sidebar-box {
42835
43228
  box-sizing: border-box;
42836
43229
  border-radius: var(--semantics-surfaces-corner-radius);
42837
43230
  background-color: var(--_sidebar-section-sidebar-box-background-color);
42838
- box-shadow: inset 0 0 0 var(--semantics-surfaces-border-width) var(--_sidebar-section-sidebar-box-highlight-border-color);
43231
+ box-shadow: inset 0 0 0 var(--semantics-surfaces-border-width) var(--_sidebar-section-sidebar-box-border-color);
42839
43232
 
42840
43233
  @container (min-width: ${lgMin$4}) {
42841
43234
  position: sticky;
@@ -43465,8 +43858,8 @@ var NLDDSheet = (_NLDDSheet = class NLDDSheet extends LitElement {
43465
43858
  }
43466
43859
  }, _NLDDSheet.styles = sheetStyles, _NLDDSheet);
43467
43860
  __decorate([property({
43468
- type: String,
43469
- reflect: true
43861
+ reflect: true,
43862
+ converter: reflectNonDefault("")
43470
43863
  })], NLDDSheet.prototype, "width", void 0);
43471
43864
  __decorate([property({
43472
43865
  type: String,
@@ -43493,7 +43886,9 @@ NLDDSheet = __decorate([customElement("nldd-sheet")], NLDDSheet);
43493
43886
  * A page section with a left sidebar alongside the main content.
43494
43887
  *
43495
43888
  * - **Wide (section >= 1008px):** two columns. The sidebar is a sticky, scrollable
43496
- * tinted box (max-width 320px) beside the main content. Its sticky top/bottom insets
43889
+ * box (max-width 320px) beside the main content. It takes the surface of the
43890
+ * section around it and is edged by a divider line, so it reads as a block
43891
+ * without drawing the eye away from the main. Its sticky top/bottom insets
43497
43892
  * default to 16px; override with `sticky-top` / `sticky-bottom` so it clears
43498
43893
  * other sticky page elements (e.g. a sticky header).
43499
43894
  * - **Narrow (section < 1008px):** the sidebar collapses behind a sheet (a left panel on
@@ -43521,6 +43916,7 @@ NLDDSheet = __decorate([customElement("nldd-sheet")], NLDDSheet);
43521
43916
  * @element nldd-sidebar-section
43522
43917
  *
43523
43918
  * @attr {string} [width] - Body max-width: 'full' removes the constraint; any CSS length overrides the default.
43919
+ * @attr {boolean} grow - Takes the height the page has left, so the footer sits at the bottom of a short page. Without it, nldd-page lets its last section grow.
43524
43920
  * @attr {string} [sidebar-label] - Accessible name for the sidebar (the aside landmark on lg and the sheet on sm/md). Default 'Zijbalk'.
43525
43921
  * @attr {object} [translations] - Override translation keys (sheet title fallback, dismiss label); unset keys fall back to Dutch.
43526
43922
  * @attr {boolean} [no-collapse] - Opt out of the sheet: a narrow section stacks the sidebar above the main instead of collapsing. `collapsed` then stays false.
@@ -43640,8 +44036,8 @@ var _NLDDSidebarSection = class NLDDSidebarSection extends PageSectionMixin(LitE
43640
44036
  };
43641
44037
  var NLDDSidebarSection = (_NLDDSidebarSection.styles = sidebarSectionStyles, _NLDDSidebarSection);
43642
44038
  __decorate([property({
43643
- type: String,
43644
- reflect: true
44039
+ reflect: true,
44040
+ converter: reflectNonDefault("")
43645
44041
  })], NLDDSidebarSection.prototype, "width", void 0);
43646
44042
  __decorate([property({
43647
44043
  type: String,
@@ -43745,7 +44141,7 @@ function boxTemplate(_component) {
43745
44141
  * helping users understand their relationship at a glance.
43746
44142
  *
43747
44143
  * @element nldd-box
43748
- * @attr {'tinted'|'base'|'critical'} background - Which surface this box draws, named as it is on nldd-app-view, nldd-page, nldd-split-view-pane and nldd-card. It starts tinted where a card starts base: a box is there to stand out from the page, a card to sit on it.
44144
+ * @attr {'tinted'|'base'|'critical'} background - Which surface this box draws, named as it is on nldd-shell, nldd-page, nldd-split-view-pane and nldd-card. It starts tinted where a card starts base: a box is there to stand out from the page, a card to sit on it.
43749
44145
  * - `tinted` (default): a box on a plain page background.
43750
44146
  * - `base`: a box on an already-tinted parent (the border ring gets +2
43751
44147
  * palette steps so it still reads against a card-on-card).
@@ -45599,7 +45995,7 @@ var listItemSegmentStyles = css`
45599
45995
  function template$9(control, href, target, rel, checked, expanded, current, disabled, accessibleLabel, actionTabindex, popupType, popovertarget, popoverTargetElement, popoverTargetAction) {
45600
45996
  const content = html`<slot></slot>`;
45601
45997
  const ariaExpanded = expanded === void 0 ? popupType ? "false" : nothing : String(expanded);
45602
- const ariaCurrent = current ? "page" : nothing;
45998
+ const ariaCurrent = current ?? nothing;
45603
45999
  const label = accessibleLabel || nothing;
45604
46000
  if (control === "link") return html`<a class="list-item-segment"
45605
46001
  href=${href ?? nothing}
@@ -45641,6 +46037,7 @@ var _NLDDListItemSegment = class NLDDListItemSegment extends LitElement {
45641
46037
  this.popoverTargetElement = null;
45642
46038
  this.popoverTargetAction = "toggle";
45643
46039
  this.current = false;
46040
+ this.currentType = "page";
45644
46041
  this.disabled = false;
45645
46042
  this._parentType = "list";
45646
46043
  this._handleClick = (e) => {
@@ -45729,7 +46126,7 @@ var _NLDDListItemSegment = class NLDDListItemSegment extends LitElement {
45729
46126
  this.classList.toggle("is-expanded", expanded === true);
45730
46127
  }
45731
46128
  render() {
45732
- return template$9(this._controlType, this.href, this.target, this.rel, this.checked, this.disclosure ? this._rowExpanded : this.expanded, this.current, this.disabled, this.accessibleLabel, this._tabbable === void 0 ? void 0 : this._tabbable ? "0" : "-1", this.popupType, this.popovertarget, this.popoverTargetElement, this.popoverTargetAction);
46129
+ return template$9(this._controlType, this.href, this.target, this.rel, this.checked, this.disclosure ? this._rowExpanded : this.expanded, this.current ? this.currentType : void 0, this.disabled, this.accessibleLabel, this._tabbable === void 0 ? void 0 : this._tabbable ? "0" : "-1", this.popupType, this.popovertarget, this.popoverTargetElement, this.popoverTargetAction);
45733
46130
  }
45734
46131
  };
45735
46132
  var NLDDListItemSegment = (_NLDDListItemSegment.styles = [listItemSegmentStyles], _NLDDListItemSegment);
@@ -45772,6 +46169,11 @@ __decorate([property({
45772
46169
  type: Boolean,
45773
46170
  reflect: true
45774
46171
  })], NLDDListItemSegment.prototype, "current", void 0);
46172
+ __decorate([property({
46173
+ reflect: true,
46174
+ attribute: "current-type",
46175
+ converter: reflectNonDefault("page")
46176
+ })], NLDDListItemSegment.prototype, "currentType", void 0);
45775
46177
  __decorate([property({
45776
46178
  type: Boolean,
45777
46179
  reflect: true
@@ -46372,6 +46774,7 @@ var titleCellStyles = css`
46372
46774
  color: var(--_title-cell-secondary-color);
46373
46775
  font: var(--primitives-font-body-xs-regular-tight);
46374
46776
  overflow-wrap: anywhere;
46777
+ text-wrap: pretty;
46375
46778
  }
46376
46779
 
46377
46780
  /* Balanced, not pretty: a title is a handful of words, and evening out the
@@ -46402,6 +46805,7 @@ var titleCellStyles = css`
46402
46805
  color: var(--_title-cell-secondary-color);
46403
46806
  font: var(--primitives-font-body-sm-regular-tight);
46404
46807
  overflow-wrap: anywhere;
46808
+ text-wrap: pretty;
46405
46809
  }
46406
46810
  `;
46407
46811
  //#endregion
@@ -47776,6 +48180,16 @@ var menuBarItemStyles = css`
47776
48180
  flex-shrink: 0;
47777
48181
  }
47778
48182
 
48183
+ .menu-bar-item__icon[hidden] {
48184
+ display: none;
48185
+ }
48186
+
48187
+ ::slotted([slot="icon"]) {
48188
+ display: flex;
48189
+ width: 100%;
48190
+ height: 100%;
48191
+ }
48192
+
47779
48193
  /* ## Disclosure icon */
47780
48194
 
47781
48195
  .menu-bar-item__disclosure-icon {
@@ -47821,12 +48235,12 @@ var menuBarItemStyles = css`
47821
48235
  /* # Icon-only */
47822
48236
 
47823
48237
  :host([icon-only]) .menu-bar-item,
47824
- :host([content-priority="icon"][compact][icon]:not([icon=""])) .menu-bar-item {
48238
+ :host([content-priority="icon"][compact]:is([icon]:not([icon=""]), [data-has-icon])) .menu-bar-item {
47825
48239
  padding: var(--primitives-space-8);
47826
48240
  }
47827
48241
 
47828
48242
  :host([icon-only]) .menu-bar-item__text,
47829
- :host([content-priority="icon"][compact][icon]:not([icon=""])) .menu-bar-item__text {
48243
+ :host([content-priority="icon"][compact]:is([icon]:not([icon=""]), [data-has-icon])) .menu-bar-item__text {
47830
48244
  position: absolute;
47831
48245
  margin: -1px;
47832
48246
  border: 0;
@@ -47852,6 +48266,13 @@ function template$4(component) {
47852
48266
  const ariaCurrent = component.current ? component.currentType : nothing;
47853
48267
  const ariaHaspopup = component.expandable ? "menu" : component.haspopup || nothing;
47854
48268
  const ariaExpanded = component.expandable || component.haspopup ? String(component.expanded) : nothing;
48269
+ const icon = html`
48270
+ <span class="menu-bar-item__icon" ?hidden=${!component.icon && !component._hasSlottedIcon}>
48271
+ <slot name="icon" @slotchange=${component._onIconSlotChange}>
48272
+ ${component.icon ? html`<nldd-icon icon=${component.icon}></nldd-icon>` : nothing}
48273
+ </slot>
48274
+ </span>
48275
+ `;
47855
48276
  if (isLink) return html`
47856
48277
  <a class="menu-bar-item"
47857
48278
  href=${safeHref}
@@ -47862,11 +48283,7 @@ function template$4(component) {
47862
48283
  aria-haspopup=${ariaHaspopup}
47863
48284
  aria-expanded=${ariaExpanded}
47864
48285
  >
47865
- ${component.icon ? html`
47866
- <span class="menu-bar-item__icon">
47867
- <nldd-icon icon=${component.icon}></nldd-icon>
47868
- </span>
47869
- ` : nothing}
48286
+ ${icon}
47870
48287
  <span class="menu-bar-item__text">
47871
48288
  ${component.text}
47872
48289
  </span>
@@ -47889,11 +48306,7 @@ function template$4(component) {
47889
48306
  .popoverTargetElement=${component.popoverTargetElement}
47890
48307
  .popoverTargetAction=${component.popoverTargetAction}
47891
48308
  >
47892
- ${component.icon ? html`
47893
- <span class="menu-bar-item__icon">
47894
- <nldd-icon icon=${component.icon}></nldd-icon>
47895
- </span>
47896
- ` : nothing}
48309
+ ${icon}
47897
48310
  <span class="menu-bar-item__text">
47898
48311
  ${component.text}
47899
48312
  </span>
@@ -47934,6 +48347,7 @@ function template$4(component) {
47934
48347
  *
47935
48348
  * @fires select - On a click on a non-expandable button item (bubbles, composed)
47936
48349
  *
48350
+ * @slot icon - Takes the place of the icon: an `nldd-avatar` for the person who is signed in, for instance. It gets the size of an icon, and follows `content-priority` and `icon-only` as the icon does. Wins over `icon`.
47937
48351
  * @slot - Content of the expandable popover. Wrap items in an `<nldd-menu>` so
47938
48352
  * this component does not have to duplicate the menu API (variant,
47939
48353
  * accessible-label, translations, filterFn and so on). Event listeners on
@@ -47961,6 +48375,11 @@ var _NLDDMenuBarItem = class NLDDMenuBarItem extends LitElement {
47961
48375
  this._menuOpen = false;
47962
48376
  this._pointerdownWhileMenuOpen = false;
47963
48377
  this._menuToggleHandler = null;
48378
+ this._hasSlottedIcon = false;
48379
+ this._onIconSlotChange = (e) => {
48380
+ this._hasSlottedIcon = e.target.assignedElements().length > 0;
48381
+ this.toggleAttribute("data-has-icon", this._hasSlottedIcon);
48382
+ };
47964
48383
  this._onSlotChange = () => {
47965
48384
  this._wireMenu();
47966
48385
  };
@@ -48094,6 +48513,7 @@ __decorate([property({
48094
48513
  })], NLDDMenuBarItem.prototype, "expanded", void 0);
48095
48514
  __decorate([property({ attribute: false })], NLDDMenuBarItem.prototype, "popoverTargetElement", void 0);
48096
48515
  __decorate([property({ attribute: false })], NLDDMenuBarItem.prototype, "popoverTargetAction", void 0);
48516
+ __decorate([state()], NLDDMenuBarItem.prototype, "_hasSlottedIcon", void 0);
48097
48517
  NLDDMenuBarItem = __decorate([customElement("nldd-menu-bar-item")], NLDDMenuBarItem);
48098
48518
  //#endregion
48099
48519
  //#region src/components/navigation/menu-bar/menu-bar.ts
@@ -49647,7 +50067,7 @@ var _NLDDTopNavigationBar = class NLDDTopNavigationBar extends withTranslations(
49647
50067
  Promise.resolve().then(() => list_item_exports),
49648
50068
  Promise.resolve().then(() => text_cell_exports),
49649
50069
  Promise.resolve().then(() => icon_cell_exports),
49650
- import("./icon-DQHT2C7z.js").then((n) => n.n)
50070
+ import("./icon-D_ZGezHx.js").then((n) => n.n)
49651
50071
  ]);
49652
50072
  }
49653
50073
  _createGlobalMenuSheet() {
@@ -56588,6 +57008,13 @@ function statusBarTemplate(component) {
56588
57008
  * action per bar at most; several actions, or links in running text, belong in
56589
57009
  * nldd-banner.
56590
57010
  *
57011
+ * ## Placement
57012
+ * The bar is the first thing on the screen: above nldd-top-navigation-bar or
57013
+ * nldd-top-title-bar, across the whole app, also when a split view shows
57014
+ * several panes. It reports the state of the service, not of one page, so it
57015
+ * never sits inside the content or below a top bar. Below a top bar it says so
57016
+ * in development.
57017
+ *
56591
57018
  * ## ARIA
56592
57019
  * role and aria-live are set automatically from the variant:
56593
57020
  * - critical → role="alert" (implies aria-live="assertive"; interrupts the screen reader)
@@ -56620,6 +57047,11 @@ var _NLDDStatusBar = class NLDDStatusBar extends LitElement {
56620
57047
  super.connectedCallback();
56621
57048
  this._applyAriaForVariant(this.variant);
56622
57049
  }
57050
+ firstUpdated() {}
57051
+ /** DEV-only: warns when a top bar comes before the status bar. Top bars in an overlay are left out, since a sheet or dialog has its own. */
57052
+ _checkPlacement() {
57053
+ if ([...this.getRootNode().querySelectorAll("nldd-top-navigation-bar, nldd-top-title-bar")].some((bar) => !bar.closest("nldd-sheet, nldd-modal-dialog, nldd-popover, dialog") && (bar.compareDocumentPosition(this) & Node.DOCUMENT_POSITION_FOLLOWING) !== 0 && !bar.contains(this))) console.warn("<nldd-status-bar>: The status bar sits below a top bar. It belongs above it, as the first thing on the screen.", this);
57054
+ }
56623
57055
  updated(changed) {
56624
57056
  if (changed.has("variant")) this._applyAriaForVariant(this.variant);
56625
57057
  }
@@ -57514,4 +57946,4 @@ __decorate([property({
57514
57946
  })], NLDDJustInTimeEducation.prototype, "noArrow", void 0);
57515
57947
  NLDDJustInTimeEducation = _NLDDJustInTimeEducation = __decorate([customElement("nldd-just-in-time-education")], NLDDJustInTimeEducation);
57516
57948
  //#endregion
57517
- export { NLDDActivityIndicator, NLDDAppView, NLDDAvatar, NLDDAvatarGroup, NLDDBadge, NLDDBanner, NLDDBarSplitView, NLDDBlockquote, NLDDBox, NLDDBreadcrumbs, NLDDBreadcrumbsItem, NLDDButton, NLDDButtonBar, NLDDButtonGroup, NLDDCard, NLDDCell, NLDDCheckbox, NLDDCheckboxField, NLDDCodeEditor, NLDDCodeViewer, NLDDCollection, NLDDComboBox, NLDDContainer, NLDDDateField, NLDDDatePicker, NLDDDescriptionCell, NLDDDivider, NLDDDocumentTabBar, NLDDDragHandleCell, NLDDDropdown, NLDDFileField, NLDDForm, NLDDFormActions, NLDDFormField, NLDDFormSection, NLDDFullBleedSection, NLDDHero, NLDDIcon, NLDDIconButton, NLDDIconCell, NLDDIdentity, NLDDImage, NLDDInlineDialog, NLDDJustInTimeEducation, NLDDKeyboardShortcut, NLDDLink, NLDDList, NLDDListItem, NLDDListItemSegment, NLDDMenu, NLDDMenuBar, NLDDMenuBarItem, NLDDModalDialog, NLDDMultiLineTextField, NLDDNavigationSplitView, NLDDNotification, NLDDNumberField, NLDDOneHalfOneHalfSection, NLDDOneThirdTwoThirdsSection, NLDDPage, NLDDPageFooter, NLDDPageFooterLegalBar, NLDDPageFooterLegalBarItem, NLDDPagination, NLDDPasswordField, NLDDPopover, NLDDProgressBar, NLDDProgressBarSegmentIndicator, NLDDProgressCircle, NLDDProgressCircleSegmentIndicator, NLDDRadioButton, NLDDRadioButtonField, NLDDRadioButtonGroup, NLDDRichText, NLDDSearchField, NLDDSegmentedControl, NLDDSheet, NLDDSideBySideSplitView, NLDDSidebarSection, NLDDSimpleSection, NLDDSkipLink, NLDDSpacer, NLDDSpacerCell, NLDDSplitButton, NLDDSplitViewDivider, NLDDSplitViewPane, NLDDStackedSplitView, NLDDStatusBar, NLDDStepBar, NLDDStepBarItem, NLDDStepCell, NLDDStepper, NLDDSwitch, NLDDSwitchField, NLDDTabBar, NLDDTable, NLDDTableRow, NLDDTag, NLDDText, NLDDTextCell, NLDDTextEditor, NLDDTextField, NLDDTimeField, NLDDTimePicker, NLDDTitle, NLDDTitleCell, NLDDToggleButton, NLDDToggleButtonGroup, NLDDToken, NLDDTokenField, NLDDToolbar, NLDDTooltip, NLDDTopNavigationBar, NLDDTopTitleBar, NLDDTwoThirdsOneThirdSection, NLDDValidationList, NLDDWindow, setTranslations };
57949
+ export { NLDDActivityIndicator, NLDDAvatar, NLDDAvatarGroup, NLDDBadge, NLDDBanner, NLDDBarSplitView, NLDDBlockquote, NLDDBox, NLDDBreadcrumbs, NLDDBreadcrumbsItem, NLDDButton, NLDDButtonBar, NLDDButtonGroup, NLDDCard, NLDDCell, NLDDCheckbox, NLDDCheckboxField, NLDDCodeEditor, NLDDCodeViewer, NLDDCollection, NLDDComboBox, NLDDContainer, NLDDDateField, NLDDDatePicker, NLDDDescriptionCell, NLDDDivider, NLDDDocumentTabBar, NLDDDragHandleCell, NLDDDropdown, NLDDFileField, NLDDForm, NLDDFormActions, NLDDFormField, NLDDFormSection, NLDDFullBleedSection, NLDDHero, NLDDIcon, NLDDIconButton, NLDDIconCell, NLDDIdentity, NLDDImage, NLDDInlineDialog, NLDDJustInTimeEducation, NLDDKeyboardShortcut, NLDDLink, NLDDList, NLDDListItem, NLDDListItemSegment, NLDDMenu, NLDDMenuBar, NLDDMenuBarItem, NLDDModalDialog, NLDDMultiLineTextField, NLDDNavigationSplitView, NLDDNotification, NLDDNumberField, NLDDOneHalfOneHalfSection, NLDDOneThirdTwoThirdsSection, NLDDPage, NLDDPageFooter, NLDDPageFooterLegalBar, NLDDPageFooterLegalBarItem, NLDDPagination, NLDDPasswordField, NLDDPopover, NLDDProgressBar, NLDDProgressBarSegmentIndicator, NLDDProgressCircle, NLDDProgressCircleSegmentIndicator, NLDDRadioButton, NLDDRadioButtonField, NLDDRadioButtonGroup, NLDDRichText, NLDDSearchField, NLDDSegmentedControl, NLDDSheet, NLDDShell, NLDDSideBySideSplitView, NLDDSidebarSection, NLDDSimpleSection, NLDDSkipLink, NLDDSpacer, NLDDSpacerCell, NLDDSplitButton, NLDDSplitViewDivider, NLDDSplitViewPane, NLDDStackedSplitView, NLDDStatusBar, NLDDStepBar, NLDDStepBarItem, NLDDStepCell, NLDDStepper, NLDDSwitch, NLDDSwitchField, NLDDTabBar, NLDDTable, NLDDTableRow, NLDDTag, NLDDText, NLDDTextCell, NLDDTextEditor, NLDDTextField, NLDDTimeField, NLDDTimePicker, NLDDTitle, NLDDTitleCell, NLDDToggleButton, NLDDToggleButtonGroup, NLDDToken, NLDDTokenField, NLDDToolbar, NLDDTooltip, NLDDTopNavigationBar, NLDDTopTitleBar, NLDDTwoThirdsOneThirdSection, NLDDValidationList, NLDDWindow, setTranslations };