srcdev-nuxt-components 9.4.11 → 9.5.0

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
Files changed (623) hide show
  1. package/.claude/skills/component-aria-landmark.md +1 -1
  2. package/.claude/skills/component-dynamic-slots.md +0 -1
  3. package/.claude/skills/component-export-types.md +3 -3
  4. package/.claude/skills/component-inline-action-button.md +7 -7
  5. package/.claude/skills/component-local-style-override.md +134 -50
  6. package/.claude/skills/component-naming.md +107 -0
  7. package/.claude/skills/components/action-menu.md +18 -14
  8. package/.claude/skills/components/alert-content.md +110 -0
  9. package/.claude/skills/components/alert-mask-core.md +15 -1
  10. package/.claude/skills/components/alert-masked-content.md +95 -0
  11. package/.claude/skills/components/auto-grid.md +21 -13
  12. package/.claude/skills/components/canvas-switcher.md +3 -3
  13. package/.claude/skills/components/capture-qr-code.md +19 -9
  14. package/.claude/skills/components/carousel-flip.md +3 -3
  15. package/.claude/skills/components/container-glow.md +2 -2
  16. package/.claude/skills/components/content-docs.md +9 -5
  17. package/.claude/skills/components/cookie-consent-banner.md +16 -17
  18. package/.claude/skills/components/dashboard-quad-grid.md +4 -4
  19. package/.claude/skills/components/decode-qr-code.md +15 -9
  20. package/.claude/skills/components/display-avatar.md +16 -31
  21. package/.claude/skills/components/display-chip.md +15 -10
  22. package/.claude/skills/components/display-dialog.md +3 -1
  23. package/.claude/skills/components/display-pill.md +17 -75
  24. package/.claude/skills/components/display-prompt.md +11 -19
  25. package/.claude/skills/components/display-qr-code.md +5 -0
  26. package/.claude/skills/components/display-theme-switch.md +7 -6
  27. package/.claude/skills/components/display-toast.md +5 -6
  28. package/.claude/skills/components/entry-animation.md +2 -5
  29. package/.claude/skills/components/eyebrow-text.md +6 -4
  30. package/.claude/skills/components/form-field.md +79 -0
  31. package/.claude/skills/components/form-fieldset.md +75 -0
  32. package/.claude/skills/components/form-wrapper.md +71 -0
  33. package/.claude/skills/components/glass-panel.md +60 -51
  34. package/.claude/skills/components/grid-stack.md +8 -2
  35. package/.claude/skills/components/header-block.md +1 -1
  36. package/.claude/skills/components/hero-text.md +8 -6
  37. package/.claude/skills/components/input-button.md +72 -0
  38. package/.claude/skills/components/input-checkbox-radio.md +149 -0
  39. package/.claude/skills/components/input-checkbox.md +148 -0
  40. package/.claude/skills/components/input-description.md +102 -0
  41. package/.claude/skills/components/input-error.md +105 -0
  42. package/.claude/skills/components/input-label.md +119 -0
  43. package/.claude/skills/components/{input-number-core.md → input-number.md} +41 -36
  44. package/.claude/skills/components/input-radio.md +95 -0
  45. package/.claude/skills/components/input-range-core.md +4 -4
  46. package/.claude/skills/components/input-select-core.md +1 -1
  47. package/.claude/skills/components/input-text-core.md +8 -6
  48. package/.claude/skills/components/input-textarea-core.md +4 -4
  49. package/.claude/skills/components/layout-grid-by-cols.md +31 -43
  50. package/.claude/skills/components/link-text.md +2 -2
  51. package/.claude/skills/components/opening-hours.md +116 -0
  52. package/.claude/skills/components/page-hero-highlights.md +35 -35
  53. package/.claude/skills/components/page-row.md +1 -1
  54. package/.claude/skills/components/pending-effect.md +63 -0
  55. package/.claude/skills/components/price-list.md +72 -0
  56. package/.claude/skills/components/pricing-card.md +3 -3
  57. package/.claude/skills/components/profile-section.md +6 -4
  58. package/.claude/skills/components/samaritan-prompt.md +140 -0
  59. package/.claude/skills/components/scroll-reveal-frame.md +21 -20
  60. package/.claude/skills/components/scroll-reveal-image.md +31 -21
  61. package/.claude/skills/components/service-detail.md +2 -2
  62. package/.claude/skills/components/services-card-grid.md +5 -4
  63. package/.claude/skills/components/services-card.md +12 -10
  64. package/.claude/skills/components/site-navigation.md +20 -6
  65. package/.claude/skills/components/slider-gallery.md +88 -0
  66. package/.claude/skills/components/social-icons-list.md +12 -6
  67. package/.claude/skills/components/tab-navigation.md +1 -1
  68. package/.claude/skills/components/text-block.md +68 -0
  69. package/.claude/skills/components/toggle-switch-core.md +3 -3
  70. package/.claude/skills/components/triple-toggle-switch.md +85 -0
  71. package/.claude/skills/composable-zod-validation.md +1 -1
  72. package/.claude/skills/consumer-styles-structure.md +153 -0
  73. package/.claude/skills/icon-sets.md +3 -3
  74. package/.claude/skills/icon-sizing.md +66 -0
  75. package/.claude/skills/index.md +35 -16
  76. package/.claude/skills/new-app-scaffold.md +45 -7
  77. package/.claude/skills/pull-request-description.md +1 -0
  78. package/.claude/skills/storybook-add-story.md +53 -5
  79. package/.claude/skills/testing-add-playwright.md +1 -1
  80. package/.claude/skills/theming-colour-ramps.md +25 -3
  81. package/.claude/skills/theming-component-token-pattern.md +16 -16
  82. package/.claude/skills/theming-override-default.md +7 -0
  83. package/.claude/skills/theming-partial-override.md +1 -1
  84. package/.claude/skills/theming-typography-tokens.md +1 -1
  85. package/.claude/skills/vercel-node-version.md +1 -1
  86. package/.vscode/srcdev-component-action-menu.code-snippets +42 -0
  87. package/.vscode/srcdev-component-alert-content.code-snippets +36 -0
  88. package/.vscode/srcdev-component-alert-masked-content.code-snippets +35 -0
  89. package/.vscode/srcdev-component-auto-grid.code-snippets +39 -0
  90. package/.vscode/srcdev-component-capture-decode-qr-code.code-snippets +28 -0
  91. package/.vscode/srcdev-component-content-docs.code-snippets +4 -4
  92. package/.vscode/srcdev-component-cookie-consent-banner.code-snippets +33 -0
  93. package/.vscode/srcdev-component-display-avatar.code-snippets +28 -0
  94. package/.vscode/srcdev-component-display-chip.code-snippets +27 -0
  95. package/.vscode/srcdev-component-display-pill.code-snippets +38 -0
  96. package/.vscode/srcdev-component-display-prompt.code-snippets +10 -54
  97. package/.vscode/srcdev-component-display-qr-code.code-snippets +22 -0
  98. package/.vscode/srcdev-component-eyebrow-text.code-snippets +19 -0
  99. package/.vscode/srcdev-component-form-field.code-snippets +25 -0
  100. package/.vscode/srcdev-component-form-fieldset.code-snippets +36 -0
  101. package/.vscode/srcdev-component-form-wrapper.code-snippets +30 -0
  102. package/.vscode/srcdev-component-glass-panel.code-snippets +38 -0
  103. package/.vscode/srcdev-component-grid-stack.code-snippets +49 -0
  104. package/.vscode/srcdev-component-input-button.code-snippets +27 -0
  105. package/.vscode/srcdev-component-input-checkbox-radio.code-snippets +60 -0
  106. package/.vscode/srcdev-component-input-checkbox.code-snippets +48 -0
  107. package/.vscode/srcdev-component-input-description.code-snippets +44 -0
  108. package/.vscode/srcdev-component-input-error.code-snippets +30 -0
  109. package/.vscode/srcdev-component-input-label.code-snippets +39 -0
  110. package/.vscode/srcdev-component-input-number.code-snippets +11 -11
  111. package/.vscode/srcdev-component-input-radio.code-snippets +58 -0
  112. package/.vscode/srcdev-component-layout-grid-by-cols.code-snippets +46 -0
  113. package/.vscode/srcdev-component-link-text.code-snippets +30 -0
  114. package/.vscode/srcdev-component-opening-hours.code-snippets +40 -0
  115. package/.vscode/srcdev-component-page-hero-highlights.code-snippets +37 -0
  116. package/.vscode/srcdev-component-page-row.code-snippets +47 -0
  117. package/.vscode/srcdev-component-pending-effect.code-snippets +26 -0
  118. package/.vscode/srcdev-component-price-list.code-snippets +37 -0
  119. package/.vscode/srcdev-component-pricing-card.code-snippets +2 -2
  120. package/.vscode/srcdev-component-profile-section.code-snippets +36 -0
  121. package/.vscode/srcdev-component-samaritan-prompt.code-snippets +60 -0
  122. package/.vscode/srcdev-component-scroll-reveal-frame.code-snippets +36 -0
  123. package/.vscode/srcdev-component-scroll-reveal-image.code-snippets +46 -0
  124. package/.vscode/srcdev-component-services-card.code-snippets +4 -4
  125. package/.vscode/srcdev-component-services-grids.code-snippets +36 -0
  126. package/.vscode/srcdev-component-site-navigation.code-snippets +26 -18
  127. package/.vscode/srcdev-component-slider-gallery.code-snippets +9 -0
  128. package/.vscode/srcdev-component-social-icons-list.code-snippets +24 -0
  129. package/.vscode/srcdev-component-stepper-list.code-snippets +39 -0
  130. package/.vscode/srcdev-component-text-block.code-snippets +31 -0
  131. package/.vscode/srcdev-component-triple-toggle-switch.code-snippets +30 -0
  132. package/README.md +2 -2
  133. package/app/app.config.ts +10 -0
  134. package/app/assets/styles/setup/02.colours/_orange.css +11 -11
  135. package/app/assets/styles/setup/02.colours/_theme-params.css +2 -2
  136. package/app/assets/styles/setup/03.theming/_default.css +1 -22
  137. package/app/assets/styles/setup/03.theming/_theme-slots.css +1 -1
  138. package/app/assets/styles/setup/03.theming/_warning.css +8 -10
  139. package/app/assets/styles/setup/04.elements/forms/02.typography.css +0 -14
  140. package/app/assets/styles/setup/04.elements/forms/06.button-geometry.css +1 -1
  141. package/app/assets/styles/setup/index.css +1 -1
  142. package/app/components/01.atoms/alert-mask/AlertMaskCore.vue +23 -5
  143. package/app/components/01.atoms/alert-mask/CONSUMER-STYLING.md +23 -5
  144. package/app/components/01.atoms/alert-mask/stories/AlertMaskCore.stories.ts +45 -19
  145. package/app/components/01.atoms/alert-mask/tests/AlertMaskCore.spec.ts +35 -1
  146. package/app/components/01.atoms/animations/animated-svg-text/CONSUMER-STYLING.md +13 -0
  147. package/app/components/01.atoms/animations/clip-element/CONSUMER-STYLING.md +13 -0
  148. package/app/components/01.atoms/animations/clip-element/ClipElement.vue +2 -2
  149. package/app/components/01.atoms/animations/container-glow/CONSUMER-STYLING.md +26 -5
  150. package/app/components/01.atoms/animations/entry/.nuxt/app.config.mjs +21 -0
  151. package/app/components/01.atoms/animations/entry/.nuxt/components.d.ts +66 -0
  152. package/app/components/01.atoms/animations/entry/.nuxt/imports.d.ts +30 -0
  153. package/app/components/01.atoms/animations/entry/.nuxt/manifest/meta/test.json +1 -0
  154. package/app/components/01.atoms/animations/entry/.nuxt/types/app.config.d.ts +35 -0
  155. package/app/components/01.atoms/animations/entry/.nuxt/types/build.d.ts +23 -0
  156. package/app/components/01.atoms/animations/entry/.nuxt/types/builder-env.d.ts +1 -0
  157. package/app/components/01.atoms/animations/entry/.nuxt/types/components.d.ts +71 -0
  158. package/app/components/01.atoms/animations/entry/.nuxt/types/imports.d.ts +386 -0
  159. package/app/components/01.atoms/animations/entry/.nuxt/types/middleware.d.ts +11 -0
  160. package/app/components/01.atoms/animations/entry/.nuxt/types/modules.d.ts +79 -0
  161. package/app/components/01.atoms/animations/entry/.nuxt/types/nitro-layouts.d.ts +17 -0
  162. package/app/components/01.atoms/animations/entry/.nuxt/types/nitro-nuxt.d.ts +64 -0
  163. package/app/components/01.atoms/animations/entry/.nuxt/types/plugins.d.ts +29 -0
  164. package/app/components/01.atoms/animations/entry/.nuxt/types/runtime-config.d.ts +32 -0
  165. package/app/components/01.atoms/animations/entry/.nuxt/types/shared-imports.d.ts +10 -0
  166. package/app/components/01.atoms/animations/entry/.nuxt/types/vue-shim.d.ts +0 -0
  167. package/app/components/01.atoms/animations/entry/.nuxtrc +1 -0
  168. package/app/components/01.atoms/animations/entry/CONSUMER-STYLING.md +65 -0
  169. package/app/components/01.atoms/animations/entry/EntryAnimation.vue +6 -5
  170. package/app/components/01.atoms/animations/entry/node_modules/.cache/nuxt/chrome-workspace.json +1 -0
  171. package/app/components/01.atoms/animations/entry/node_modules/.cache/vite/client/vitest/da39a3ee5e6b4b0d3255bfef95601890afd80709/results.json +1 -0
  172. package/app/components/01.atoms/animations/entry/stories/EntryAnimation.stories.ts +1 -1
  173. package/app/components/01.atoms/animations/entry/tests/EntryAnimation.spec.ts +25 -0
  174. package/app/components/01.atoms/animations/glowing-border/CONSUMER-STYLING.md +24 -5
  175. package/app/components/01.atoms/animations/marquee-scroller/CONSUMER-STYLING.md +20 -0
  176. package/app/components/01.atoms/animations/rotating-carousel-image/CONSUMER-STYLING.md +17 -0
  177. package/app/components/01.atoms/animations/scroll-reveal-frame/CONSUMER-STYLING.md +77 -0
  178. package/app/components/01.atoms/animations/scroll-reveal-frame/ScrollRevealFrame.vue +37 -78
  179. package/app/components/01.atoms/animations/scroll-reveal-frame/stories/ScrollRevealFrame.stories.ts +48 -0
  180. package/app/components/01.atoms/animations/scroll-reveal-frame/tests/ScrollRevealFrame.spec.ts +40 -33
  181. package/app/components/01.atoms/animations/scroll-reveal-frame/tests/__snapshots__/ScrollRevealFrame.spec.ts.snap +4 -4
  182. package/app/components/01.atoms/animations/scroll-reveal-image/CONSUMER-STYLING.md +74 -0
  183. package/app/components/01.atoms/animations/scroll-reveal-image/ScrollRevealImage.vue +14 -44
  184. package/app/components/01.atoms/animations/scroll-reveal-image/stories/ScrollRevealImage.stories.ts +50 -1
  185. package/app/components/01.atoms/animations/scroll-reveal-image/tests/ScrollRevealImage.spec.ts +27 -20
  186. package/app/components/01.atoms/animations/scroll-reveal-image/tests/__snapshots__/ScrollRevealImage.spec.ts.snap +4 -4
  187. package/app/components/01.atoms/animations/section-parallax/CONSUMER-STYLING.md +21 -4
  188. package/app/components/01.atoms/animations/view-timeline/CONSUMER-STYLING.md +25 -0
  189. package/app/components/01.atoms/banner-video/CONSUMER-STYLING.md +12 -5
  190. package/app/components/01.atoms/canvas-switcher/CONSUMER-STYLING.md +20 -7
  191. package/app/components/01.atoms/canvas-switcher/CanvasSwitcher.vue +12 -7
  192. package/app/components/01.atoms/card/CONSUMER-STYLING.md +47 -42
  193. package/app/components/01.atoms/card/CardCore.vue +7 -17
  194. package/app/components/01.atoms/clipped-panel/CONSUMER-STYLING.md +13 -0
  195. package/app/components/01.atoms/content-wrappers/docs-pages/CONSUMER-STYLING.md +127 -0
  196. package/app/components/01.atoms/content-wrappers/docs-pages/ContentDocs.vue +44 -77
  197. package/app/components/01.atoms/content-wrappers/docs-pages/stories/ContentDocs.stories.ts +3 -3
  198. package/app/components/01.atoms/content-wrappers/layout-grid/dashboard-quad-grid/CONSUMER-STYLING.md +14 -1
  199. package/app/components/01.atoms/content-wrappers/layout-grid/dashboard-quad-grid/stories/DashboardQuadGrid.stories.ts +2 -0
  200. package/app/components/01.atoms/content-wrappers/layout-grid/dashboard-stats-grid/CONSUMER-STYLING.md +13 -0
  201. package/app/components/01.atoms/content-wrappers/layout-grid/dashboard-stats-grid/stories/DashboardStatsGrid.stories.ts +2 -0
  202. package/app/components/01.atoms/content-wrappers/layout-grid/layout-grid-by-cols/CONSUMER-STYLING.md +72 -0
  203. package/app/components/01.atoms/content-wrappers/layout-grid/layout-grid-by-cols/LayoutGridByCols.vue +26 -25
  204. package/app/components/01.atoms/content-wrappers/layout-grid/layout-grid-by-cols/stories/LayoutGridByCols.stories.ts +91 -107
  205. package/app/components/01.atoms/content-wrappers/layout-grid/layout-grid-by-cols/tests/LayoutGridByCols.spec.ts +50 -15
  206. package/app/components/01.atoms/content-wrappers/layout-grid/layout-grid-by-cols/tests/__snapshots__/LayoutGridByCols.spec.ts.snap +5 -5
  207. package/app/components/01.atoms/display-banner/CONSUMER-STYLING.md +13 -0
  208. package/app/components/01.atoms/display-dialog/CONSUMER-STYLING.md +82 -54
  209. package/app/components/01.atoms/display-dialog/DisplayDialog.vue +38 -45
  210. package/app/components/01.atoms/display-dialog/stories/DisplayDialog.stories.ts +25 -0
  211. package/app/components/01.atoms/display-dialog/tests/DisplayDialog.spec.ts +21 -0
  212. package/app/components/01.atoms/display-pill/CONSUMER-STYLING.md +112 -0
  213. package/app/components/01.atoms/display-pill/DisplayPill.vue +88 -50
  214. package/app/components/01.atoms/display-pill/stories/DisplayPill.stories.ts +56 -3
  215. package/app/components/01.atoms/display-pill/tests/DisplayPill.spec.ts +104 -4
  216. package/app/components/01.atoms/display-pill/tests/__snapshots__/DisplayPill.spec.ts.snap +3 -3
  217. package/app/components/01.atoms/display-tooltip/CONSUMER-STYLING.md +22 -2
  218. package/app/components/01.atoms/display-tooltip/DisplayTooltip.vue +18 -26
  219. package/app/components/01.atoms/glass-panel/CONSUMER-STYLING.md +91 -0
  220. package/app/components/01.atoms/glass-panel/GlassPanel.vue +34 -30
  221. package/app/components/01.atoms/glass-panel/stories/GlassPanel.stories.ts +121 -0
  222. package/app/components/01.atoms/glass-panel/tests/GlassPanel.spec.ts +61 -0
  223. package/app/components/01.atoms/grids/auto-grid/AutoGrid.vue +5 -10
  224. package/app/components/01.atoms/grids/auto-grid/CONSUMER-STYLING.md +76 -0
  225. package/app/components/01.atoms/grids/auto-grid/stories/AutoGrid.stories.ts +5 -4
  226. package/app/components/01.atoms/grids/auto-grid/tests/AutoGrid.spec.ts +8 -0
  227. package/app/components/01.atoms/grids/column-flow-grid/CONSUMER-STYLING.md +11 -2
  228. package/app/components/01.atoms/grids/grid-stack/CONSUMER-STYLING.md +76 -0
  229. package/app/components/01.atoms/grids/grid-stack/GridStack.vue +6 -1
  230. package/app/components/01.atoms/grids/grid-stack/stories/GridStack.stories.ts +1 -1
  231. package/app/components/01.atoms/grids/grid-stack/tests/GridStack.spec.ts +35 -0
  232. package/app/components/01.atoms/grids/masonry-grid/CONSUMER-STYLING.md +11 -2
  233. package/app/components/01.atoms/navigation/breadcrumb/Breadcrumb.vue +5 -10
  234. package/app/components/01.atoms/navigation/breadcrumb/CONSUMER-STYLING.md +15 -0
  235. package/app/components/01.atoms/navigation/skip-links/CONSUMER-STYLING.md +13 -0
  236. package/app/components/01.atoms/navigation/tabs/CONSUMER-STYLING.md +21 -0
  237. package/app/components/01.atoms/page-row/CONSUMER-STYLING.md +46 -8
  238. package/app/components/01.atoms/page-row/PageRow.vue +17 -13
  239. package/app/components/01.atoms/page-row/stories/PageRow.stories.ts +8 -0
  240. package/app/components/01.atoms/page-row/tests/PageRow.spec.ts +7 -11
  241. package/app/components/01.atoms/pop-over/CONSUMER-STYLING.md +13 -0
  242. package/app/components/01.atoms/qr-code/CONSUMER-STYLING.md +48 -0
  243. package/app/components/01.atoms/qr-code/DisplayQrCode.vue +5 -1
  244. package/app/components/01.atoms/qr-code/stories/DisplayQrCode.stories.ts +11 -3
  245. package/app/components/01.atoms/qr-code/tests/DisplayQrCode.spec.ts +15 -0
  246. package/app/components/01.atoms/text-block/CONSUMER-STYLING.md +49 -0
  247. package/app/components/01.atoms/text-block/TextBlock.vue +13 -5
  248. package/app/components/01.atoms/text-block/stories/TextBlock.stories.ts +84 -0
  249. package/app/components/01.atoms/text-block/tests/TextBlock.spec.ts +78 -0
  250. package/app/components/01.atoms/text-block/tests/__snapshots__/TextBlock.spec.ts.snap +7 -0
  251. package/app/components/01.atoms/text-blocks/eyebrow-text/CONSUMER-STYLING.md +56 -0
  252. package/app/components/01.atoms/text-blocks/eyebrow-text/EyebrowText.vue +10 -5
  253. package/app/components/01.atoms/text-blocks/eyebrow-text/tests/EyebrowText.spec.ts +11 -0
  254. package/app/components/01.atoms/text-blocks/header-block/CONSUMER-STYLING.md +16 -1
  255. package/app/components/01.atoms/text-blocks/hero-text/CONSUMER-STYLING.md +74 -0
  256. package/app/components/01.atoms/text-blocks/hero-text/HeroText.vue +14 -9
  257. package/app/components/01.atoms/text-blocks/hero-text/tests/HeroText.spec.ts +11 -0
  258. package/app/components/01.atoms/text-blocks/link-text/CONSUMER-STYLING.md +45 -0
  259. package/app/components/01.atoms/text-blocks/link-text/LinkText.vue +15 -8
  260. package/app/components/01.atoms/text-blocks/link-text/tests/LinkText.spec.ts +11 -0
  261. package/app/components/01.atoms/ui-block-decorated/CONSUMER-STYLING.md +13 -0
  262. package/app/components/02.molecules/action-menu/ActionMenu.vue +28 -30
  263. package/app/components/02.molecules/action-menu/{ActionMenuItemCore.vue → ActionMenuItem.vue} +12 -14
  264. package/app/components/02.molecules/action-menu/CONSUMER-STYLING.md +90 -76
  265. package/app/components/02.molecules/action-menu/stories/ActionMenu.stories.ts +48 -41
  266. package/app/components/02.molecules/action-menu/tests/ActionMenu.spec.ts +46 -1
  267. package/app/components/02.molecules/action-menu/tests/{ActionMenuItemCore.spec.ts → ActionMenuItem.spec.ts} +11 -5
  268. package/app/components/02.molecules/action-menu/tests/__snapshots__/ActionMenuItem.spec.ts.snap +27 -0
  269. package/app/components/02.molecules/alert-content/AlertContent.vue +17 -8
  270. package/app/components/02.molecules/alert-content/AlertContentInner.vue +57 -30
  271. package/app/components/02.molecules/alert-content/CONSUMER-STYLING.md +84 -0
  272. package/app/components/02.molecules/alert-content/stories/AlertContent.stories.ts +39 -0
  273. package/app/components/02.molecules/alert-content/tests/AlertContent.spec.ts +32 -0
  274. package/app/components/02.molecules/alert-content/tests/AlertContentInner.spec.ts +32 -0
  275. package/app/components/02.molecules/alert-masked-content/AlertMaskedContent.vue +9 -5
  276. package/app/components/02.molecules/alert-masked-content/CONSUMER-STYLING.md +73 -0
  277. package/app/components/02.molecules/alert-masked-content/stories/AlertMaskedContent.stories.ts +91 -10
  278. package/app/components/02.molecules/alert-masked-content/tests/AlertMaskedContent.spec.ts +52 -0
  279. package/app/components/02.molecules/cookie-consent-banner/CONSUMER-STYLING.md +95 -0
  280. package/app/components/02.molecules/cookie-consent-banner/CookieConsentBanner.vue +149 -0
  281. package/app/components/{01.atoms → 02.molecules}/cookie-consent-banner/stories/CookieConsentBanner.stories.ts +22 -3
  282. package/app/components/{01.atoms → 02.molecules}/cookie-consent-banner/tests/CookieConsentBanner.spec.ts +81 -4
  283. package/app/components/02.molecules/display-avatar/CONSUMER-STYLING.md +63 -0
  284. package/app/components/02.molecules/display-avatar/DisplayAvatar.vue +120 -0
  285. package/app/components/{01.atoms → 02.molecules}/display-avatar/stories/DisplayAvatar.stories.ts +56 -14
  286. package/app/components/{01.atoms → 02.molecules}/display-avatar/tests/DisplayAvatar.spec.ts +43 -11
  287. package/app/components/02.molecules/display-avatar/tests/__snapshots__/DisplayAvatar.spec.ts.snap +11 -0
  288. package/app/components/02.molecules/display-chip/CONSUMER-STYLING.md +57 -0
  289. package/app/components/02.molecules/display-chip/DisplayChip.vue +50 -83
  290. package/app/components/02.molecules/display-chip/tests/DisplayChip.spec.ts +10 -10
  291. package/app/components/02.molecules/display-chip/tests/__snapshots__/DisplayChip.spec.ts.snap +4 -4
  292. package/app/components/02.molecules/display-theme-switch/CONSUMER-STYLING.md +25 -4
  293. package/app/components/02.molecules/display-theme-switch/DisplayThemeSwitch.vue +9 -6
  294. package/app/components/02.molecules/display-theme-switch/stories/DisplayThemeSwitch.stories.ts +6 -1
  295. package/app/components/02.molecules/display-theme-switch/tests/DisplayThemeSwitch.spec.ts +10 -1
  296. package/app/components/02.molecules/display-tooltip-defined/CONSUMER-STYLING.md +11 -0
  297. package/app/components/02.molecules/expandable/accordian/CONSUMER-STYLING.md +11 -4
  298. package/app/components/02.molecules/expandable/expanding-panel/CONSUMER-STYLING.md +12 -5
  299. package/app/components/02.molecules/expandable/expanding-panel-classic/CONSUMER-STYLING.md +12 -5
  300. package/app/components/02.molecules/input-copy/CONSUMER-STYLING.md +12 -5
  301. package/app/components/02.molecules/input-copy/InputCopy.vue +12 -25
  302. package/app/components/02.molecules/input-copy/stories/InputCopy.stories.ts +1 -1
  303. package/app/components/02.molecules/input-copy/tests/InputCopy.spec.ts +1 -1
  304. package/app/components/02.molecules/navigation/deep-expanding-menu/CONSUMER-STYLING.md +13 -0
  305. package/app/components/02.molecules/navigation/deep-expanding-menu-classic/CONSUMER-STYLING.md +11 -0
  306. package/app/components/02.molecules/navigation/site-navigation/CONSUMER-STYLING.md +109 -0
  307. package/app/components/02.molecules/navigation/site-navigation/SiteNavigation.vue +37 -55
  308. package/app/components/02.molecules/navigation/site-navigation/stories/SiteNavigation.stories.ts +22 -1
  309. package/app/components/02.molecules/navigation/site-navigation/tests/SiteNavigation.spec.ts +41 -6
  310. package/app/components/02.molecules/navigation/tab-navigation/CONSUMER-STYLING.md +13 -8
  311. package/app/components/02.molecules/navigation/tab-navigation/TabNavigation.vue +18 -36
  312. package/app/components/02.molecules/navigation/tab-navigation/stories/TabNavigation.stories.ts +1 -1
  313. package/app/components/02.molecules/navigation/tab-navigation/tests/TabNavigation.spec.ts +1 -1
  314. package/app/components/02.molecules/opening-hours/CONSUMER-STYLING.md +134 -0
  315. package/app/components/02.molecules/opening-hours/OpeningHours.vue +352 -0
  316. package/app/components/02.molecules/opening-hours/stories/OpeningHours.stories.ts +127 -0
  317. package/app/components/02.molecules/opening-hours/tests/OpeningHours.spec.ts +228 -0
  318. package/app/components/02.molecules/opening-hours/tests/OpeningHours.structuredData.spec.ts +45 -0
  319. package/app/components/02.molecules/opening-hours/tests/__snapshots__/OpeningHours.spec.ts.snap +23 -0
  320. package/app/components/02.molecules/opening-hours/tests/buildOpeningHoursSpecification.spec.ts +52 -0
  321. package/app/components/02.molecules/price-list/CONSUMER-STYLING.md +106 -0
  322. package/app/components/02.molecules/price-list/PriceList.vue +48 -40
  323. package/app/components/02.molecules/price-list/stories/PriceList.stories.ts +15 -2
  324. package/app/components/02.molecules/price-list/tests/PriceList.spec.ts +39 -2
  325. package/app/components/02.molecules/price-list/tests/__snapshots__/PriceList.spec.ts.snap +4 -16
  326. package/app/components/02.molecules/pricing-card/CONSUMER-STYLING.md +23 -5
  327. package/app/components/02.molecules/pricing-card/PricingCard.vue +31 -61
  328. package/app/components/02.molecules/pricing-card/stories/PricingCard.stories.ts +2 -0
  329. package/app/components/02.molecules/pricing-card/tests/PricingCard.spec.ts +14 -1
  330. package/app/components/02.molecules/profile-section/CONSUMER-STYLING.md +53 -0
  331. package/app/components/02.molecules/profile-section/ProfileSection.vue +53 -66
  332. package/app/components/02.molecules/profile-section/tests/ProfileSection.spec.ts +4 -4
  333. package/app/components/02.molecules/profile-section/tests/__snapshots__/ProfileSection.spec.ts.snap +6 -12
  334. package/app/components/02.molecules/prompt/CONSUMER-STYLING.md +51 -0
  335. package/app/components/{01.atoms → 02.molecules}/prompt/DisplayPrompt.vue +23 -8
  336. package/app/components/{01.atoms → 02.molecules}/prompt/stories/DisplayPrompt.stories.ts +18 -1
  337. package/app/components/{01.atoms → 02.molecules}/prompt/tests/DisplayPrompt.spec.ts +37 -7
  338. package/app/components/02.molecules/qr-code/CONSUMER-STYLING.md +66 -0
  339. package/app/components/02.molecules/qr-code/CaptureQrCode.vue +31 -12
  340. package/app/components/02.molecules/qr-code/DecodeQrCode.vue +55 -19
  341. package/app/components/02.molecules/qr-code/stories/CaptureQrCode.stories.ts +56 -0
  342. package/app/components/02.molecules/qr-code/stories/DecodeQrCode.stories.ts +53 -0
  343. package/app/components/02.molecules/qr-code/tests/CaptureQrCode.spec.ts +68 -20
  344. package/app/components/02.molecules/qr-code/tests/DecodeQrCode.spec.ts +44 -8
  345. package/app/components/02.molecules/samaritan-prompt/CONSUMER-STYLING.md +118 -0
  346. package/app/components/02.molecules/samaritan-prompt/SamaritanPrompt.vue +108 -51
  347. package/app/components/02.molecules/samaritan-prompt/SamaritanPromptMixed.vue +63 -62
  348. package/app/components/02.molecules/samaritan-prompt/stories/SamaritanPrompt.stories.ts +129 -0
  349. package/app/components/02.molecules/samaritan-prompt/stories/SamaritanPromptMixed.stories.ts +124 -0
  350. package/app/components/02.molecules/samaritan-prompt/tests/SamaritanPrompt.spec.ts +66 -0
  351. package/app/components/02.molecules/samaritan-prompt/tests/SamaritanPromptMixed.spec.ts +95 -17
  352. package/app/components/02.molecules/select-menu/CONSUMER-STYLING.md +11 -2
  353. package/app/components/02.molecules/social-icons-list/CONSUMER-STYLING.md +43 -0
  354. package/app/components/02.molecules/social-icons-list/SocialIconsList.vue +15 -15
  355. package/app/components/02.molecules/social-icons-list/stories/SocialIconsList.stories.ts +6 -1
  356. package/app/components/02.molecules/social-icons-list/tests/SocialIconsList.spec.ts +22 -1
  357. package/app/components/02.molecules/social-icons-list/tests/__snapshots__/SocialIconsList.spec.ts.snap +3 -3
  358. package/app/components/02.molecules/stepper-list/CONSUMER-STYLING.md +44 -5
  359. package/app/components/02.molecules/stepper-list/StepperList.vue +23 -43
  360. package/app/components/02.molecules/stepper-list/tests/StepperList.spec.ts +9 -0
  361. package/app/components/{01.atoms → 02.molecules}/toast/CONSUMER-STYLING.md +14 -0
  362. package/app/components/{01.atoms → 02.molecules}/toast/DisplayToast.vue +1 -2
  363. package/app/components/{01.atoms → 02.molecules}/toast/DisplayToastProvider.vue +1 -2
  364. package/app/components/{01.atoms → 02.molecules}/toast/stories/DisplayToast.stories.ts +1 -1
  365. package/app/components/{01.atoms → 02.molecules}/toast/stories/DisplayToastProvider.stories.ts +1 -1
  366. package/app/components/03.organisms/image-galleries/carousel-flip/CONSUMER-STYLING.md +13 -0
  367. package/app/components/03.organisms/image-galleries/slider-gallery/CONSUMER-STYLING.md +137 -0
  368. package/app/components/03.organisms/image-galleries/slider-gallery/SliderGallery.vue +378 -343
  369. package/app/components/03.organisms/image-galleries/slider-gallery/stories/SliderGallery.stories.ts +26 -1
  370. package/app/components/03.organisms/image-galleries/slider-gallery/tests/SliderGallery.spec.ts +102 -23
  371. package/app/components/03.organisms/image-galleries/slider-gallery/tests/__snapshots__/SliderGallery.spec.ts.snap +44 -44
  372. package/app/components/03.organisms/responsive-header/CONSUMER-STYLING.md +12 -1
  373. package/app/components/03.organisms/responsive-header/ResponsiveHeader.vue +0 -4
  374. package/app/components/03.organisms/services/service-detail/CONSUMER-STYLING.md +24 -3
  375. package/app/components/03.organisms/services/service-detail/ServiceDetail.vue +3 -3
  376. package/app/components/03.organisms/services/service-detail/stories/ServiceDetail.stories.ts +13 -13
  377. package/app/components/03.organisms/services/service-detail/tests/__snapshots__/ServiceDetail.spec.ts.snap +1 -1
  378. package/app/components/03.organisms/services/service-summary/CONSUMER-STYLING.md +24 -7
  379. package/app/components/03.organisms/services/service-summary/ServiceSummary.vue +3 -3
  380. package/app/components/03.organisms/services/service-summary/stories/ServiceSummary.stories.ts +1 -1
  381. package/app/components/03.organisms/services/service-summary/tests/__snapshots__/ServiceSummary.spec.ts.snap +1 -1
  382. package/app/components/03.organisms/services/services-card/CONSUMER-STYLING.md +11 -2
  383. package/app/components/03.organisms/services/services-card/ServicesCard.vue +17 -26
  384. package/app/components/03.organisms/services/services-card/tests/ServicesCard.spec.ts +21 -0
  385. package/app/components/03.organisms/services/services-grids/CONSUMER-STYLING.md +50 -0
  386. package/app/components/03.organisms/services/services-grids/ServicesCardGrid.vue +9 -16
  387. package/app/components/03.organisms/services/services-grids/stories/ServicesCardGrid.stories.ts +6 -0
  388. package/app/components/03.organisms/services/services-grids/tests/ServicesCardGrid.spec.ts +18 -0
  389. package/app/components/03.organisms/services/services-grids/tests/__snapshots__/ServiceSummaryGrid.spec.ts.snap +3 -3
  390. package/app/components/03.organisms/services/services-grids/tests/__snapshots__/ServicesCardGrid.spec.ts.snap +3 -3
  391. package/app/components/03.organisms/site-header/CONSUMER-STYLING.md +12 -1
  392. package/app/components/04.templates/page-hero-highlights/CONSUMER-STYLING.md +103 -0
  393. package/app/components/04.templates/page-hero-highlights/PageHeroHighlights.vue +144 -193
  394. package/app/components/04.templates/page-hero-highlights/PageHeroHighlightsHeader.vue +27 -37
  395. package/app/components/04.templates/page-hero-highlights/stories/PageHeroHighlights.stories.ts +56 -60
  396. package/app/components/04.templates/page-hero-highlights/stories/PageHeroHighlightsHeader.stories.ts +2 -2
  397. package/app/components/04.templates/page-hero-highlights/tests/PageHeroHighlights.spec.ts +10 -10
  398. package/app/components/04.templates/page-hero-highlights/tests/PageHeroHighlightsHeader.spec.ts +7 -7
  399. package/app/components/04.templates/page-hero-highlights/tests/__snapshots__/PageHeroHighlights.spec.ts.snap +6 -6
  400. package/app/components/05.forms/form-errors/CONSUMER-STYLING.md +112 -0
  401. package/app/components/05.forms/form-errors/InputError.vue +101 -122
  402. package/app/components/05.forms/form-errors/stories/InputError.stories.ts +125 -0
  403. package/app/components/05.forms/form-errors/tests/InputError.spec.ts +82 -31
  404. package/app/components/05.forms/form-field/CONSUMER-STYLING.md +91 -0
  405. package/app/components/05.forms/form-field/FormField.vue +26 -35
  406. package/app/components/05.forms/form-field/stories/FormField.stories.ts +104 -0
  407. package/app/components/05.forms/form-field/tests/FormField.spec.ts +75 -0
  408. package/app/components/05.forms/form-fieldset/CONSUMER-STYLING.md +88 -0
  409. package/app/components/05.forms/form-fieldset/FormFieldset.vue +34 -28
  410. package/app/components/05.forms/form-fieldset/stories/FormFieldset.stories.ts +84 -0
  411. package/app/components/05.forms/form-fieldset/tests/FormFieldset.spec.ts +111 -0
  412. package/app/components/05.forms/form-wrapper/CONSUMER-STYLING.md +101 -0
  413. package/app/components/05.forms/form-wrapper/FormWrapper.vue +32 -15
  414. package/app/components/05.forms/form-wrapper/stories/FormWrapper.stories.ts +75 -0
  415. package/app/components/05.forms/form-wrapper/tests/FormWrapper.spec.ts +57 -0
  416. package/app/components/05.forms/input-button/CONSUMER-STYLING.md +52 -7
  417. package/app/components/05.forms/input-button/{InputButtonCore.vue → InputButton.vue} +60 -18
  418. package/app/components/05.forms/input-button/playwright/{input-button-core.playwright.ts → input-button.playwright.ts} +5 -5
  419. package/app/components/05.forms/input-button/stories/{InputButtonCore.stories.ts → InputButton.stories.ts} +8 -10
  420. package/app/components/05.forms/input-button/tests/{InputButtonCore.spec.ts → InputButton.spec.ts} +75 -19
  421. package/app/components/05.forms/input-button/tests/__snapshots__/{InputButtonCore.spec.ts.snap → InputButton.spec.ts.snap} +18 -18
  422. package/app/components/05.forms/input-checkbox/CONSUMER-STYLING.md +93 -0
  423. package/app/components/05.forms/input-checkbox/MultipleCheckboxes.vue +19 -25
  424. package/app/components/05.forms/input-checkbox/SingleCheckbox.vue +17 -43
  425. package/app/components/05.forms/input-checkbox/stories/MultipleCheckboxes.stories.ts +104 -0
  426. package/app/components/05.forms/input-checkbox/stories/SingleCheckbox.stories.ts +75 -0
  427. package/app/components/05.forms/input-checkbox/tests/MultipleCheckboxes.spec.ts +91 -53
  428. package/app/components/05.forms/input-checkbox/tests/SingleCheckbox.spec.ts +112 -0
  429. package/app/components/05.forms/input-checkbox-radio/CONSUMER-STYLING.md +115 -35
  430. package/app/components/05.forms/input-checkbox-radio/InputCheckboxRadio.vue +158 -0
  431. package/app/components/05.forms/input-checkbox-radio/InputCheckboxRadioButton.vue +102 -101
  432. package/app/components/05.forms/input-checkbox-radio/InputCheckboxRadioField.vue +100 -0
  433. package/app/components/05.forms/input-checkbox-radio/stories/{InputCheckboxRadioCore.stories.ts → InputCheckboxRadio.stories.ts} +23 -8
  434. package/app/components/05.forms/input-checkbox-radio/stories/InputCheckboxRadioButton.stories.ts +60 -16
  435. package/app/components/05.forms/input-checkbox-radio/stories/InputCheckboxRadioField.stories.ts +93 -0
  436. package/app/components/05.forms/input-checkbox-radio/tests/InputCheckboxRadio.spec.ts +174 -0
  437. package/app/components/05.forms/input-checkbox-radio/tests/InputCheckboxRadioButton.spec.ts +87 -0
  438. package/app/components/05.forms/input-checkbox-radio/tests/InputCheckboxRadioField.spec.ts +87 -0
  439. package/app/components/05.forms/input-description/CONSUMER-STYLING.md +177 -0
  440. package/app/components/05.forms/input-description/InputDescription.vue +45 -24
  441. package/app/components/05.forms/input-description/stories/InputDescription.stories.ts +160 -0
  442. package/app/components/05.forms/input-description/tests/InputDescription.spec.ts +62 -386
  443. package/app/components/05.forms/input-label/CONSUMER-STYLING.md +134 -0
  444. package/app/components/05.forms/input-label/InputLabel.vue +99 -38
  445. package/app/components/05.forms/input-label/stories/InputLabel.stories.ts +236 -0
  446. package/app/components/05.forms/input-label/tests/InputLabel.spec.ts +113 -342
  447. package/app/components/05.forms/input-number/CONSUMER-STYLING.md +16 -7
  448. package/app/components/05.forms/input-number/{InputNumberCore.vue → InputNumber.vue} +6 -6
  449. package/app/components/05.forms/input-number/{variants/InputNumberDefault.vue → InputNumberField.vue} +12 -15
  450. package/app/components/05.forms/input-number/stories/{InputNumberCore.stories.ts → InputNumber.stories.ts} +6 -6
  451. package/app/components/05.forms/input-number/{variants/stories/InputNumberDefault.stories.ts → stories/InputNumberField.stories.ts} +5 -5
  452. package/app/components/05.forms/input-number/tests/{InputNumberCore.spec.ts → InputNumber.spec.ts} +2 -2
  453. package/app/components/05.forms/input-number/{variants/tests/InputNumberDefault.spec.ts → tests/InputNumberField.spec.ts} +8 -8
  454. package/app/components/05.forms/input-radio/CONSUMER-STYLING.md +70 -0
  455. package/app/components/05.forms/input-radio/MultipleRadiobuttons.vue +19 -30
  456. package/app/components/05.forms/input-radio/stories/MultipleRadiobuttons.stories.ts +116 -0
  457. package/app/components/05.forms/input-radio/tests/MultipleRadioButtons.spec.ts +125 -74
  458. package/app/components/05.forms/input-range/CONSUMER-STYLING.md +13 -0
  459. package/app/components/05.forms/input-range/InputRangeCore.vue +1 -1
  460. package/app/components/05.forms/input-range/{variants/InputRangeDefault.vue → InputRangeDefault.vue} +7 -11
  461. package/app/components/05.forms/input-range/{variants/tests → tests}/InputRangeDefault.spec.ts +1 -1
  462. package/app/components/05.forms/input-select/CONSUMER-STYLING.md +11 -2
  463. package/app/components/05.forms/input-select/{variants/InputSelectWithLabel.vue → InputSelectWithLabel.vue} +6 -9
  464. package/app/components/05.forms/input-select/stories/InputSelectWithLabel.stories.ts +1 -1
  465. package/app/components/05.forms/input-text/CONSUMER-STYLING.md +12 -3
  466. package/app/components/05.forms/input-text/{variants/InputPasswordWithLabel.vue → InputPasswordWithLabel.vue} +3 -3
  467. package/app/components/05.forms/input-text/{variants/InputTextAsNumberWithLabel.vue → InputTextAsNumberWithLabel.vue} +12 -15
  468. package/app/components/05.forms/input-text/InputTextCore.vue +8 -11
  469. package/app/components/05.forms/input-text/{variants/InputTextWithLabel.vue → InputTextWithLabel.vue} +9 -10
  470. package/app/components/05.forms/input-text/stories/InputPasswordWithLabel.stories.ts +1 -1
  471. package/app/components/05.forms/input-text/stories/InputTextAsNumberWithLabel.stories.ts +1 -1
  472. package/app/components/05.forms/input-text/stories/InputTextWithLabel.stories.ts +1 -1
  473. package/app/components/05.forms/input-text/tests/InputPasswordWithLabel.spec.ts +2 -1
  474. package/app/components/05.forms/input-text/tests/InputTextAsNumberWithLabel.spec.ts +1 -1
  475. package/app/components/05.forms/input-text/tests/InputTextWithLabel.spec.ts +2 -1
  476. package/app/components/05.forms/input-textarea/CONSUMER-STYLING.md +11 -2
  477. package/app/components/05.forms/input-textarea/{variants/InputTextareaWithLabel.vue → InputTextareaWithLabel.vue} +3 -7
  478. package/app/components/05.forms/input-textarea/stories/InputTextareaWithLabel.stories.ts +1 -1
  479. package/app/components/05.forms/patterns/stories/ContactForm.stories.ts +9 -10
  480. package/app/components/05.forms/patterns/stories/LoginForm.stories.ts +10 -10
  481. package/app/components/05.forms/patterns/stories/MigratedFieldsForm.stories.ts +246 -101
  482. package/app/components/05.forms/pending-effect/CONSUMER-STYLING.md +92 -0
  483. package/app/components/05.forms/pending-effect/PendingEffect.vue +52 -45
  484. package/app/components/05.forms/pending-effect/stories/PendingEffect.stories.ts +132 -0
  485. package/app/components/05.forms/pending-effect/tests/PendingEffect.spec.ts +67 -0
  486. package/app/components/05.forms/toggle-switch/CONSUMER-STYLING.md +11 -2
  487. package/app/components/05.forms/toggle-switch/ToggleSwitchCore.vue +10 -29
  488. package/app/components/05.forms/toggle-switch/{variants/ToggleSwitchWithLabel.vue → ToggleSwitchWithLabel.vue} +5 -7
  489. package/app/components/05.forms/toggle-switch/{variants/ToggleSwitchWithLabelInline.vue → ToggleSwitchWithLabelInline.vue} +2 -4
  490. package/app/components/05.forms/toggle-switch/stories/ToggleSwitchWithLabel.stories.ts +1 -1
  491. package/app/components/05.forms/toggle-switch/stories/ToggleSwitchWithLabelInline.stories.ts +4 -1
  492. package/app/components/05.forms/toggle-switch/{variants/tests → tests}/ToggleSwitchWithLabel.spec.ts +26 -0
  493. package/app/components/05.forms/triple-toggle-switch/CONSUMER-STYLING.md +75 -62
  494. package/app/components/05.forms/triple-toggle-switch/TripleToggleSwitch.vue +243 -0
  495. package/app/components/05.forms/triple-toggle-switch/stories/TripleToggleSwitch.stories.ts +104 -0
  496. package/app/components/05.forms/triple-toggle-switch/tests/TripleToggleSwitch.spec.ts +138 -0
  497. package/app/composables/tests/useCancellableTimer.spec.ts +48 -0
  498. package/app/composables/tests/useMaxChildWidth.spec.ts +67 -0
  499. package/app/composables/useCancellableTimer.ts +27 -7
  500. package/app/composables/useMaxChildWidth.ts +4 -6
  501. package/app/types/app-config.d.ts +10 -0
  502. package/app/types/components/cookie-consent-banner.d.ts +3 -0
  503. package/app/types/components/index.ts +6 -1
  504. package/app/types/components/opening-hours.d.ts +48 -0
  505. package/app/types/components/price-list.d.ts +11 -0
  506. package/app/types/components/profile-section.d.ts +6 -0
  507. package/app/types/components/samaritan-prompt.d.ts +13 -0
  508. package/app/types/components/services-card.d.ts +9 -0
  509. package/app/types/components/slider-gallery.d.ts +2 -0
  510. package/app/types/components/social-icons-list.d.ts +2 -0
  511. package/app/types/forms/types.forms.d.ts +3 -0
  512. package/app/types/forms/types.zodFormControl.d.ts +0 -3
  513. package/app/utils/opening-hours.ts +44 -0
  514. package/nuxt.config.ts +5 -1
  515. package/package.json +2 -2
  516. package/ramps.config.mjs +1 -1
  517. package/.claude/commands/create-commit-message.md +0 -13
  518. package/.claude/commands/create-release-notes.md +0 -34
  519. package/.claude/commands/migrate-component.md +0 -169
  520. package/.claude/commands/run-commit.md +0 -13
  521. package/.claude/component-ledger/artifact-url.txt +0 -1
  522. package/.claude/component-ledger/audit.json +0 -1
  523. package/.claude/component-ledger/build.mjs +0 -164
  524. package/.claude/component-ledger/output.html +0 -569
  525. package/.claude/component-ledger/template.html +0 -569
  526. package/.claude/hooks/check-component-update.sh +0 -95
  527. package/.claude/hooks/refresh-component-ledger.sh +0 -32
  528. package/.claude/settings.json +0 -134
  529. package/.claude/settings.local.json +0 -38
  530. package/.claude/skills/components/alert-content-inner.md +0 -60
  531. package/.claude/skills/components/navigation-horizontal.md +0 -99
  532. package/.claude/skills/components/samaritan-prompt-mixed.md +0 -139
  533. package/app/components/01.atoms/content-wrappers/content-columns-2/ContentColumns2.vue +0 -51
  534. package/app/components/01.atoms/content-wrappers/content-columns-2/stories/ContentColumns2.stories.ts +0 -110
  535. package/app/components/01.atoms/content-wrappers/content-columns-2/tests/ContentColumns2.spec.ts +0 -105
  536. package/app/components/01.atoms/content-wrappers/content-columns-2/tests/__snapshots__/ContentColumns2.spec.ts.snap +0 -14
  537. package/app/components/01.atoms/content-wrappers/content-width/ContentWidth.vue +0 -88
  538. package/app/components/01.atoms/content-wrappers/content-width/stories/ContentWidth.stories.ts +0 -362
  539. package/app/components/01.atoms/content-wrappers/content-width/tests/ContentWidth.spec.ts +0 -132
  540. package/app/components/01.atoms/content-wrappers/layout-grid/layout-grid-by-cols/tests/__snapshots__/LayoutGrid.spec.ts.snap +0 -36
  541. package/app/components/01.atoms/content-wrappers/layout-grid/layout-grid-by-width/LayoutGridByWidth.vue +0 -70
  542. package/app/components/01.atoms/content-wrappers/layout-grid/layout-grid-by-width/stories/LayoutGridByWidth.stories.ts +0 -220
  543. package/app/components/01.atoms/content-wrappers/layout-grid/layout-grid-by-width/tests/LayoutGridByWidth.spec.ts +0 -174
  544. package/app/components/01.atoms/content-wrappers/layout-grid/layout-grid-by-width/tests/__snapshots__/LayoutGrid.spec.ts.snap +0 -36
  545. package/app/components/01.atoms/content-wrappers/layout-grid/layout-grid-by-width/tests/__snapshots__/LayoutGridByCols.spec.ts.snap +0 -36
  546. package/app/components/01.atoms/content-wrappers/layout-grid/layout-grid-by-width/tests/__snapshots__/LayoutGridByWidth.spec.ts.snap +0 -36
  547. package/app/components/01.atoms/cookie-consent-banner/CookieConsentBanner.vue +0 -148
  548. package/app/components/01.atoms/display-avatar/DisplayAvatar.vue +0 -130
  549. package/app/components/01.atoms/display-avatar/tests/__snapshots__/DisplayAvatar.spec.ts.snap +0 -11
  550. package/app/components/02.molecules/action-menu/tests/__snapshots__/ActionMenuItemCore.spec.ts.snap +0 -27
  551. package/app/components/02.molecules/navigation/navigation-horizontal/NavigationHorizontal.vue +0 -162
  552. package/app/components/02.molecules/navigation/navigation-horizontal/stories/NavigationHorizontal.stories.ts +0 -373
  553. package/app/components/02.molecules/navigation/navigation-horizontal/tests/NavigationHorizontal.spec.ts +0 -152
  554. package/app/components/02.molecules/navigation/navigation-horizontal/tests/__snapshots__/NavigationHorizontal.spec.ts.snap +0 -17
  555. package/app/components/02.molecules/qr-code/stories/QrCode.stories.ts +0 -101
  556. package/app/components/03.organisms/colour-finder/ColourFinder.vue +0 -1519
  557. package/app/components/05.forms/input-checkbox-radio/InputCheckboxRadioCore.vue +0 -202
  558. package/app/components/05.forms/input-checkbox-radio/InputCheckboxRadioWithLabel.vue +0 -105
  559. package/app/components/05.forms/input-checkbox-radio/tests/InputCheckboxRadioCore.spec.ts +0 -320
  560. package/app/components/05.forms/triple-toggle-switch/TripleToggleSwitchCore.vue +0 -314
  561. package/app/components/05.forms/triple-toggle-switch/stories/TripleToggleSwitchCore.stories.ts +0 -63
  562. package/.vscode/{srcdev-component-dialog.code-snippets → srcdev-component-display-dialog.code-snippets} +0 -0
  563. package/app/components/{01.atoms → 02.molecules}/toast/tests/DisplayToast.spec.ts +1 -1
  564. /package/app/components/{01.atoms → 02.molecules}/toast/tests/DisplayToastProvider.spec.ts +0 -0
  565. /package/app/components/05.forms/input-button/playwright/{input-button-core.playwright.ts-snapshots → input-button.playwright.ts-snapshots}/combo-icons-secondary-chromium-darwin.png +0 -0
  566. /package/app/components/05.forms/input-button/playwright/{input-button-core.playwright.ts-snapshots → input-button.playwright.ts-snapshots}/combo-icons-secondary-firefox-darwin.png +0 -0
  567. /package/app/components/05.forms/input-button/playwright/{input-button-core.playwright.ts-snapshots → input-button.playwright.ts-snapshots}/combo-icons-secondary-webkit-darwin.png +0 -0
  568. /package/app/components/05.forms/input-button/playwright/{input-button-core.playwright.ts-snapshots → input-button.playwright.ts-snapshots}/combo-icons-tertiary-chromium-darwin.png +0 -0
  569. /package/app/components/05.forms/input-button/playwright/{input-button-core.playwright.ts-snapshots → input-button.playwright.ts-snapshots}/combo-icons-tertiary-firefox-darwin.png +0 -0
  570. /package/app/components/05.forms/input-button/playwright/{input-button-core.playwright.ts-snapshots → input-button.playwright.ts-snapshots}/combo-icons-tertiary-webkit-darwin.png +0 -0
  571. /package/app/components/05.forms/input-button/playwright/{input-button-core.playwright.ts-snapshots → input-button.playwright.ts-snapshots}/combo-primary-pending-chromium-darwin.png +0 -0
  572. /package/app/components/05.forms/input-button/playwright/{input-button-core.playwright.ts-snapshots → input-button.playwright.ts-snapshots}/combo-primary-pending-firefox-darwin.png +0 -0
  573. /package/app/components/05.forms/input-button/playwright/{input-button-core.playwright.ts-snapshots → input-button.playwright.ts-snapshots}/combo-primary-pending-webkit-darwin.png +0 -0
  574. /package/app/components/05.forms/input-button/playwright/{input-button-core.playwright.ts-snapshots → input-button.playwright.ts-snapshots}/combo-secondary-pill-chromium-darwin.png +0 -0
  575. /package/app/components/05.forms/input-button/playwright/{input-button-core.playwright.ts-snapshots → input-button.playwright.ts-snapshots}/combo-secondary-pill-firefox-darwin.png +0 -0
  576. /package/app/components/05.forms/input-button/playwright/{input-button-core.playwright.ts-snapshots → input-button.playwright.ts-snapshots}/combo-secondary-pill-webkit-darwin.png +0 -0
  577. /package/app/components/05.forms/input-button/playwright/{input-button-core.playwright.ts-snapshots → input-button.playwright.ts-snapshots}/combo-tertiary-readonly-chromium-darwin.png +0 -0
  578. /package/app/components/05.forms/input-button/playwright/{input-button-core.playwright.ts-snapshots → input-button.playwright.ts-snapshots}/combo-tertiary-readonly-firefox-darwin.png +0 -0
  579. /package/app/components/05.forms/input-button/playwright/{input-button-core.playwright.ts-snapshots → input-button.playwright.ts-snapshots}/combo-tertiary-readonly-webkit-darwin.png +0 -0
  580. /package/app/components/05.forms/input-button/playwright/{input-button-core.playwright.ts-snapshots → input-button.playwright.ts-snapshots}/default-chromium-darwin.png +0 -0
  581. /package/app/components/05.forms/input-button/playwright/{input-button-core.playwright.ts-snapshots → input-button.playwright.ts-snapshots}/default-firefox-darwin.png +0 -0
  582. /package/app/components/05.forms/input-button/playwright/{input-button-core.playwright.ts-snapshots → input-button.playwright.ts-snapshots}/default-theme-default-chromium-darwin.png +0 -0
  583. /package/app/components/05.forms/input-button/playwright/{input-button-core.playwright.ts-snapshots → input-button.playwright.ts-snapshots}/default-theme-default-firefox-darwin.png +0 -0
  584. /package/app/components/05.forms/input-button/playwright/{input-button-core.playwright.ts-snapshots → input-button.playwright.ts-snapshots}/default-theme-default-webkit-darwin.png +0 -0
  585. /package/app/components/05.forms/input-button/playwright/{input-button-core.playwright.ts-snapshots → input-button.playwright.ts-snapshots}/default-theme-error-chromium-darwin.png +0 -0
  586. /package/app/components/05.forms/input-button/playwright/{input-button-core.playwright.ts-snapshots → input-button.playwright.ts-snapshots}/default-theme-error-firefox-darwin.png +0 -0
  587. /package/app/components/05.forms/input-button/playwright/{input-button-core.playwright.ts-snapshots → input-button.playwright.ts-snapshots}/default-theme-error-webkit-darwin.png +0 -0
  588. /package/app/components/05.forms/input-button/playwright/{input-button-core.playwright.ts-snapshots → input-button.playwright.ts-snapshots}/default-theme-success-chromium-darwin.png +0 -0
  589. /package/app/components/05.forms/input-button/playwright/{input-button-core.playwright.ts-snapshots → input-button.playwright.ts-snapshots}/default-theme-success-firefox-darwin.png +0 -0
  590. /package/app/components/05.forms/input-button/playwright/{input-button-core.playwright.ts-snapshots → input-button.playwright.ts-snapshots}/default-theme-success-webkit-darwin.png +0 -0
  591. /package/app/components/05.forms/input-button/playwright/{input-button-core.playwright.ts-snapshots → input-button.playwright.ts-snapshots}/default-theme-warning-chromium-darwin.png +0 -0
  592. /package/app/components/05.forms/input-button/playwright/{input-button-core.playwright.ts-snapshots → input-button.playwright.ts-snapshots}/default-theme-warning-firefox-darwin.png +0 -0
  593. /package/app/components/05.forms/input-button/playwright/{input-button-core.playwright.ts-snapshots → input-button.playwright.ts-snapshots}/default-theme-warning-webkit-darwin.png +0 -0
  594. /package/app/components/05.forms/input-button/playwright/{input-button-core.playwright.ts-snapshots → input-button.playwright.ts-snapshots}/default-variant-primary-chromium-darwin.png +0 -0
  595. /package/app/components/05.forms/input-button/playwright/{input-button-core.playwright.ts-snapshots → input-button.playwright.ts-snapshots}/default-variant-primary-firefox-darwin.png +0 -0
  596. /package/app/components/05.forms/input-button/playwright/{input-button-core.playwright.ts-snapshots → input-button.playwright.ts-snapshots}/default-variant-primary-webkit-darwin.png +0 -0
  597. /package/app/components/05.forms/input-button/playwright/{input-button-core.playwright.ts-snapshots → input-button.playwright.ts-snapshots}/default-variant-secondary-chromium-darwin.png +0 -0
  598. /package/app/components/05.forms/input-button/playwright/{input-button-core.playwright.ts-snapshots → input-button.playwright.ts-snapshots}/default-variant-secondary-firefox-darwin.png +0 -0
  599. /package/app/components/05.forms/input-button/playwright/{input-button-core.playwright.ts-snapshots → input-button.playwright.ts-snapshots}/default-variant-secondary-webkit-darwin.png +0 -0
  600. /package/app/components/05.forms/input-button/playwright/{input-button-core.playwright.ts-snapshots → input-button.playwright.ts-snapshots}/default-variant-tertiary-chromium-darwin.png +0 -0
  601. /package/app/components/05.forms/input-button/playwright/{input-button-core.playwright.ts-snapshots → input-button.playwright.ts-snapshots}/default-variant-tertiary-firefox-darwin.png +0 -0
  602. /package/app/components/05.forms/input-button/playwright/{input-button-core.playwright.ts-snapshots → input-button.playwright.ts-snapshots}/default-variant-tertiary-webkit-darwin.png +0 -0
  603. /package/app/components/05.forms/input-button/playwright/{input-button-core.playwright.ts-snapshots → input-button.playwright.ts-snapshots}/default-webkit-darwin.png +0 -0
  604. /package/app/components/05.forms/input-button/playwright/{input-button-core.playwright.ts-snapshots → input-button.playwright.ts-snapshots}/nuxt-icon-only-component-chromium-darwin.png +0 -0
  605. /package/app/components/05.forms/input-button/playwright/{input-button-core.playwright.ts-snapshots → input-button.playwright.ts-snapshots}/nuxt-icon-only-component-firefox-darwin.png +0 -0
  606. /package/app/components/05.forms/input-button/playwright/{input-button-core.playwright.ts-snapshots → input-button.playwright.ts-snapshots}/nuxt-icon-only-component-webkit-darwin.png +0 -0
  607. /package/app/components/05.forms/input-button/playwright/{input-button-core.playwright.ts-snapshots → input-button.playwright.ts-snapshots}/state-pending-chromium-darwin.png +0 -0
  608. /package/app/components/05.forms/input-button/playwright/{input-button-core.playwright.ts-snapshots → input-button.playwright.ts-snapshots}/state-pending-firefox-darwin.png +0 -0
  609. /package/app/components/05.forms/input-button/playwright/{input-button-core.playwright.ts-snapshots → input-button.playwright.ts-snapshots}/state-pending-webkit-darwin.png +0 -0
  610. /package/app/components/05.forms/input-button/playwright/{input-button-core.playwright.ts-snapshots → input-button.playwright.ts-snapshots}/state-pill-chromium-darwin.png +0 -0
  611. /package/app/components/05.forms/input-button/playwright/{input-button-core.playwright.ts-snapshots → input-button.playwright.ts-snapshots}/state-pill-firefox-darwin.png +0 -0
  612. /package/app/components/05.forms/input-button/playwright/{input-button-core.playwright.ts-snapshots → input-button.playwright.ts-snapshots}/state-pill-webkit-darwin.png +0 -0
  613. /package/app/components/05.forms/input-button/playwright/{input-button-core.playwright.ts-snapshots → input-button.playwright.ts-snapshots}/state-readonly-chromium-darwin.png +0 -0
  614. /package/app/components/05.forms/input-button/playwright/{input-button-core.playwright.ts-snapshots → input-button.playwright.ts-snapshots}/state-readonly-firefox-darwin.png +0 -0
  615. /package/app/components/05.forms/input-button/playwright/{input-button-core.playwright.ts-snapshots → input-button.playwright.ts-snapshots}/state-readonly-webkit-darwin.png +0 -0
  616. /package/app/components/05.forms/input-button/playwright/{input-button-core.playwright.ts-snapshots → input-button.playwright.ts-snapshots}/with-both-nuxt-icon-components-chromium-darwin.png +0 -0
  617. /package/app/components/05.forms/input-button/playwright/{input-button-core.playwright.ts-snapshots → input-button.playwright.ts-snapshots}/with-both-nuxt-icon-components-firefox-darwin.png +0 -0
  618. /package/app/components/05.forms/input-button/playwright/{input-button-core.playwright.ts-snapshots → input-button.playwright.ts-snapshots}/with-both-nuxt-icon-components-webkit-darwin.png +0 -0
  619. /package/app/components/05.forms/input-range/{variants/stories → stories}/InputRangeDefault.stories.ts +0 -0
  620. /package/app/components/05.forms/input-select/{variants/tests → tests}/InputSelectWithLabel.spec.ts +0 -0
  621. /package/app/components/05.forms/input-textarea/{variants/tests → tests}/InputTextareaWithLabel.spec.ts +0 -0
  622. /package/app/components/05.forms/toggle-switch/{variants/tests → tests}/ToggleSwitchWithLabelInline.spec.ts +0 -0
  623. /package/app/types/components/{navigation-horizontal.d.ts → nav-item.d.ts} +0 -0
@@ -1,6 +1,6 @@
1
1
  ---
2
2
  name: ScrollRevealFrame
3
- description: ScrollRevealFrame generic parallax clipping frame — props, slot API, CSS tokens, browser support, when to use vs ScrollRevealImage
3
+ description: ScrollRevealFrame generic parallax clipping frame — props, slot API, public CSS tokens (prop or CSS), browser support, when to use vs ScrollRevealImage
4
4
  type: reference
5
5
  ---
6
6
 
@@ -14,26 +14,28 @@ Use `ScrollRevealFrame` when the content inside the frame is **anything other th
14
14
 
15
15
  ## How it works
16
16
 
17
- - The `<figure>` root is a fixed-height clipping window (`overflow: hidden`) that registers a named `view-timeline`.
18
- - The inner `.reveal-content` wrapper is taller than the frame by `parallaxOffset` and animates `translateY` as the frame scrolls through the viewport.
17
+ - The `<figure class="scroll-reveal-frame">` root is a fixed-height clipping window (`overflow: hidden`) that registers a named `view-timeline`.
18
+ - The inner `.scroll-reveal-frame-content` wrapper is taller than the frame by the parallax offset and animates `translateY` as the frame scrolls through the viewport.
19
19
  - Slot content fills that wrapper — anything inside pans as a unit.
20
20
 
21
21
  Browser support (as of 2026): Chrome 115+, Edge 115+, Firefox 114+, Safari 17.2+. Older browsers fall back to a static cropped view.
22
22
 
23
23
  ## Props
24
24
 
25
+ The three sizing props have **no default**. When passed, each writes its public token inline on the root (so it wins over any CSS). When omitted, the token comes from CSS, falling back to the default shown.
26
+
25
27
  | Prop | Type | Default | Description |
26
28
  |------|------|---------|-------------|
27
- | `frameHeight` | `string` | `"540px"` | Height of the visible clipping frame. Any CSS length unit (`px`, `vh`, `rem`). |
28
- | `parallaxOffset` | `string` | `"36rem"` | Distance the content travels vertically across the full scroll range. Larger = more dramatic reveal. |
29
- | `radius` | `string` | `"0px"` | `border-radius` applied to the clipping frame. Slot content stays contained within the rounded shape. |
29
+ | `frameHeight` | `string` | unset (CSS `540px`) | Height of the visible clipping frame. Any CSS length unit. Writes `--scroll-reveal-frame-height`. |
30
+ | `parallaxOffset` | `string` | unset (CSS `36rem`) | Distance the content travels vertically across the full scroll range. Writes `--scroll-reveal-frame-parallax-offset`. |
31
+ | `radius` | `string` | unset (CSS `0px`) | `border-radius` of the clipping frame. Writes `--scroll-reveal-frame-radius`. |
30
32
  | `styleClassPassthrough` | `string \| string[]` | `[]` | Extra classes applied to the root `<figure>`. |
31
33
 
32
34
  ## Slots
33
35
 
34
36
  | Slot | Description |
35
37
  |------|-------------|
36
- | `default` | Content to pan. It fills a `div.reveal-content` that is taller than the frame by `parallaxOffset`. |
38
+ | `default` | Content to pan. It fills a `div.scroll-reveal-frame-content` that is taller than the frame by the parallax offset. |
37
39
 
38
40
  ## Basic usage — single image
39
41
 
@@ -91,29 +93,27 @@ Wrap each `<img>` / `<NuxtImg>` in a `<div>` cell — `object-fit` on an `<img>`
91
93
 
92
94
  ## Responsive frame height
93
95
 
94
- The `frameHeight` prop sets `--_frame-height` as an inline style. To vary it responsively, override the CSS custom property in a scoped style block:
96
+ Don't pass the prop; set the public token from CSS on an element you own:
95
97
 
96
98
  ```css
97
99
  .my-page {
98
- .reveal-frame {
99
- --_frame-height: 320px;
100
+ --scroll-reveal-frame-height: 320px;
100
101
 
101
- @media (width >= 768px) {
102
- --_frame-height: 540px;
103
- }
102
+ @media (width >= 768px) {
103
+ --scroll-reveal-frame-height: 540px;
104
104
  }
105
105
  }
106
106
  ```
107
107
 
108
108
  ## CSS custom properties
109
109
 
110
- These are set from props via inline `:style` but can be overridden in CSS for responsive or contextual control.
110
+ Full detail in `CONSUMER-STYLING.md` next to the component.
111
111
 
112
- | Property | Default | Set by prop |
112
+ | Property | Default | Set by prop (when passed) |
113
113
  |----------|---------|-------------|
114
- | `--_frame-height` | `540px` | `frameHeight` |
115
- | `--_parallax-offset` | `36rem` | `parallaxOffset` |
116
- | `--_radius` | `0px` | `radius` |
114
+ | `--scroll-reveal-frame-height` | `540px` | `frameHeight` |
115
+ | `--scroll-reveal-frame-parallax-offset` | `36rem` | `parallaxOffset` |
116
+ | `--scroll-reveal-frame-radius` | `0px` | `radius` |
117
117
 
118
118
  ## Choosing parallaxOffset
119
119
 
@@ -131,6 +131,7 @@ Values below `20rem` tend to look static at normal scroll speeds.
131
131
  ## Notes
132
132
 
133
133
  - `overflow: hidden` is on the root `<figure>` — content that needs to escape (dropdowns, tooltips) must be portalled outside.
134
- - The named `view-timeline` (`--reveal-frame-timeline`) is scoped to the component. Multiple `ScrollRevealFrame` instances on the same page are independent.
135
- - Reduced-motion: the animation is disabled and the content falls back to a static centred crop via `@media (prefers-reduced-motion: reduce)`.
134
+ - The named `view-timeline` (`--scroll-reveal-frame-timeline`) is scoped to the component. Multiple `ScrollRevealFrame` instances on the same page are independent.
135
+ - Reduced-motion: the animation is disabled and the content is sized to the frame (a static crop) via `@media (prefers-reduced-motion: reduce)`. Same for browsers without `animation-timeline`.
136
136
  - Do not put `ScrollRevealFrame` inside a container with `overflow: hidden` or `overflow: clip` — this breaks the `view-timeline` scroll detection.
137
+ - 2026-09-27 migration: the private `--_frame-height`/`--_parallax-offset`/`--_radius` tokens became public `--scroll-reveal-frame-*` tokens, and the props lost their defaults. Before, the props always wrote the private tokens inline, so the CSS override this doc used to recommend could never apply. Classes renamed `.reveal-frame` → `.scroll-reveal-frame`, `.reveal-content` → `.scroll-reveal-frame-content`; keyframes `reveal-pan` → `scroll-reveal-frame-pan` (generic global names, collision-prone). `ScrollRevealImage`'s image class became `.scroll-reveal-image`.
@@ -1,6 +1,6 @@
1
1
  ---
2
2
  name: ScrollRevealImage
3
- description: ScrollRevealImage single-image parallax reveal — props, focalX usage, CSS tokens, browser support, when to use vs ScrollRevealFrame
3
+ description: ScrollRevealImage single-image parallax reveal — props, focalX and focal-y crop tokens, CSS tokens (prop or CSS), browser support, when to use vs ScrollRevealFrame
4
4
  type: reference
5
5
  ---
6
6
 
@@ -20,10 +20,10 @@ For arbitrary slot content — a grid of images, video, markup — use `ScrollRe
20
20
  | `alt` | `string` | `""` | Alt text for the image. |
21
21
  | `imgWidth` | `number` | `1920` | Intrinsic width of the source image — required for NuxtImg optimisation. |
22
22
  | `imgHeight` | `number` | `1080` | Intrinsic height of the source image — required for NuxtImg optimisation. |
23
- | `frameHeight` | `string` | `"540px"` | Height of the visible clipping frame. Any CSS length unit (`px`, `vh`, `rem`). |
24
- | `parallaxOffset` | `string` | `"36rem"` | Distance the image travels vertically across the full scroll range. Larger = more dramatic reveal. |
25
- | `focalX` | `string` | `"50%"` | Horizontal focal point — CSS `object-position` x-axis value. Controls which horizontal slice stays in view. |
26
- | `radius` | `string` | `"0px"` | `border-radius` applied to the clipping frame. |
23
+ | `frameHeight` | `string` | unset (CSS default `540px`) | Height of the visible clipping frame. Any CSS length unit. Leave unset to control it from CSS via `--scroll-reveal-frame-height`. |
24
+ | `parallaxOffset` | `string` | unset (CSS default `36rem`) | Distance the image travels vertically across the full scroll range. Leave unset to control it via `--scroll-reveal-frame-parallax-offset`. |
25
+ | `focalX` | `string` | unset (CSS default `50%`) | Horizontal focal point, CSS `object-position` x value. Controls which horizontal slice stays in view. Leave unset to control it via `--scroll-reveal-image-focal-x`. |
26
+ | `radius` | `string` | unset (CSS default `0px`) | `border-radius` of the clipping frame. Leave unset to control it via `--scroll-reveal-frame-radius`. |
27
27
  | `loading` | `"lazy" \| "eager"` | `"lazy"` | Image loading strategy. Use `"eager"` if this is the LCP image (e.g. partially in view on load). |
28
28
  | `styleClassPassthrough` | `string \| string[]` | `[]` | Extra classes applied to the root `<figure>`. |
29
29
 
@@ -102,7 +102,7 @@ The vertical position of the image is driven by the scroll animation (`translate
102
102
  | `"75%"` | Right of centre — useful for a subject offset to the right |
103
103
  | `"100%"` or `"right"` | Right edge |
104
104
 
105
- Internally, `focalX` sets `object-position: <focalX> 0%` on the `<img>`. The `Y` is always `0%` because the animation handles vertical travel.
105
+ Internally, `focalX` sets `--scroll-reveal-image-focal-x`, used as `object-position: <focal-x> <focal-y>` on the `<img>`. The Y comes from `--scroll-reveal-image-focal-y` (default `0%`, so the animation starts at the image top); raise it if the top of the image is empty or the subject sits low. With no animation (reduced motion or no support), Y is `--scroll-reveal-image-focal-y-static` (default `50%`).
106
106
 
107
107
  ## imgWidth / imgHeight
108
108
 
@@ -122,34 +122,43 @@ Common pairs:
122
122
 
123
123
  ## Responsive frame height
124
124
 
125
- Override `--_frame-height` in a scoped style block for responsive control:
125
+ Don't pass `frame-height`, and set the frame's public token from CSS on an ancestor you own (a prop,
126
+ when passed, is written inline and always wins):
126
127
 
127
128
  ```css
128
129
  .my-page {
129
- .reveal-frame {
130
- --_frame-height: 320px;
130
+ --scroll-reveal-frame-height: 320px;
131
131
 
132
- @media (width >= 768px) {
133
- --_frame-height: 480px;
134
- }
132
+ @media (width >= 768px) {
133
+ --scroll-reveal-frame-height: 480px;
134
+ }
135
135
 
136
- @media (width >= 1024px) {
137
- --_frame-height: 540px;
138
- }
136
+ @media (width >= 1024px) {
137
+ --scroll-reveal-frame-height: 540px;
139
138
  }
140
139
  }
141
140
  ```
142
141
 
142
+ > **Changed 2026-09-27**: this section used to recommend overriding `--_frame-height` on
143
+ > `.reveal-frame`. That never worked, because this component always passed a default `frameHeight`
144
+ > down and the frame always wrote it inline. The frame-sizing props now default to unset.
145
+
143
146
  ## CSS custom properties
144
147
 
145
- Set from props via inline `:style` — override in CSS for responsive or contextual control.
148
+ Frame tokens come from `ScrollRevealFrame` (see its `CONSUMER-STYLING.md`); each prop writes its
149
+ token inline only when passed.
146
150
 
147
151
  | Property | Default | Set by prop |
148
152
  | -------- | ------- | ----------- |
149
- | `--_frame-height` | `540px` | `frameHeight` |
150
- | `--_parallax-offset` | `36rem` | `parallaxOffset` |
151
- | `--_radius` | `0px` | `radius` |
152
- | `--_focal-x` | `50%` | `focalX` |
153
+ | `--scroll-reveal-frame-height` | `540px` | `frameHeight` |
154
+ | `--scroll-reveal-frame-parallax-offset` | `36rem` | `parallaxOffset` |
155
+ | `--scroll-reveal-frame-radius` | `0px` | `radius` |
156
+ | `--scroll-reveal-image-focal-x` | `50%` | `focalX` |
157
+ | `--scroll-reveal-image-focal-y` | `0%` | none (CSS only) |
158
+ | `--scroll-reveal-image-focal-y-static` | `50%` | none (CSS only) |
159
+
160
+ Classes: root `.scroll-reveal-frame`, wrapper `.scroll-reveal-frame-content`, image
161
+ `.scroll-reveal-image` (renamed 2026-09-27 from `.reveal-frame`/`.reveal-content`/`.reveal-image`).
153
162
 
154
163
  ## Choosing parallaxOffset
155
164
 
@@ -160,5 +169,6 @@ See `scroll-reveal-frame.md` for the full guide. For portrait images the default
160
169
  - The root `<figure>` has `margin: 0` set in the component — browser default `<figure>` margins are neutralised at source.
161
170
  - `decoding="async"` is always set on the `<img>`. Use `:loading="'eager'"` if this component is the LCP image (e.g. a hero partially in view on load) — the default `"lazy"` is correct for below-fold usage.
162
171
  - Do not place inside a container with `overflow: hidden` or `overflow: clip` — breaks the `view-timeline` scroll detection inherited from `ScrollRevealFrame`.
163
- - Reduced-motion: animation is disabled and the image falls back to a static crop centred at `object-position: <focalX> 50%`.
172
+ - Reduced-motion: animation is disabled and the image falls back to a static crop at `object-position: <focal-x> <focal-y-static>` (default `50% 50%`).
173
+ - 2026-09-27 migration: `focalX` lost its `"50%"` default and now writes the public `--scroll-reveal-image-focal-x` only when passed (it was a private `--_focal-x`, always inline, so CSS could never change it). New `--scroll-reveal-image-focal-y`/`-focal-y-static` tokens replace the hardcoded vertical crop. Added CONSUMER-STYLING.md, snippet and a `CssTokens` story.
164
174
  - Storybook: the `"none"` image provider is active (`nuxt.config.ts`), so `src` paths pass through unchanged. Always provide explicit `img-width` and `img-height` props to avoid the `w=1536` fallback in deployed Storybook.
@@ -111,7 +111,7 @@ are delegated to the consumer, matching `ServiceSummary`'s slot-based routing pa
111
111
  :related-services="relatedServices"
112
112
  >
113
113
  <template #book-cta>
114
- <InputButtonCore tag="a" href="/contact" button-text="Book now" variant="primary" />
114
+ <InputButton tag="a" href="/contact" button-text="Book now" variant="primary" />
115
115
  </template>
116
116
  <template #sidebar-note>
117
117
  A patch test is required at least 48 hours before any colour treatment.
@@ -120,7 +120,7 @@ are delegated to the consumer, matching `ServiceSummary`'s slot-based routing pa
120
120
  <NuxtLink :to="`/services/${related.slug}`">{{ related.title }} — {{ related.price }}</NuxtLink>
121
121
  </template>
122
122
  <template #final-cta>
123
- <InputButtonCore tag="a" href="/contact" button-text="Book now" variant="secondary" />
123
+ <InputButton tag="a" href="/contact" button-text="Book now" variant="secondary" />
124
124
  </template>
125
125
  </ServiceDetail>
126
126
  ```
@@ -10,13 +10,14 @@
10
10
  | ----------------------- | --------------------------------- | -------------------------------- | -------- |
11
11
  | `servicesData` | `Service[]` | — | **yes** |
12
12
  | `tag` | `"div" \| "section" \| "main"` | `"div"` | no |
13
- | `eyebrowConfig` | `EyebrowConfig` | `{}` | no |
14
- | `heroConfig` | `HeroConfig` | `{}` | no |
13
+ | `eyebrowConfig` | `ServicesCardEyebrowConfig` | `{}` | no |
14
+ | `heroConfig` | `ServicesCardHeroConfig` | `{}` | no |
15
15
  | `hrefBase` | `string` | `"/services/"` | no |
16
16
  | `buttonTextPrefix` | `string` | `"Enquire about"` | no |
17
+ | `buttonIcon` | `string` | `"mdi:arrow-right"` | no |
17
18
  | `styleClassPassthrough` | `string \| string[]` | `[]` | no |
18
19
 
19
- Both config props are passed through to every `ServicesCard` in the grid unchanged. See [services-card.md](./services-card.md) for the full `EyebrowConfig` / `HeroConfig` key reference.
20
+ Both config props are passed through to every `ServicesCard` in the grid unchanged. See [services-card.md](./services-card.md) for the full key reference. The types are exported as `ServicesCardEyebrowConfig` / `ServicesCardHeroConfig` from `srcdev-nuxt-components` (were inline and not importable before 2026-09-28).
20
21
 
21
22
  ### Button link and text
22
23
 
@@ -104,6 +105,6 @@ if (servicesData.value.length === 0) {
104
105
 
105
106
  - Component is auto-imported in Nuxt — no import needed.
106
107
  - The `Service` type is imported from `~/types/types.services`.
107
- - Uses `repeat(auto-fit, minmax(var(--services-card-grid-column-min-width, 250px), 1fr))` — columns grow to fill available space and wrap when below the minimum width.
108
+ - Uses `repeat(auto-fit, minmax(min(var(--services-card-grid-column-min-width, 250px), 100%), 1fr))` (the `min(…, 100%)` stops a single column overflowing containers narrower than the minimum, fixed 2026-09-28) — columns grow to fill available space and wrap when below the minimum width.
108
109
  - The `#actions` slot template is passed down into each `ServicesCard`; `serviceData` is the scoped prop for the current iteration item.
109
110
  - Data fetching is the page's responsibility — pass an empty array as fallback while loading (`servicesData ?? []`).
@@ -12,8 +12,8 @@
12
12
  | `tag` | `"div" \| "section" \| "article"` | `"div"` | no |
13
13
  | `href` | `string` | `undefined` | no |
14
14
  | `external` | `boolean` | `false` | no |
15
- | `eyebrowConfig` | `EyebrowConfig` | `{}` | no |
16
- | `heroConfig` | `HeroConfig` | `{}` | no |
15
+ | `eyebrowConfig` | `ServicesCardEyebrowConfig` | `{}` | no |
16
+ | `heroConfig` | `ServicesCardHeroConfig` | `{}` | no |
17
17
  | `durationText` | `string` | `undefined` | no |
18
18
  | `priceText` | `string` | `undefined` | no |
19
19
  | `styleClassPassthrough` | `string \| string[]` | `[]` | no |
@@ -24,7 +24,7 @@ A row below the description shows duration (left) and price (right), separated b
24
24
 
25
25
  ### Whole-card clickable (`href`)
26
26
 
27
- When `href` is set **and no `actions` slot content is provided**, the root element switches from `tag` to a link (`NuxtLink` for an internal href starting with `/`, a plain `a` otherwise) and the whole card becomes clickable — matching `InputButtonCore`'s link-resolution pattern. `external` forces a plain `a` tag even for an internal-looking href (e.g. a Nitro server route like `/api/auth/github`).
27
+ When `href` is set **and no `actions` slot content is provided**, the root element switches from `tag` to a link (`NuxtLink` for an internal href starting with `/`, a plain `a` otherwise) and the whole card becomes clickable — matching `InputButton`'s link-resolution pattern. `external` forces a plain `a` tag even for an internal-looking href (e.g. a Nitro server route like `/api/auth/github`).
28
28
 
29
29
  If an `actions` slot is provided, the card stays as a static `tag` element (no href rendered) even when `href` is set — this avoids nesting another interactive element (e.g. a button/link in `actions`) inside the card's own anchor, which would be invalid HTML. Use the `href` mode for a plain "whole card links out" card with no separate CTA, and the `actions`-slot mode (see Basic usage below) when the card needs its own button/link.
30
30
 
@@ -32,6 +32,8 @@ If an `actions` slot is provided, the card stays as a static `tag` element (no h
32
32
 
33
33
  ### EyebrowConfig
34
34
 
35
+ Exported as `ServicesCardEyebrowConfig` (and `ServicesCardHeroConfig` below) from `srcdev-nuxt-components` since 2026-09-28.
36
+
35
37
  | Key | Type | Default |
36
38
  | ---------- | ---------------------------------- | --------- |
37
39
  | `tag` | `"p" \| "div" \| "span"` | `"div"` |
@@ -71,7 +73,7 @@ scaffold a style block using `styleClassPassthrough` instead — see
71
73
  ```vue
72
74
  <ServicesCard :service-data="service">
73
75
  <template #actions="{ serviceData }">
74
- <InputButtonCore
76
+ <InputButton
75
77
  variant="secondary"
76
78
  :button-text="`More about ${serviceData.title}`"
77
79
  :href="`/services/${serviceData.slug}`"
@@ -79,7 +81,7 @@ scaffold a style block using `styleClassPassthrough` instead — see
79
81
  <template #right>
80
82
  <Icon name="mdi:arrow-right" class="icon" />
81
83
  </template>
82
- </InputButtonCore>
84
+ </InputButton>
83
85
  </template>
84
86
  </ServicesCard>
85
87
  ```
@@ -93,7 +95,7 @@ scaffold a style block using `styleClassPassthrough` instead — see
93
95
  :hero-config="{ tag: 'h3', fontSize: 'title' }"
94
96
  >
95
97
  <template #actions="{ serviceData }">
96
- <InputButtonCore variant="secondary" :button-text="`Enquire`" :href="`/services/${serviceData.slug}`" />
98
+ <InputButton variant="secondary" :button-text="`Enquire`" :href="`/services/${serviceData.slug}`" />
97
99
  </template>
98
100
  </ServicesCard>
99
101
  ```
@@ -111,7 +113,7 @@ scaffold a style block using `styleClassPassthrough` instead — see
111
113
  <span>From {{ serviceData.price }}</span>
112
114
  </template>
113
115
  <template #actions="{ serviceData }">
114
- <InputButtonCore variant="secondary" :button-text="`Enquire`" :href="`/services/${serviceData.slug}`" />
116
+ <InputButton variant="secondary" :button-text="`Enquire`" :href="`/services/${serviceData.slug}`" />
115
117
  </template>
116
118
  </ServicesCard>
117
119
  ```
@@ -126,7 +128,7 @@ scaffold a style block using `styleClassPassthrough` instead — see
126
128
  :hero-config="{ tag: 'h2', fontSize: 'heading' }"
127
129
  >
128
130
  <template #actions="{ serviceData }">
129
- <InputButtonCore
131
+ <InputButton
130
132
  variant="secondary"
131
133
  :button-text="`Enquire about ${serviceData.title}`"
132
134
  :href="`/services/${serviceData.slug}`"
@@ -135,7 +137,7 @@ scaffold a style block using `styleClassPassthrough` instead — see
135
137
  <template #right>
136
138
  <Icon name="mdi:arrow-right" class="icon" />
137
139
  </template>
138
- </InputButtonCore>
140
+ </InputButton>
139
141
  </template>
140
142
  </ServicesCard>
141
143
  </template>
@@ -172,5 +174,5 @@ No `actions` slot — the entire card renders as an anchor (`NuxtLink` for the i
172
174
  - Root markup is two rows (`grid-template-rows: auto 1fr`): `.image-wrapper`, then a `.details-wrapper` (`display: flex; flex-direction: column`) holding the eyebrow, title, description, and a `.footer` wrapper. Description length is controlled by `--description-line-clamp` (default effectively unclamped) rather than a fixed-height grid row.
173
175
  - `.footer` groups the meta row and the `actions` slot and gets `margin-block-start: auto`, pinning them to the bottom of the card. Combined with the root's `1fr` details row, this means when `ServicesCardGrid`'s default `align-items: stretch` makes a card taller than its own content (to match a taller sibling in the same row), the extra height goes to `.footer`'s top margin rather than leaving whitespace below the actions slot — so the meta row and actions/button line up across a row of cards regardless of each card's description length. This does the visual job of CSS subgrid without needing a subgrid chain across `ServicesCard`/`ServicesCardGrid` (which would also break whenever cards in a row don't all render the same optional rows — `.meta` and `actions` are both conditional).
174
176
  - Image has a `3/4` aspect ratio with a subtle scale-on-hover effect.
175
- - `.services-card`, `.image-wrapper`, `.details-wrapper`, and `.footer` all set `min-inline-size: 0`. Without it, an unbreakable child — most commonly a long `actions` slot button label, since `InputButtonCore`'s `.button-text` is `white-space: nowrap` with no ellipsis — forces its content's min-content width up through the flex/grid chain and widens that one card's grid column in `ServicesCardGrid` wider than its siblings (the image just rides along on the widened column; it isn't the actual cause). If you see one card/column wider than the rest with cut-off content, check for a long unbreakable string in a slot before assuming it's an image sizing issue.
177
+ - `.services-card`, `.image-wrapper`, `.details-wrapper`, and `.footer` all set `min-inline-size: 0`. Without it, an unbreakable child — most commonly a long `actions` slot button label, since `InputButton`'s `.button-text` is `white-space: nowrap` with no ellipsis — forces its content's min-content width up through the flex/grid chain and widens that one card's grid column in `ServicesCardGrid` wider than its siblings (the image just rides along on the widened column; it isn't the actual cause). If you see one card/column wider than the rest with cut-off content, check for a long unbreakable string in a slot before assuming it's an image sizing issue.
176
178
  - Usually consumed via `ServicesCardGrid` rather than directly.
@@ -17,6 +17,8 @@ Both the horizontal list and the panel include animated active/hover indicator d
17
17
  | `navItemData` | `NavItemData` | — (required) | Navigation items — see type below |
18
18
  | `navAlign` | `"left" \| "center" \| "right"` | `"left"` | Alignment of the horizontal nav list |
19
19
  | `ariaLabel` | `string` | `"Site navigation"` | aria-label on the root `<nav>` landmark — override for localisation |
20
+ | `openMenuLabel` | `string` | `"Open navigation menu"` | Burger button text (screen-reader) while closed — override for localisation |
21
+ | `closeMenuLabel` | `string` | `"Close navigation menu"` | Burger button text (screen-reader) while open — override for localisation |
20
22
  | `styleClassPassthrough` | `string \| string[]` | `[]` | Extra classes applied to the root `<nav>` |
21
23
 
22
24
  ## NavItemData type
@@ -24,7 +26,7 @@ Both the horizontal list and the panel include animated active/hover indicator d
24
26
  **Within the layer:**
25
27
 
26
28
  ```ts
27
- import type { NavItemData } from "~/types/components/navigation-horizontal.d";
29
+ import type { NavItemData } from "~/types/components/nav-item.d";
28
30
  ```
29
31
 
30
32
  **In a consuming app:**
@@ -70,6 +72,8 @@ Set these tokens on a parent element (e.g. your `<header>`) to theme the navigat
70
72
  .your-header {
71
73
  /* ── Decorators ────────────────────────────────────── */
72
74
  --site-nav-decorator-indicator-color: var(--rose-05); /* underline bar */
75
+ --site-nav-decorator-hovered-bg: transparent; /* hover pill behind a link */
76
+ --site-nav-decorator-active-bg: transparent; /* active pill behind a link */
73
77
 
74
78
  /* ── Horizontal nav links ──────────────────────────── */
75
79
  --site-nav-link-color: var(--warm-01);
@@ -102,30 +106,40 @@ Set these tokens on a parent element (e.g. your `<header>`) to theme the navigat
102
106
  --site-nav-burger-gap: 5px;
103
107
  --site-nav-burger-transition: 300ms ease;
104
108
 
105
- /* ── Backdrop (teleported to <body>) ───────────────── */
109
+ }
110
+ ```
111
+
112
+ The backdrop is teleported to `<body>`, so its tokens only land when set on `:root`/`html`/`body`,
113
+ not on your header:
114
+
115
+ ```css
116
+ :where(html) {
106
117
  --site-nav-backdrop-bg: oklch(0% 0 0 / 55%);
107
118
  --site-nav-backdrop-blur: 3px;
108
119
  --site-nav-backdrop-duration: 350ms;
120
+ --site-nav-backdrop-z-index: 10; /* keep your header above this */
109
121
  }
110
122
  ```
111
123
 
124
+ Full reference: `app/components/02.molecules/navigation/site-navigation/CONSUMER-STYLING.md`.
125
+
112
126
  ## Behaviour notes
113
127
 
114
128
  - **Collapse detection**: `ResizeObserver` fires on every container resize. The list's `scrollWidth` is cached whenever the list is in the DOM; that cached value is compared against the container's `clientWidth` to set `isCollapsed`.
115
129
  - **isLoaded state**: The component uses `useState("site-nav-loaded")` — a Nuxt shared state — to gate visibility until the first measurement is complete, preventing a flash of the wrong nav state on load. The nav renders `opacity: 0` until `is-loaded` is applied.
116
130
  - **Teleport**: The backdrop overlay is teleported to `<body>` via `<Teleport>` and is only mounted when `isCollapsed && isLoaded`.
117
- - **Panel inert**: The `#site-nav-panel` div receives `:inert="!isMenuOpen ? true : undefined"` — it is inert (keyboard/pointer-inaccessible) when closed.
131
+ - **Panel inert**: The panel div (id `site-nav-panel-{useId}`, unique per instance) receives `:inert="!isMenuOpen ? true : undefined"` — it is inert (keyboard/pointer-inaccessible) when closed.
118
132
  - **Decorator init**: `initNavDecorators()` and `initPanelDecorators()` inject `<li>` elements with CSS-driven indicator `<div>`s. They query `[data-nav-item]` / `[data-panel-nav-item]` to find links, and look for `router-link-active` to set the initial active position.
119
133
 
120
134
  ## Accessibility
121
135
 
122
- - Root `<nav>` has `aria-label="Site navigation"`.
123
- - Burger button uses `aria-expanded` (string `"true"/"false"`) and `aria-controls="site-nav-panel"`.
136
+ - Root `<nav>` has `aria-label` from the `ariaLabel` prop (default `"Site navigation"`).
137
+ - Burger button text comes from `openMenuLabel`/`closeMenuLabel`, with `aria-expanded` (string `"true"/"false"`) and `aria-controls` pointing at the panel's per-instance id (was a fixed `site-nav-panel`, which collided when two navs were on one page; fixed 2026-09-27).
124
138
  - Backdrop and indicator `<li>` elements are `aria-hidden="true"`.
125
139
  - Panel div is `inert` when closed.
126
140
 
127
141
  ## Related files
128
142
 
129
- - Type: `app/types/components/navigation-horizontal.d.ts`
143
+ - Type: `app/types/components/nav-item.d.ts`
130
144
  - Tests: `app/components/02.molecules/navigation/site-navigation/tests/SiteNavigation.spec.ts`
131
145
  - Story: `app/components/02.molecules/navigation/site-navigation/stories/SiteNavigation.stories.ts`
@@ -0,0 +1,88 @@
1
+ # SliderGallery
2
+
3
+ ## Overview
4
+
5
+ `SliderGallery` (`03.organisms/image-galleries/slider-gallery`) is a full-screen image carousel:
6
+ a large slide with staggered text, a thumbnail strip that animates into place, prev/next arrows, a
7
+ progress bar, and optional auto-advance. It's `position: absolute; inset: 0` at `100svh × 100vw`,
8
+ so place it inside a positioned container sized for it (usually a full-viewport hero).
9
+
10
+ > **Changed 2026-09-28:** every inner class is now `slider-gallery-*` (was bare `.list`, `.item`,
11
+ > `.content`, `.title`, `.thumbnail`, `.arrows`, `.time` and so on, which collided with consumer CSS
12
+ > since the component renders inline). State classes are `.is-next`/`.is-prev`/`.is-prepended`/`.is-loaded`.
13
+ > The arrows lost their fixed `id="prev"`/`id="next"`. The dead "See more" `<button>` is now a link,
14
+ > rendered only for slides with an `href`. Auto-advance pauses on hover/focus and is off under
15
+ > reduced motion. Keyframes are prefixed `slider-gallery-*`.
16
+
17
+ ## Props
18
+
19
+ | Prop | Type | Default | Notes |
20
+ |---|---|---|---|
21
+ | `v-model:gallery-data` | `IGalleryData[]` | required | Slides (see type below) |
22
+ | `autoRun` | `boolean` | `true` | Auto-advance. Paused while hovered or focused; never runs under `prefers-reduced-motion: reduce` |
23
+ | `autoRunInterval` | `number` | `7000` | ms between auto-advances |
24
+ | `animationDuration` | `number` | `3000` | ms a transition locks the controls (also drives the progress bar) |
25
+ | `ariaLabel` | `string` | `"Image gallery"` | Carousel region label |
26
+ | `loadingText` | `string` | `"Loading gallery..."` | Loading-state copy |
27
+ | `seeMoreText` | `string` | `"SEE MORE"` | Link text for slides with an `href` |
28
+ | `prevAriaLabel` / `nextAriaLabel` | `string` | `"Previous image"` / `"Next image"` | Arrow button labels |
29
+ | `prevIcon` / `nextIcon` | `string` | `ic:outline-keyboard-arrow-left/right` | Arrow icons |
30
+ | `textScrim` | `boolean` | `true` | Fades in a gradient behind the active slide's text (slides with no stylist, title, category, description or href get none): dark behind `textBrightness: "light"` slides, light behind `"dark"` ones. Adds `.has-text-scrim` to the root. Styled by `--slider-gallery-text-light-scrim` / `--slider-gallery-text-dark-scrim` |
31
+ | `styleClassPassthrough` | `string \| string[]` | `[]` | Classes on the root. Reactive |
32
+
33
+ All copy props are there for localisation: pass translated strings.
34
+
35
+ ## IGalleryData
36
+
37
+ ```ts
38
+ import type { IGalleryData } from "srcdev-nuxt-components";
39
+
40
+ interface IGalleryData {
41
+ src: string;
42
+ alt: string;
43
+ stylist?: string; // small caps line above the title
44
+ title?: string;
45
+ category?: string; // second large line
46
+ description?: string;
47
+ thumbnail?: { title: string; description: string };
48
+ textBrightness: "light" | "dark"; // text colour over this image
49
+ href?: string; // renders a see-more link; omitted = no link
50
+ }
51
+ ```
52
+
53
+ ## Accessibility
54
+
55
+ - Root is `role="region"` + `aria-roledescription="carousel"` + `aria-label`.
56
+ - Arrow buttons have labels; ArrowLeft/ArrowRight work while focus is inside the gallery.
57
+ - The thumbnail strip is decorative duplicate content: `aria-hidden`, thumbnail images have empty `alt`.
58
+ - Loading block is `role="status"`; the progress bar is `aria-hidden`.
59
+ - Auto-advance meets WCAG 2.2.2 via pause-on-hover/focus, and is disabled under reduced motion (animations also collapse to near-instant there).
60
+
61
+ ## Usage
62
+
63
+ ```vue
64
+ <script setup lang="ts">
65
+ import type { IGalleryData } from "srcdev-nuxt-components";
66
+ const slides = ref<IGalleryData[]>([
67
+ { src: "/images/work-1.jpg", alt: "Balayage on long curls", title: "Balayage", textBrightness: "light", href: "/work/balayage" },
68
+ ]);
69
+ </script>
70
+
71
+ <template>
72
+ <div class="hero" style="position: relative; height: 100svh;">
73
+ <SliderGallery v-model:gallery-data="slides" aria-label="Recent work" />
74
+ </div>
75
+ </template>
76
+ ```
77
+
78
+ ## Styling
79
+
80
+ Public tokens (`--slider-gallery-*`) cover height, z-index, accent (spinner and progress), text
81
+ colours, thumbnail size/border/radius/overlay, arrow row position (base, tablet, desktop), arrow size, colours, border, outline (resting, hover and focus) and CTA colours. Full reference:
82
+ `app/components/03.organisms/image-galleries/slider-gallery/CONSUMER-STYLING.md`.
83
+
84
+ ## Notes
85
+
86
+ - Navigation moves real DOM nodes (append/prepend) rather than re-rendering, so don't key other
87
+ logic off the rendered order of `.slider-gallery-item`.
88
+ - `z-index` defaults to `9999` (`--slider-gallery-z-index`) because it's a full-screen takeover.
@@ -12,6 +12,7 @@
12
12
  |------|------|---------|-------|
13
13
  | `items` | `ISocialIcon[]` | — | **Required.** Array of social network items. |
14
14
  | `label` | `string` | `"Social media profiles"` | `aria-label` applied to the `<ul>` element. |
15
+ | `linkLabelTemplate` | `string` | `"{network} profile (opens in a new tab)"` | `aria-label` for each link; `{network}` is replaced with the item's `networkName`. |
15
16
  | `styleClassPassthrough` | `string \| string[]` | `[]` | Extra CSS classes applied to the root `<ul>`. |
16
17
 
17
18
  ---
@@ -20,7 +21,8 @@
20
21
 
21
22
  ```ts
22
23
  interface ISocialIcon {
23
- networkName: string; // Used as aria-label: "{networkName} profile"
24
+ networkName: string; // Fills {network} in the list's linkLabelTemplate
25
+ label?: string; // Optional per-item aria-label, overrides the template
24
26
  iconName: string; // Iconify icon name, e.g. "logos:instagram-icon"
25
27
  baseHref: string; // Base URL including trailing slash, e.g. "https://www.instagram.com/"
26
28
  profileId: string; // Profile identifier appended to baseHref
@@ -84,8 +86,12 @@ import type { ISocialIcon } from "srcdev-nuxt-components";
84
86
 
85
87
  | Property | Default | Notes |
86
88
  |----------|---------|-------|
87
- | `--theme-social-icon-size` | `2.4rem` | Width and height of each icon |
88
- | `--theme-social-icon-gap` | `1.2rem` | Gap between icons in the flex row |
89
+ | `--social-icons-list-icon-size` | `2.4rem` | Icon size (applied as `font-size`) |
90
+ | `--social-icons-list-gap` | `1.2rem` | Gap between icons in the flex row |
91
+ | `--social-icons-list-hover-scale` | `1.15` | Hover/focus scale (none under reduced motion) |
92
+ | `--social-icons-list-hover-opacity` | `0.85` | Hover/focus opacity |
93
+
94
+ > Renamed 2026-09-28 from `--theme-social-icon-size` / `--theme-social-icon-gap`. Full reference: `CONSUMER-STYLING.md` in the component folder.
89
95
 
90
96
  > **Note:** Iconify's `logos:*` styles are injected outside any CSS `@layer`, which means they override layered component styles. Icon sizing is applied via an inline `style` attribute on the `<Icon>` element so it takes precedence.
91
97
 
@@ -108,8 +114,8 @@ Offer this scaffold when placing the component in a consuming page or section. T
108
114
  ─────────────────────────────────────────────────────────────────── */
109
115
  .my-page-or-section {
110
116
  .social-icons-list {
111
- /* --theme-social-icon-size: 3.2rem; */
112
- /* --theme-social-icon-gap: 1.6rem; */
117
+ /* --social-icons-list-icon-size: 3.2rem; */
118
+ /* --social-icons-list-gap: 1.6rem; */
113
119
  /* margin-block-start: 1.6rem; */
114
120
 
115
121
  .social-icon-link {
@@ -130,6 +136,6 @@ need to target a specific instance. See `component-local-style-override.md` for
130
136
  ## Notes
131
137
 
132
138
  - All links open in a new tab with `rel="noopener noreferrer"`.
133
- - Each link carries `aria-label="{networkName} profile"` for screen reader accessibility.
139
+ - Each link's `aria-label` comes from `linkLabelTemplate` (default `"{network} profile (opens in a new tab)"`, `{network}` = `networkName`), or the item's own `label`. Pass a translated template for other languages. The icon is `aria-hidden`.
134
140
  - The `logos:*` Iconify collection requires `@iconify-json/logos` to be installed in the consumer app. Without it, icons will fall back to a CDN fetch (causing FOUC). See [icon-sets.md](../icon-sets.md).
135
141
  - Auto-imported in Nuxt — no manual import needed.
@@ -245,7 +245,7 @@ SSR and the very first client paint always render the **full, uncollapsed** `<ul
245
245
  swap is what shrinks the header and shifts everything below it.
246
246
 
247
247
  Confirmed via `PerformanceObserver({type: "layout-shift"})` plus DOM `MutationObserver` tracing in a
248
- consuming app (`luxury-locs-by-natasha-nuxt3`): the class mutation on `.tab-navigation` (adding
248
+ consuming app: the class mutation on `.tab-navigation` (adding
249
249
  `is-loaded is-animated`) lines up exactly with `.main-content`'s bounding-rect top moving by the
250
250
  header's full height delta, at a variable point (roughly 100ms–800ms after first paint depending on
251
251
  hydration timing) after first paint.
@@ -0,0 +1,68 @@
1
+ ---
2
+ name: TextBlock
3
+ description: TextBlock vertical-rhythm text wrapper — tag prop, fluid block padding tokens, heading-id slot prop for section/article aria-labelledby, styleClassPassthrough
4
+ type: reference
5
+ ---
6
+
7
+ # TextBlock
8
+
9
+ ## Overview
10
+
11
+ `TextBlock` wraps a block of text (typically a page lead: `EyebrowText` + `HeroText`/`HeaderBlock`
12
+ + intro copy) and gives it consistent fluid vertical padding. It has no layout of its own; put it
13
+ inside a `PageRow` for horizontal placement.
14
+
15
+ ## Props
16
+
17
+ | Prop | Type | Default | Description |
18
+ |------|------|---------|-------------|
19
+ | `tag` | `"div" \| "section" \| "article" \| "main"` | `"div"` | Root element. `section`/`article` get `aria-labelledby` (see below); `main` deliberately does not. |
20
+ | `styleClassPassthrough` | `string \| string[]` | `[]` | Extra classes on the root. Reactive: changing the prop swaps the classes. |
21
+
22
+ ## Slots
23
+
24
+ | Slot | Slot props | Description |
25
+ |------|-----------|-------------|
26
+ | `default` | `{ headingId: string }` | Content. Bind `headingId` to your heading's `id` when `tag` is `section`/`article`. |
27
+
28
+ ## Basic usage
29
+
30
+ ```vue
31
+ <PageRow tag="div" variant="content">
32
+ <TextBlock :style-class-passthrough="['page-lead']">
33
+ <EyebrowText text-content="Pricing" font-size="large" />
34
+ <HeroText … />
35
+ </TextBlock>
36
+ </PageRow>
37
+ ```
38
+
39
+ ## As a labelled landmark
40
+
41
+ With `tag="section"` or `tag="article"`, the root gets `aria-labelledby` from `useAriaLabelledById`.
42
+ Bind the `heading-id` slot prop to a real heading, or the landmark has no accessible name (a
43
+ dev-mode `console.warn` flags this):
44
+
45
+ ```vue
46
+ <TextBlock tag="section" v-slot="{ headingId }">
47
+ <HeaderBlock :id="headingId" :tag-level="2" :class-level="2">Our services</HeaderBlock>
48
+ <p>…</p>
49
+ </TextBlock>
50
+ ```
51
+
52
+ ## CSS tokens
53
+
54
+ | Token | Default |
55
+ |-------|---------|
56
+ | `--text-block-padding-block-start` | `var(--fluid-space-48-96)` |
57
+ | `--text-block-padding-block-end` | `var(--fluid-space-48-96)` |
58
+
59
+ See [CONSUMER-STYLING.md](../../../app/components/01.atoms/text-block/CONSUMER-STYLING.md).
60
+
61
+ ## History
62
+
63
+ - **Migrated 2026-09-25** (0/5 → 5/5): padding moved from hardcoded `--fluid-space-48-96` to the two
64
+ public tokens above (same defaults, no visual change); `section`/`article` now get
65
+ `aria-labelledby` plus the `heading-id` slot prop (previously an unnamed landmark);
66
+ `styleClassPassthrough` is now reactive to prop changes. Some consumer apps
67
+ redeclare `.text-block { padding-block-*: var(--fluid-space-48-96) }` in their
68
+ own pages; that duplicates the default and can be deleted.