srcdev-nuxt-components 9.4.12 → 9.5.1

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 (624) 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 +25 -6
  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 +36 -17
  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-toggle-switch.code-snippets +3 -1
  132. package/.vscode/srcdev-component-triple-toggle-switch.code-snippets +30 -0
  133. package/README.md +2 -2
  134. package/app/app.config.ts +10 -0
  135. package/app/assets/styles/setup/02.colours/_orange.css +11 -11
  136. package/app/assets/styles/setup/02.colours/_theme-params.css +2 -2
  137. package/app/assets/styles/setup/03.theming/_default.css +1 -22
  138. package/app/assets/styles/setup/03.theming/_theme-slots.css +1 -1
  139. package/app/assets/styles/setup/03.theming/_warning.css +8 -10
  140. package/app/assets/styles/setup/04.elements/forms/02.typography.css +0 -14
  141. package/app/assets/styles/setup/04.elements/forms/06.button-geometry.css +1 -1
  142. package/app/assets/styles/setup/index.css +1 -1
  143. package/app/components/01.atoms/alert-mask/AlertMaskCore.vue +23 -5
  144. package/app/components/01.atoms/alert-mask/CONSUMER-STYLING.md +23 -5
  145. package/app/components/01.atoms/alert-mask/stories/AlertMaskCore.stories.ts +45 -19
  146. package/app/components/01.atoms/alert-mask/tests/AlertMaskCore.spec.ts +35 -1
  147. package/app/components/01.atoms/animations/animated-svg-text/CONSUMER-STYLING.md +13 -0
  148. package/app/components/01.atoms/animations/clip-element/CONSUMER-STYLING.md +13 -0
  149. package/app/components/01.atoms/animations/clip-element/ClipElement.vue +2 -2
  150. package/app/components/01.atoms/animations/container-glow/CONSUMER-STYLING.md +26 -5
  151. package/app/components/01.atoms/animations/entry/.nuxt/app.config.mjs +21 -0
  152. package/app/components/01.atoms/animations/entry/.nuxt/components.d.ts +66 -0
  153. package/app/components/01.atoms/animations/entry/.nuxt/imports.d.ts +30 -0
  154. package/app/components/01.atoms/animations/entry/.nuxt/manifest/meta/test.json +1 -0
  155. package/app/components/01.atoms/animations/entry/.nuxt/types/app.config.d.ts +35 -0
  156. package/app/components/01.atoms/animations/entry/.nuxt/types/build.d.ts +23 -0
  157. package/app/components/01.atoms/animations/entry/.nuxt/types/builder-env.d.ts +1 -0
  158. package/app/components/01.atoms/animations/entry/.nuxt/types/components.d.ts +71 -0
  159. package/app/components/01.atoms/animations/entry/.nuxt/types/imports.d.ts +386 -0
  160. package/app/components/01.atoms/animations/entry/.nuxt/types/middleware.d.ts +11 -0
  161. package/app/components/01.atoms/animations/entry/.nuxt/types/modules.d.ts +79 -0
  162. package/app/components/01.atoms/animations/entry/.nuxt/types/nitro-layouts.d.ts +17 -0
  163. package/app/components/01.atoms/animations/entry/.nuxt/types/nitro-nuxt.d.ts +64 -0
  164. package/app/components/01.atoms/animations/entry/.nuxt/types/plugins.d.ts +29 -0
  165. package/app/components/01.atoms/animations/entry/.nuxt/types/runtime-config.d.ts +32 -0
  166. package/app/components/01.atoms/animations/entry/.nuxt/types/shared-imports.d.ts +10 -0
  167. package/app/components/01.atoms/animations/entry/.nuxt/types/vue-shim.d.ts +0 -0
  168. package/app/components/01.atoms/animations/entry/.nuxtrc +1 -0
  169. package/app/components/01.atoms/animations/entry/CONSUMER-STYLING.md +65 -0
  170. package/app/components/01.atoms/animations/entry/EntryAnimation.vue +6 -5
  171. package/app/components/01.atoms/animations/entry/node_modules/.cache/nuxt/chrome-workspace.json +1 -0
  172. package/app/components/01.atoms/animations/entry/node_modules/.cache/vite/client/vitest/da39a3ee5e6b4b0d3255bfef95601890afd80709/results.json +1 -0
  173. package/app/components/01.atoms/animations/entry/stories/EntryAnimation.stories.ts +1 -1
  174. package/app/components/01.atoms/animations/entry/tests/EntryAnimation.spec.ts +25 -0
  175. package/app/components/01.atoms/animations/glowing-border/CONSUMER-STYLING.md +24 -5
  176. package/app/components/01.atoms/animations/marquee-scroller/CONSUMER-STYLING.md +20 -0
  177. package/app/components/01.atoms/animations/rotating-carousel-image/CONSUMER-STYLING.md +17 -0
  178. package/app/components/01.atoms/animations/scroll-reveal-frame/CONSUMER-STYLING.md +77 -0
  179. package/app/components/01.atoms/animations/scroll-reveal-frame/ScrollRevealFrame.vue +37 -78
  180. package/app/components/01.atoms/animations/scroll-reveal-frame/stories/ScrollRevealFrame.stories.ts +48 -0
  181. package/app/components/01.atoms/animations/scroll-reveal-frame/tests/ScrollRevealFrame.spec.ts +40 -33
  182. package/app/components/01.atoms/animations/scroll-reveal-frame/tests/__snapshots__/ScrollRevealFrame.spec.ts.snap +4 -4
  183. package/app/components/01.atoms/animations/scroll-reveal-image/CONSUMER-STYLING.md +74 -0
  184. package/app/components/01.atoms/animations/scroll-reveal-image/ScrollRevealImage.vue +14 -44
  185. package/app/components/01.atoms/animations/scroll-reveal-image/stories/ScrollRevealImage.stories.ts +50 -1
  186. package/app/components/01.atoms/animations/scroll-reveal-image/tests/ScrollRevealImage.spec.ts +27 -20
  187. package/app/components/01.atoms/animations/scroll-reveal-image/tests/__snapshots__/ScrollRevealImage.spec.ts.snap +4 -4
  188. package/app/components/01.atoms/animations/section-parallax/CONSUMER-STYLING.md +21 -4
  189. package/app/components/01.atoms/animations/view-timeline/CONSUMER-STYLING.md +25 -0
  190. package/app/components/01.atoms/banner-video/CONSUMER-STYLING.md +12 -5
  191. package/app/components/01.atoms/canvas-switcher/CONSUMER-STYLING.md +20 -7
  192. package/app/components/01.atoms/canvas-switcher/CanvasSwitcher.vue +12 -7
  193. package/app/components/01.atoms/card/CONSUMER-STYLING.md +47 -42
  194. package/app/components/01.atoms/card/CardCore.vue +7 -17
  195. package/app/components/01.atoms/clipped-panel/CONSUMER-STYLING.md +13 -0
  196. package/app/components/01.atoms/content-wrappers/docs-pages/CONSUMER-STYLING.md +127 -0
  197. package/app/components/01.atoms/content-wrappers/docs-pages/ContentDocs.vue +44 -77
  198. package/app/components/01.atoms/content-wrappers/docs-pages/stories/ContentDocs.stories.ts +3 -3
  199. package/app/components/01.atoms/content-wrappers/layout-grid/dashboard-quad-grid/CONSUMER-STYLING.md +14 -1
  200. package/app/components/01.atoms/content-wrappers/layout-grid/dashboard-quad-grid/stories/DashboardQuadGrid.stories.ts +2 -0
  201. package/app/components/01.atoms/content-wrappers/layout-grid/dashboard-stats-grid/CONSUMER-STYLING.md +13 -0
  202. package/app/components/01.atoms/content-wrappers/layout-grid/dashboard-stats-grid/stories/DashboardStatsGrid.stories.ts +2 -0
  203. package/app/components/01.atoms/content-wrappers/layout-grid/layout-grid-by-cols/CONSUMER-STYLING.md +72 -0
  204. package/app/components/01.atoms/content-wrappers/layout-grid/layout-grid-by-cols/LayoutGridByCols.vue +26 -25
  205. package/app/components/01.atoms/content-wrappers/layout-grid/layout-grid-by-cols/stories/LayoutGridByCols.stories.ts +91 -107
  206. package/app/components/01.atoms/content-wrappers/layout-grid/layout-grid-by-cols/tests/LayoutGridByCols.spec.ts +50 -15
  207. package/app/components/01.atoms/content-wrappers/layout-grid/layout-grid-by-cols/tests/__snapshots__/LayoutGridByCols.spec.ts.snap +5 -5
  208. package/app/components/01.atoms/display-banner/CONSUMER-STYLING.md +13 -0
  209. package/app/components/01.atoms/display-dialog/CONSUMER-STYLING.md +82 -54
  210. package/app/components/01.atoms/display-dialog/DisplayDialog.vue +38 -45
  211. package/app/components/01.atoms/display-dialog/stories/DisplayDialog.stories.ts +25 -0
  212. package/app/components/01.atoms/display-dialog/tests/DisplayDialog.spec.ts +21 -0
  213. package/app/components/01.atoms/display-pill/CONSUMER-STYLING.md +112 -0
  214. package/app/components/01.atoms/display-pill/DisplayPill.vue +88 -50
  215. package/app/components/01.atoms/display-pill/stories/DisplayPill.stories.ts +56 -3
  216. package/app/components/01.atoms/display-pill/tests/DisplayPill.spec.ts +104 -4
  217. package/app/components/01.atoms/display-pill/tests/__snapshots__/DisplayPill.spec.ts.snap +3 -3
  218. package/app/components/01.atoms/display-tooltip/CONSUMER-STYLING.md +22 -2
  219. package/app/components/01.atoms/display-tooltip/DisplayTooltip.vue +18 -26
  220. package/app/components/01.atoms/glass-panel/CONSUMER-STYLING.md +91 -0
  221. package/app/components/01.atoms/glass-panel/GlassPanel.vue +34 -30
  222. package/app/components/01.atoms/glass-panel/stories/GlassPanel.stories.ts +121 -0
  223. package/app/components/01.atoms/glass-panel/tests/GlassPanel.spec.ts +61 -0
  224. package/app/components/01.atoms/grids/auto-grid/AutoGrid.vue +5 -10
  225. package/app/components/01.atoms/grids/auto-grid/CONSUMER-STYLING.md +76 -0
  226. package/app/components/01.atoms/grids/auto-grid/stories/AutoGrid.stories.ts +5 -4
  227. package/app/components/01.atoms/grids/auto-grid/tests/AutoGrid.spec.ts +8 -0
  228. package/app/components/01.atoms/grids/column-flow-grid/CONSUMER-STYLING.md +11 -2
  229. package/app/components/01.atoms/grids/grid-stack/CONSUMER-STYLING.md +76 -0
  230. package/app/components/01.atoms/grids/grid-stack/GridStack.vue +6 -1
  231. package/app/components/01.atoms/grids/grid-stack/stories/GridStack.stories.ts +1 -1
  232. package/app/components/01.atoms/grids/grid-stack/tests/GridStack.spec.ts +35 -0
  233. package/app/components/01.atoms/grids/masonry-grid/CONSUMER-STYLING.md +11 -2
  234. package/app/components/01.atoms/navigation/breadcrumb/Breadcrumb.vue +5 -10
  235. package/app/components/01.atoms/navigation/breadcrumb/CONSUMER-STYLING.md +15 -0
  236. package/app/components/01.atoms/navigation/skip-links/CONSUMER-STYLING.md +13 -0
  237. package/app/components/01.atoms/navigation/tabs/CONSUMER-STYLING.md +21 -0
  238. package/app/components/01.atoms/page-row/CONSUMER-STYLING.md +46 -8
  239. package/app/components/01.atoms/page-row/PageRow.vue +17 -13
  240. package/app/components/01.atoms/page-row/stories/PageRow.stories.ts +8 -0
  241. package/app/components/01.atoms/page-row/tests/PageRow.spec.ts +7 -11
  242. package/app/components/01.atoms/pop-over/CONSUMER-STYLING.md +13 -0
  243. package/app/components/01.atoms/qr-code/CONSUMER-STYLING.md +48 -0
  244. package/app/components/01.atoms/qr-code/DisplayQrCode.vue +5 -1
  245. package/app/components/01.atoms/qr-code/stories/DisplayQrCode.stories.ts +11 -3
  246. package/app/components/01.atoms/qr-code/tests/DisplayQrCode.spec.ts +15 -0
  247. package/app/components/01.atoms/text-block/CONSUMER-STYLING.md +49 -0
  248. package/app/components/01.atoms/text-block/TextBlock.vue +13 -5
  249. package/app/components/01.atoms/text-block/stories/TextBlock.stories.ts +84 -0
  250. package/app/components/01.atoms/text-block/tests/TextBlock.spec.ts +78 -0
  251. package/app/components/01.atoms/text-block/tests/__snapshots__/TextBlock.spec.ts.snap +7 -0
  252. package/app/components/01.atoms/text-blocks/eyebrow-text/CONSUMER-STYLING.md +56 -0
  253. package/app/components/01.atoms/text-blocks/eyebrow-text/EyebrowText.vue +10 -5
  254. package/app/components/01.atoms/text-blocks/eyebrow-text/tests/EyebrowText.spec.ts +11 -0
  255. package/app/components/01.atoms/text-blocks/header-block/CONSUMER-STYLING.md +16 -1
  256. package/app/components/01.atoms/text-blocks/hero-text/CONSUMER-STYLING.md +74 -0
  257. package/app/components/01.atoms/text-blocks/hero-text/HeroText.vue +14 -9
  258. package/app/components/01.atoms/text-blocks/hero-text/tests/HeroText.spec.ts +11 -0
  259. package/app/components/01.atoms/text-blocks/link-text/CONSUMER-STYLING.md +45 -0
  260. package/app/components/01.atoms/text-blocks/link-text/LinkText.vue +15 -8
  261. package/app/components/01.atoms/text-blocks/link-text/tests/LinkText.spec.ts +11 -0
  262. package/app/components/01.atoms/ui-block-decorated/CONSUMER-STYLING.md +13 -0
  263. package/app/components/02.molecules/action-menu/ActionMenu.vue +28 -30
  264. package/app/components/02.molecules/action-menu/{ActionMenuItemCore.vue → ActionMenuItem.vue} +12 -14
  265. package/app/components/02.molecules/action-menu/CONSUMER-STYLING.md +90 -76
  266. package/app/components/02.molecules/action-menu/stories/ActionMenu.stories.ts +48 -41
  267. package/app/components/02.molecules/action-menu/tests/ActionMenu.spec.ts +46 -1
  268. package/app/components/02.molecules/action-menu/tests/{ActionMenuItemCore.spec.ts → ActionMenuItem.spec.ts} +11 -5
  269. package/app/components/02.molecules/action-menu/tests/__snapshots__/ActionMenuItem.spec.ts.snap +27 -0
  270. package/app/components/02.molecules/alert-content/AlertContent.vue +17 -8
  271. package/app/components/02.molecules/alert-content/AlertContentInner.vue +57 -30
  272. package/app/components/02.molecules/alert-content/CONSUMER-STYLING.md +84 -0
  273. package/app/components/02.molecules/alert-content/stories/AlertContent.stories.ts +39 -0
  274. package/app/components/02.molecules/alert-content/tests/AlertContent.spec.ts +32 -0
  275. package/app/components/02.molecules/alert-content/tests/AlertContentInner.spec.ts +32 -0
  276. package/app/components/02.molecules/alert-masked-content/AlertMaskedContent.vue +9 -5
  277. package/app/components/02.molecules/alert-masked-content/CONSUMER-STYLING.md +73 -0
  278. package/app/components/02.molecules/alert-masked-content/stories/AlertMaskedContent.stories.ts +91 -10
  279. package/app/components/02.molecules/alert-masked-content/tests/AlertMaskedContent.spec.ts +52 -0
  280. package/app/components/02.molecules/cookie-consent-banner/CONSUMER-STYLING.md +95 -0
  281. package/app/components/02.molecules/cookie-consent-banner/CookieConsentBanner.vue +149 -0
  282. package/app/components/{01.atoms → 02.molecules}/cookie-consent-banner/stories/CookieConsentBanner.stories.ts +22 -3
  283. package/app/components/{01.atoms → 02.molecules}/cookie-consent-banner/tests/CookieConsentBanner.spec.ts +81 -4
  284. package/app/components/02.molecules/display-avatar/CONSUMER-STYLING.md +63 -0
  285. package/app/components/02.molecules/display-avatar/DisplayAvatar.vue +120 -0
  286. package/app/components/{01.atoms → 02.molecules}/display-avatar/stories/DisplayAvatar.stories.ts +56 -14
  287. package/app/components/{01.atoms → 02.molecules}/display-avatar/tests/DisplayAvatar.spec.ts +43 -11
  288. package/app/components/02.molecules/display-avatar/tests/__snapshots__/DisplayAvatar.spec.ts.snap +11 -0
  289. package/app/components/02.molecules/display-chip/CONSUMER-STYLING.md +57 -0
  290. package/app/components/02.molecules/display-chip/DisplayChip.vue +50 -83
  291. package/app/components/02.molecules/display-chip/tests/DisplayChip.spec.ts +10 -10
  292. package/app/components/02.molecules/display-chip/tests/__snapshots__/DisplayChip.spec.ts.snap +4 -4
  293. package/app/components/02.molecules/display-theme-switch/CONSUMER-STYLING.md +25 -4
  294. package/app/components/02.molecules/display-theme-switch/DisplayThemeSwitch.vue +9 -6
  295. package/app/components/02.molecules/display-theme-switch/stories/DisplayThemeSwitch.stories.ts +6 -1
  296. package/app/components/02.molecules/display-theme-switch/tests/DisplayThemeSwitch.spec.ts +10 -1
  297. package/app/components/02.molecules/display-tooltip-defined/CONSUMER-STYLING.md +11 -0
  298. package/app/components/02.molecules/expandable/accordian/CONSUMER-STYLING.md +11 -4
  299. package/app/components/02.molecules/expandable/expanding-panel/CONSUMER-STYLING.md +12 -5
  300. package/app/components/02.molecules/expandable/expanding-panel-classic/CONSUMER-STYLING.md +12 -5
  301. package/app/components/02.molecules/input-copy/CONSUMER-STYLING.md +12 -5
  302. package/app/components/02.molecules/input-copy/InputCopy.vue +12 -25
  303. package/app/components/02.molecules/input-copy/stories/InputCopy.stories.ts +1 -1
  304. package/app/components/02.molecules/input-copy/tests/InputCopy.spec.ts +1 -1
  305. package/app/components/02.molecules/navigation/deep-expanding-menu/CONSUMER-STYLING.md +13 -0
  306. package/app/components/02.molecules/navigation/deep-expanding-menu-classic/CONSUMER-STYLING.md +11 -0
  307. package/app/components/02.molecules/navigation/site-navigation/CONSUMER-STYLING.md +109 -0
  308. package/app/components/02.molecules/navigation/site-navigation/SiteNavigation.vue +37 -55
  309. package/app/components/02.molecules/navigation/site-navigation/stories/SiteNavigation.stories.ts +22 -1
  310. package/app/components/02.molecules/navigation/site-navigation/tests/SiteNavigation.spec.ts +41 -6
  311. package/app/components/02.molecules/navigation/tab-navigation/CONSUMER-STYLING.md +13 -8
  312. package/app/components/02.molecules/navigation/tab-navigation/TabNavigation.vue +18 -36
  313. package/app/components/02.molecules/navigation/tab-navigation/stories/TabNavigation.stories.ts +1 -1
  314. package/app/components/02.molecules/navigation/tab-navigation/tests/TabNavigation.spec.ts +1 -1
  315. package/app/components/02.molecules/opening-hours/CONSUMER-STYLING.md +134 -0
  316. package/app/components/02.molecules/opening-hours/OpeningHours.vue +352 -0
  317. package/app/components/02.molecules/opening-hours/stories/OpeningHours.stories.ts +127 -0
  318. package/app/components/02.molecules/opening-hours/tests/OpeningHours.spec.ts +228 -0
  319. package/app/components/02.molecules/opening-hours/tests/OpeningHours.structuredData.spec.ts +45 -0
  320. package/app/components/02.molecules/opening-hours/tests/__snapshots__/OpeningHours.spec.ts.snap +23 -0
  321. package/app/components/02.molecules/opening-hours/tests/buildOpeningHoursSpecification.spec.ts +52 -0
  322. package/app/components/02.molecules/price-list/CONSUMER-STYLING.md +106 -0
  323. package/app/components/02.molecules/price-list/PriceList.vue +48 -40
  324. package/app/components/02.molecules/price-list/stories/PriceList.stories.ts +15 -2
  325. package/app/components/02.molecules/price-list/tests/PriceList.spec.ts +39 -2
  326. package/app/components/02.molecules/price-list/tests/__snapshots__/PriceList.spec.ts.snap +4 -16
  327. package/app/components/02.molecules/pricing-card/CONSUMER-STYLING.md +12 -5
  328. package/app/components/02.molecules/pricing-card/PricingCard.vue +28 -60
  329. package/app/components/02.molecules/pricing-card/tests/PricingCard.spec.ts +1 -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 +26 -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} +25 -12
  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 +2 -4
  491. package/app/components/05.forms/toggle-switch/stories/ToggleSwitchWithLabelInline.stories.ts +4 -1
  492. package/app/components/05.forms/toggle-switch/tests/ToggleSwitchWithLabel.spec.ts +133 -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/toggle-switch/variants/tests/ToggleSwitchWithLabel.spec.ts +0 -77
  561. package/app/components/05.forms/triple-toggle-switch/TripleToggleSwitchCore.vue +0 -314
  562. package/app/components/05.forms/triple-toggle-switch/stories/TripleToggleSwitchCore.stories.ts +0 -63
  563. package/.vscode/{srcdev-component-dialog.code-snippets → srcdev-component-display-dialog.code-snippets} +0 -0
  564. package/app/components/{01.atoms → 02.molecules}/toast/tests/DisplayToast.spec.ts +1 -1
  565. /package/app/components/{01.atoms → 02.molecules}/toast/tests/DisplayToastProvider.spec.ts +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-chromium-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-firefox-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-secondary-webkit-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-chromium-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-firefox-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-icons-tertiary-webkit-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-chromium-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-firefox-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-primary-pending-webkit-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-chromium-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-firefox-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-secondary-pill-webkit-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-chromium-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-firefox-darwin.png +0 -0
  580. /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
  581. /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
  582. /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
  583. /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
  584. /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
  585. /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
  586. /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
  587. /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
  588. /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
  589. /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
  590. /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
  591. /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
  592. /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
  593. /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
  594. /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
  595. /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
  596. /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
  597. /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
  598. /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
  599. /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
  600. /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
  601. /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
  602. /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
  603. /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
  604. /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
  605. /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
  606. /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
  607. /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
  608. /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
  609. /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
  610. /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
  611. /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
  612. /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
  613. /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
  614. /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
  615. /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
  616. /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
  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-chromium-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-firefox-darwin.png +0 -0
  619. /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
  620. /package/app/components/05.forms/input-range/{variants/stories → stories}/InputRangeDefault.stories.ts +0 -0
  621. /package/app/components/05.forms/input-select/{variants/tests → tests}/InputSelectWithLabel.spec.ts +0 -0
  622. /package/app/components/05.forms/input-textarea/{variants/tests → tests}/InputTextareaWithLabel.spec.ts +0 -0
  623. /package/app/components/05.forms/toggle-switch/{variants/tests → tests}/ToggleSwitchWithLabelInline.spec.ts +0 -0
  624. /package/app/types/components/{navigation-horizontal.d.ts → nav-item.d.ts} +0 -0
@@ -164,3 +164,51 @@ export const ShortFrame: Story = {
164
164
  },
165
165
  },
166
166
  };
167
+
168
+ export const ResponsiveTokens: Story = {
169
+ args: {},
170
+ render: (args) => ({
171
+ components: { ScrollRevealFrame },
172
+ setup() {
173
+ return { args };
174
+ },
175
+ template: `
176
+ <div style="padding-block: 60vh; max-width: 860px; margin-inline: auto;">
177
+ <component is="style">
178
+ .srf-story-responsive {
179
+ --scroll-reveal-frame-height: 280px;
180
+ --scroll-reveal-frame-parallax-offset: 18rem;
181
+ --scroll-reveal-frame-radius: 0.8rem;
182
+ }
183
+ @media (width >= 768px) {
184
+ .srf-story-responsive {
185
+ --scroll-reveal-frame-height: 540px;
186
+ --scroll-reveal-frame-parallax-offset: 36rem;
187
+ --scroll-reveal-frame-radius: 2.4rem;
188
+ }
189
+ }
190
+ </component>
191
+ <p style="text-align: center; font-size: 1.4rem; opacity: 0.5; margin-block-end: 4rem;">
192
+ Resize below/above 768px and scroll: height, travel and radius come from CSS tokens, no props passed
193
+ </p>
194
+ <div class="srf-story-responsive">
195
+ <ScrollRevealFrame v-bind="args">
196
+ <img
197
+ src="/images/page/hero/hero-blonde.jpg"
198
+ alt="Blonde hair portrait"
199
+ style="display: block; width: 100%; height: 100%; object-fit: cover;"
200
+ />
201
+ </ScrollRevealFrame>
202
+ </div>
203
+ </div>
204
+ `,
205
+ }),
206
+ parameters: {
207
+ docs: {
208
+ description: {
209
+ story:
210
+ "No sizing props are passed, so the frame reads --scroll-reveal-frame-height/-parallax-offset/-radius from an ancestor class with a media query. A prop, when passed, is written inline and wins over these.",
211
+ },
212
+ },
213
+ },
214
+ };
@@ -2,6 +2,8 @@ import { describe, it, expect } from "vitest";
2
2
  import { mountSuspended } from "@nuxt/test-utils/runtime";
3
3
  import ScrollRevealFrame from "../ScrollRevealFrame.vue";
4
4
 
5
+ const styleOf = (el: Element) => (el as HTMLElement).style;
6
+
5
7
  describe("ScrollRevealFrame", () => {
6
8
  // ─── Mount ───────────────────────────────────────────────────────────────
7
9
 
@@ -36,80 +38,85 @@ describe("ScrollRevealFrame", () => {
36
38
  expect(wrapper.element.tagName).toBe("FIGURE");
37
39
  });
38
40
 
39
- it("always has the reveal-frame class", async () => {
41
+ it("always has the scroll-reveal-frame class", async () => {
40
42
  const wrapper = await mountSuspended(ScrollRevealFrame);
41
- expect(wrapper.classes()).toContain("reveal-frame");
43
+ expect(wrapper.classes()).toContain("scroll-reveal-frame");
42
44
  });
43
45
 
44
46
  // ─── Inner content wrapper ───────────────────────────────────────────────
45
47
 
46
- it("renders a .reveal-content child element", async () => {
48
+ it("renders a .scroll-reveal-frame-content child element", async () => {
47
49
  const wrapper = await mountSuspended(ScrollRevealFrame);
48
- expect(wrapper.find(".reveal-content").exists()).toBe(true);
50
+ expect(wrapper.find(".scroll-reveal-frame-content").exists()).toBe(true);
49
51
  });
50
52
 
51
53
  // ─── Slot ────────────────────────────────────────────────────────────────
52
54
 
53
- it("renders slot content inside .reveal-content", async () => {
55
+ it("renders slot content inside .scroll-reveal-frame-content", async () => {
54
56
  const wrapper = await mountSuspended(ScrollRevealFrame, {
55
57
  slots: { default: "<p class='slot-child'>Hello</p>" },
56
58
  });
57
- const content = wrapper.find(".reveal-content");
59
+ const content = wrapper.find(".scroll-reveal-frame-content");
58
60
  expect(content.find(".slot-child").exists()).toBe(true);
59
61
  expect(content.find(".slot-child").text()).toBe("Hello");
60
62
  });
61
63
 
62
- it("renders multiple slot children inside .reveal-content", async () => {
64
+ it("renders multiple slot children inside .scroll-reveal-frame-content", async () => {
63
65
  const wrapper = await mountSuspended(ScrollRevealFrame, {
64
66
  slots: { default: "<div class='child-a'></div><div class='child-b'></div>" },
65
67
  });
66
- const content = wrapper.find(".reveal-content");
68
+ const content = wrapper.find(".scroll-reveal-frame-content");
67
69
  expect(content.find(".child-a").exists()).toBe(true);
68
70
  expect(content.find(".child-b").exists()).toBe(true);
69
71
  });
70
72
 
71
73
  // ─── CSS custom properties ───────────────────────────────────────────────
72
74
 
73
- it("sets --_frame-height to 540px by default", async () => {
75
+ it("sets no inline tokens by default, so CSS overrides and defaults apply", async () => {
74
76
  const wrapper = await mountSuspended(ScrollRevealFrame);
75
- const style = (wrapper.element as HTMLElement).style;
76
- expect(style.getPropertyValue("--_frame-height")).toBe("540px");
77
+ const style = styleOf(wrapper.element);
78
+ expect(style.getPropertyValue("--scroll-reveal-frame-height")).toBe("");
79
+ expect(style.getPropertyValue("--scroll-reveal-frame-parallax-offset")).toBe("");
80
+ expect(style.getPropertyValue("--scroll-reveal-frame-radius")).toBe("");
81
+ expect(wrapper.attributes("style")).toBeUndefined();
77
82
  });
78
83
 
79
- it("sets --_parallax-offset to 36rem by default", async () => {
80
- const wrapper = await mountSuspended(ScrollRevealFrame);
81
- const style = (wrapper.element as HTMLElement).style;
82
- expect(style.getPropertyValue("--_parallax-offset")).toBe("36rem");
84
+ it("reflects frameHeight prop in --scroll-reveal-frame-height", async () => {
85
+ const wrapper = await mountSuspended(ScrollRevealFrame, {
86
+ props: { frameHeight: "80vh" },
87
+ });
88
+ expect(styleOf(wrapper.element).getPropertyValue("--scroll-reveal-frame-height")).toBe("80vh");
83
89
  });
84
90
 
85
- it("sets --_radius to 0px by default", async () => {
86
- const wrapper = await mountSuspended(ScrollRevealFrame);
87
- const style = (wrapper.element as HTMLElement).style;
88
- expect(style.getPropertyValue("--_radius")).toBe("0px");
91
+ it("reflects parallaxOffset prop in --scroll-reveal-frame-parallax-offset", async () => {
92
+ const wrapper = await mountSuspended(ScrollRevealFrame, {
93
+ props: { parallaxOffset: "48rem" },
94
+ });
95
+ expect(styleOf(wrapper.element).getPropertyValue("--scroll-reveal-frame-parallax-offset")).toBe("48rem");
89
96
  });
90
97
 
91
- it("reflects frameHeight prop in --_frame-height", async () => {
98
+ it("reflects radius prop in --scroll-reveal-frame-radius", async () => {
92
99
  const wrapper = await mountSuspended(ScrollRevealFrame, {
93
- props: { frameHeight: "80vh" },
100
+ props: { radius: "2.4rem" },
94
101
  });
95
- const style = (wrapper.element as HTMLElement).style;
96
- expect(style.getPropertyValue("--_frame-height")).toBe("80vh");
102
+ expect(styleOf(wrapper.element).getPropertyValue("--scroll-reveal-frame-radius")).toBe("2.4rem");
97
103
  });
98
104
 
99
- it("reflects parallaxOffset prop in --_parallax-offset", async () => {
105
+ it("only sets the tokens whose props were passed", async () => {
100
106
  const wrapper = await mountSuspended(ScrollRevealFrame, {
101
- props: { parallaxOffset: "48rem" },
107
+ props: { radius: "1rem" },
102
108
  });
103
- const style = (wrapper.element as HTMLElement).style;
104
- expect(style.getPropertyValue("--_parallax-offset")).toBe("48rem");
109
+ const style = styleOf(wrapper.element);
110
+ expect(style.getPropertyValue("--scroll-reveal-frame-radius")).toBe("1rem");
111
+ expect(style.getPropertyValue("--scroll-reveal-frame-height")).toBe("");
105
112
  });
106
113
 
107
- it("reflects radius prop in --_radius", async () => {
114
+ it("removes the inline token when the prop is cleared", async () => {
108
115
  const wrapper = await mountSuspended(ScrollRevealFrame, {
109
- props: { radius: "2.4rem" },
116
+ props: { frameHeight: "400px" },
110
117
  });
111
- const style = (wrapper.element as HTMLElement).style;
112
- expect(style.getPropertyValue("--_radius")).toBe("2.4rem");
118
+ await wrapper.setProps({ frameHeight: undefined });
119
+ expect(styleOf(wrapper.element).getPropertyValue("--scroll-reveal-frame-height")).toBe("");
113
120
  });
114
121
 
115
122
  // ─── styleClassPassthrough ───────────────────────────────────────────────
@@ -129,11 +136,11 @@ describe("ScrollRevealFrame", () => {
129
136
  expect(wrapper.classes()).toContain("mbe-32");
130
137
  });
131
138
 
132
- it("does not apply styleClassPassthrough to .reveal-content", async () => {
139
+ it("does not apply styleClassPassthrough to .scroll-reveal-frame-content", async () => {
133
140
  const wrapper = await mountSuspended(ScrollRevealFrame, {
134
141
  props: { styleClassPassthrough: "hero-frame" },
135
142
  });
136
- expect(wrapper.find(".reveal-content").classes()).not.toContain("hero-frame");
143
+ expect(wrapper.find(".scroll-reveal-frame-content").classes()).not.toContain("hero-frame");
137
144
  });
138
145
 
139
146
  it("updates classes when styleClassPassthrough prop changes", async () => {
@@ -1,13 +1,13 @@
1
1
  // Vitest Snapshot v1, https://vitest.dev/guide/snapshot.html
2
2
 
3
3
  exports[`ScrollRevealFrame > renders correct HTML structure (all props set) 1`] = `
4
- "<figure class="reveal-frame custom-class" style="--_frame-height: 400px; --_parallax-offset: 20rem; --_radius: 1.6rem;">
5
- <div class="reveal-content"></div>
4
+ "<figure class="scroll-reveal-frame custom-class" style="--scroll-reveal-frame-height: 400px; --scroll-reveal-frame-parallax-offset: 20rem; --scroll-reveal-frame-radius: 1.6rem;">
5
+ <div class="scroll-reveal-frame-content"></div>
6
6
  </figure>"
7
7
  `;
8
8
 
9
9
  exports[`ScrollRevealFrame > renders correct HTML structure (default props) 1`] = `
10
- "<figure class="reveal-frame" style="--_frame-height: 540px; --_parallax-offset: 36rem; --_radius: 0px;">
11
- <div class="reveal-content"></div>
10
+ "<figure class="scroll-reveal-frame">
11
+ <div class="scroll-reveal-frame-content"></div>
12
12
  </figure>"
13
13
  `;
@@ -0,0 +1,74 @@
1
+ # ScrollRevealImage — Consumer Styling Guide
2
+
3
+ `ScrollRevealImage` renders a `ScrollRevealFrame` with a single `NuxtImg` inside. Frame sizing uses
4
+ the frame's own tokens; this component adds the image crop tokens.
5
+
6
+ ## Public token API
7
+
8
+ ### Frame (from ScrollRevealFrame)
9
+
10
+ | Token | Default | Set by prop |
11
+ |---|---|---|
12
+ | `--scroll-reveal-frame-height` | `540px` | `frameHeight` |
13
+ | `--scroll-reveal-frame-parallax-offset` | `36rem` | `parallaxOffset` |
14
+ | `--scroll-reveal-frame-radius` | `0px` | `radius` |
15
+
16
+ See `ScrollRevealFrame`'s `CONSUMER-STYLING.md` for details.
17
+
18
+ ### Image crop
19
+
20
+ | Token | Default | Set by prop | Controls |
21
+ |---|---|---|---|
22
+ | `--scroll-reveal-image-focal-x` | `50%` | `focalX` | Horizontal `object-position` (which slice stays in view when the frame is narrower than the image) |
23
+ | `--scroll-reveal-image-focal-y` | `0%` | none | Vertical `object-position` while the scroll animation runs |
24
+ | `--scroll-reveal-image-focal-y-static` | `50%` | none | Vertical `object-position` when there's no animation (reduced motion, or no `animation-timeline` support) |
25
+
26
+ A prop, when passed, writes its token inline on the root `<figure>` and beats any CSS. None of the
27
+ props has a default of its own, so leave one off to control that value from CSS.
28
+
29
+ > **Changed 2026-09-27**: the horizontal crop was a private `--_focal-x`, always written inline from
30
+ > a `focalX` prop that defaulted to `50%`, so CSS could never change it. The vertical crop was
31
+ > hardcoded (`0%` animated, `50%` static) with no token at all, which pushed consumers into
32
+ > overriding `object-position` on the image directly. Both are now public tokens.
33
+
34
+ Private tokens (not public API): `--_focal-x` on the image, which resolves the public focal-x once
35
+ for the three `object-position` declarations.
36
+
37
+ ## State hooks
38
+
39
+ No `data-*` attributes. Classes:
40
+
41
+ - `.scroll-reveal-frame`: the root `<figure>` (from `ScrollRevealFrame`).
42
+ - `.scroll-reveal-frame-content`: the panning wrapper (from `ScrollRevealFrame`).
43
+ - `.scroll-reveal-image`: the `<img>`.
44
+
45
+ > **Changed 2026-09-27**: `.reveal-image` → `.scroll-reveal-image` (with the frame's
46
+ > `.reveal-frame`/`.reveal-content` renames in the same release).
47
+
48
+ ## Local overrides
49
+
50
+ Set the tokens above on an element you own (a page or section class, or a class added with
51
+ `:style-class-passthrough`): they inherit down into the component. Keep the block **unlayered** (no
52
+ `@layer` wrapper) so it beats the library's `@layer components`. If your own file uses
53
+ `<style scoped>`, tokens set on your element still work, but selectors that reach inside the
54
+ component need `:deep()`. Patterns and examples: `.claude/skills/component-local-style-override.md`.
55
+
56
+ **Caveat:** `frameHeight`, `parallaxOffset`, `radius` and `focalX`, when passed, are written inline
57
+ on the root and override their tokens. To drive one from CSS, don't pass its prop.
58
+
59
+ ## Recipe: different crop on small screens
60
+
61
+ ```css
62
+ .welcome {
63
+ --scroll-reveal-image-focal-y: 40%;
64
+
65
+ @media (width >= 768px) {
66
+ --scroll-reveal-image-focal-y: 0%;
67
+ }
68
+ }
69
+ ```
70
+
71
+ ## Class passthrough
72
+
73
+ `style-class-passthrough` is forwarded to `ScrollRevealFrame` and lands on the root `<figure>`,
74
+ not the image. Reachable in normal use.
@@ -4,10 +4,10 @@
4
4
  :parallax-offset="parallaxOffset"
5
5
  :radius="radius"
6
6
  :style-class-passthrough="styleClassPassthrough"
7
- :style="{ '--_focal-x': focalX }"
7
+ :style="{ '--scroll-reveal-image-focal-x': focalX }"
8
8
  >
9
9
  <NuxtImg
10
- class="reveal-image"
10
+ class="scroll-reveal-image"
11
11
  :src="src"
12
12
  :alt="alt"
13
13
  :width="imgWidth"
@@ -19,37 +19,14 @@
19
19
  </template>
20
20
 
21
21
  <script setup lang="ts">
22
- /**
23
- * ScrollRevealImage
24
- *
25
- * A single-image convenience wrapper around ScrollRevealFrame.
26
- * Adds NuxtImg optimisation (src, alt, intrinsic dimensions) and horizontal
27
- * focal-point control (focalX → CSS object-position x-axis).
28
- *
29
- * For a grid of images or arbitrary slot content use ScrollRevealFrame directly.
30
- */
31
-
32
22
  interface Props {
33
23
  src: string;
34
24
  alt?: string;
35
- /** Intrinsic width of the source image — required for NuxtImg optimisation. */
36
25
  imgWidth?: number;
37
- /** Intrinsic height of the source image — required for NuxtImg optimisation. */
38
26
  imgHeight?: number;
39
- /** Height of the visible clipping frame. */
40
27
  frameHeight?: string;
41
- /**
42
- * How far the image travels vertically as the frame scrolls through the
43
- * viewport. Larger = more image revealed = stronger parallax feel.
44
- */
45
28
  parallaxOffset?: string;
46
- /**
47
- * Horizontal focal point — CSS `object-position` x-axis value.
48
- * Controls which horizontal slice of the image is kept in view.
49
- * Examples: "50%", "left", "30%".
50
- */
51
29
  focalX?: string;
52
- /** Optional rounded corners on the frame. */
53
30
  radius?: string;
54
31
  loading?: "lazy" | "eager";
55
32
  styleClassPassthrough?: string | string[];
@@ -59,10 +36,10 @@ withDefaults(defineProps<Props>(), {
59
36
  alt: "",
60
37
  imgWidth: 1920,
61
38
  imgHeight: 1080,
62
- frameHeight: "540px",
63
- parallaxOffset: "36rem",
64
- focalX: "50%",
65
- radius: "0px",
39
+ frameHeight: undefined,
40
+ parallaxOffset: undefined,
41
+ focalX: undefined,
42
+ radius: undefined,
66
43
  loading: "lazy",
67
44
  styleClassPassthrough: () => [],
68
45
  });
@@ -70,28 +47,21 @@ withDefaults(defineProps<Props>(), {
70
47
 
71
48
  <style lang="css">
72
49
  @layer components {
73
- .reveal-image {
50
+ .scroll-reveal-image {
51
+ --_focal-x: var(--scroll-reveal-image-focal-x, 50%);
52
+
74
53
  display: block;
75
54
  width: 100%;
76
55
  height: 100%;
77
56
  object-fit: cover;
78
- /*
79
- * Y is always 0% — ScrollRevealFrame's translateY handles vertical travel.
80
- * focalX (--_focal-x) lets the consumer pin the horizontal crop point.
81
- */
82
- object-position: var(--_focal-x, 50%) 0%;
83
- }
57
+ object-position: var(--_focal-x) var(--scroll-reveal-image-focal-y, 0%);
84
58
 
85
- /* ── Fallback: centre the crop vertically when there is no animation ── */
86
- @supports not (animation-timeline: scroll()) {
87
- .reveal-image {
88
- object-position: var(--_focal-x, 50%) 50%;
59
+ @supports not (animation-timeline: scroll()) {
60
+ object-position: var(--_focal-x) var(--scroll-reveal-image-focal-y-static, 50%);
89
61
  }
90
- }
91
62
 
92
- @media (prefers-reduced-motion: reduce) {
93
- .reveal-image {
94
- object-position: var(--_focal-x, 50%) 50%;
63
+ @media (prefers-reduced-motion: reduce) {
64
+ object-position: var(--_focal-x) var(--scroll-reveal-image-focal-y-static, 50%);
95
65
  }
96
66
  }
97
67
  }
@@ -90,7 +90,7 @@ export const Default: Story = {
90
90
  parameters: {
91
91
  docs: {
92
92
  description: {
93
- story: "All props at their default values. A portrait image panning from top to bottom as the frame crosses the viewport.",
93
+ story: "A portrait image panning from top to bottom as the frame crosses the viewport. The sizing values shown match the CSS defaults.",
94
94
  },
95
95
  },
96
96
  },
@@ -179,3 +179,52 @@ export const TallFrame: Story = {
179
179
  },
180
180
  },
181
181
  };
182
+
183
+ export const CssTokens: Story = {
184
+ args: {
185
+ src: "/images/page/hero/hero-red.jpg",
186
+ alt: "Red hair portrait",
187
+ imgWidth: 1280,
188
+ imgHeight: 1920,
189
+ },
190
+ render: (args) => ({
191
+ components: { ScrollRevealImage },
192
+ setup() {
193
+ return { args };
194
+ },
195
+ template: `
196
+ <div style="padding-block: 60vh; max-width: 860px; margin-inline: auto;">
197
+ <component is="style">
198
+ .sri-story-tokens {
199
+ --scroll-reveal-frame-height: 320px;
200
+ --scroll-reveal-frame-parallax-offset: 20rem;
201
+ --scroll-reveal-image-focal-x: 70%;
202
+ --scroll-reveal-image-focal-y: 40%;
203
+ }
204
+ @media (width >= 768px) {
205
+ .sri-story-tokens {
206
+ --scroll-reveal-frame-height: 540px;
207
+ --scroll-reveal-frame-parallax-offset: 36rem;
208
+ --scroll-reveal-image-focal-x: 50%;
209
+ --scroll-reveal-image-focal-y: 0%;
210
+ }
211
+ }
212
+ </component>
213
+ <p style="text-align: center; font-size: 1.4rem; opacity: 0.5; margin-block-end: 4rem;">
214
+ Resize below/above 768px and scroll: frame size and crop point come from CSS tokens, no props passed
215
+ </p>
216
+ <div class="sri-story-tokens">
217
+ <ScrollRevealImage v-bind="args" />
218
+ </div>
219
+ </div>
220
+ `,
221
+ }),
222
+ parameters: {
223
+ docs: {
224
+ description: {
225
+ story:
226
+ "Only the image props are passed, so frame size and crop point come from --scroll-reveal-frame-* and --scroll-reveal-image-focal-x/-y on an ancestor, changing at 768px. A prop, when passed, is written inline and wins.",
227
+ },
228
+ },
229
+ },
230
+ };
@@ -48,82 +48,89 @@ describe("ScrollRevealImage", () => {
48
48
  expect(wrapper.element.tagName).toBe("FIGURE");
49
49
  });
50
50
 
51
- it("always has the reveal-frame class", async () => {
51
+ it("always has the scroll-reveal-frame class", async () => {
52
52
  const wrapper = await mountSuspended(ScrollRevealImage, {
53
53
  props: { src: "/images/test.jpg" },
54
54
  });
55
- expect(wrapper.classes()).toContain("reveal-frame");
55
+ expect(wrapper.classes()).toContain("scroll-reveal-frame");
56
56
  });
57
57
 
58
58
  // ─── CSS custom properties ───────────────────────────────────────────────
59
59
 
60
- it("sets --_frame-height to 540px by default", async () => {
60
+ it("leaves --scroll-reveal-frame-height unset by default (CSS default applies)", async () => {
61
61
  const wrapper = await mountSuspended(ScrollRevealImage, {
62
62
  props: { src: "/images/test.jpg" },
63
63
  });
64
64
  const style = (wrapper.element as HTMLElement).style;
65
- expect(style.getPropertyValue("--_frame-height")).toBe("540px");
65
+ expect(style.getPropertyValue("--scroll-reveal-frame-height")).toBe("");
66
66
  });
67
67
 
68
- it("sets --_parallax-offset to 36rem by default", async () => {
68
+ it("leaves --scroll-reveal-frame-parallax-offset unset by default (CSS default applies)", async () => {
69
69
  const wrapper = await mountSuspended(ScrollRevealImage, {
70
70
  props: { src: "/images/test.jpg" },
71
71
  });
72
72
  const style = (wrapper.element as HTMLElement).style;
73
- expect(style.getPropertyValue("--_parallax-offset")).toBe("36rem");
73
+ expect(style.getPropertyValue("--scroll-reveal-frame-parallax-offset")).toBe("");
74
74
  });
75
75
 
76
- it("sets --_radius to 0px by default", async () => {
76
+ it("leaves --scroll-reveal-frame-radius unset by default (CSS default applies)", async () => {
77
77
  const wrapper = await mountSuspended(ScrollRevealImage, {
78
78
  props: { src: "/images/test.jpg" },
79
79
  });
80
80
  const style = (wrapper.element as HTMLElement).style;
81
- expect(style.getPropertyValue("--_radius")).toBe("0px");
81
+ expect(style.getPropertyValue("--scroll-reveal-frame-radius")).toBe("");
82
82
  });
83
83
 
84
- it("sets --_focal-x to 50% by default", async () => {
84
+ it("leaves --scroll-reveal-image-focal-x unset by default (CSS default applies)", async () => {
85
85
  const wrapper = await mountSuspended(ScrollRevealImage, {
86
86
  props: { src: "/images/test.jpg" },
87
87
  });
88
88
  const style = (wrapper.element as HTMLElement).style;
89
- expect(style.getPropertyValue("--_focal-x")).toBe("50%");
89
+ expect(style.getPropertyValue("--scroll-reveal-image-focal-x")).toBe("");
90
90
  });
91
91
 
92
- it("reflects frameHeight prop in --_frame-height", async () => {
92
+ it("reflects frameHeight prop in --scroll-reveal-frame-height", async () => {
93
93
  const wrapper = await mountSuspended(ScrollRevealImage, {
94
94
  props: { src: "/images/test.jpg", frameHeight: "80vh" },
95
95
  });
96
96
  const style = (wrapper.element as HTMLElement).style;
97
- expect(style.getPropertyValue("--_frame-height")).toBe("80vh");
97
+ expect(style.getPropertyValue("--scroll-reveal-frame-height")).toBe("80vh");
98
98
  });
99
99
 
100
- it("reflects parallaxOffset prop in --_parallax-offset", async () => {
100
+ it("reflects parallaxOffset prop in --scroll-reveal-frame-parallax-offset", async () => {
101
101
  const wrapper = await mountSuspended(ScrollRevealImage, {
102
102
  props: { src: "/images/test.jpg", parallaxOffset: "48rem" },
103
103
  });
104
104
  const style = (wrapper.element as HTMLElement).style;
105
- expect(style.getPropertyValue("--_parallax-offset")).toBe("48rem");
105
+ expect(style.getPropertyValue("--scroll-reveal-frame-parallax-offset")).toBe("48rem");
106
106
  });
107
107
 
108
- it("reflects radius prop in --_radius", async () => {
108
+ it("reflects radius prop in --scroll-reveal-frame-radius", async () => {
109
109
  const wrapper = await mountSuspended(ScrollRevealImage, {
110
110
  props: { src: "/images/test.jpg", radius: "2.4rem" },
111
111
  });
112
112
  const style = (wrapper.element as HTMLElement).style;
113
- expect(style.getPropertyValue("--_radius")).toBe("2.4rem");
113
+ expect(style.getPropertyValue("--scroll-reveal-frame-radius")).toBe("2.4rem");
114
114
  });
115
115
 
116
- it("reflects focalX prop in --_focal-x", async () => {
116
+ it("writes no inline style at all when no sizing or focal props are passed", async () => {
117
+ const wrapper = await mountSuspended(ScrollRevealImage, {
118
+ props: { src: "/images/test.jpg" },
119
+ });
120
+ expect(wrapper.attributes("style")).toBeUndefined();
121
+ });
122
+
123
+ it("reflects focalX prop in --scroll-reveal-image-focal-x", async () => {
117
124
  const wrapper = await mountSuspended(ScrollRevealImage, {
118
125
  props: { src: "/images/test.jpg", focalX: "75%" },
119
126
  });
120
127
  const style = (wrapper.element as HTMLElement).style;
121
- expect(style.getPropertyValue("--_focal-x")).toBe("75%");
128
+ expect(style.getPropertyValue("--scroll-reveal-image-focal-x")).toBe("75%");
122
129
  });
123
130
 
124
131
  // ─── Image element ───────────────────────────────────────────────────────
125
132
 
126
- it("renders an img child element with the reveal-image class", async () => {
133
+ it("renders an img child element with the scroll-reveal-image class", async () => {
127
134
  const wrapper = await mountSuspended(ScrollRevealImage, {
128
135
  props: { src: "/images/test.jpg" },
129
136
  });
@@ -131,7 +138,7 @@ describe("ScrollRevealImage", () => {
131
138
  // identified by the data-nuxt-img attribute it injects.
132
139
  const img = wrapper.find("img[data-nuxt-img]");
133
140
  expect(img.exists()).toBe(true);
134
- expect(img.classes()).toContain("reveal-image");
141
+ expect(img.classes()).toContain("scroll-reveal-image");
135
142
  });
136
143
 
137
144
  it("passes src through to the image element", async () => {
@@ -1,13 +1,13 @@
1
1
  // Vitest Snapshot v1, https://vitest.dev/guide/snapshot.html
2
2
 
3
3
  exports[`ScrollRevealImage > renders correct HTML structure (all props set) 1`] = `
4
- "<figure class="reveal-frame custom-class" style="--_frame-height: 400px; --_parallax-offset: 20rem; --_radius: 1.6rem; --_focal-x: 30%;">
5
- <div class="reveal-content"><img width="800" height="600" data-nuxt-img="" srcset="/_ipx/s_800x600/images/test.jpg 1x, /_ipx/s_1600x1200/images/test.jpg 2x" class="reveal-image" alt="All props" loading="eager" decoding="async" src="/_ipx/s_800x600/images/test.jpg"></div>
4
+ "<figure class="scroll-reveal-frame custom-class" style="--scroll-reveal-frame-height: 400px; --scroll-reveal-frame-parallax-offset: 20rem; --scroll-reveal-frame-radius: 1.6rem; --scroll-reveal-image-focal-x: 30%;">
5
+ <div class="scroll-reveal-frame-content"><img width="800" height="600" data-nuxt-img="" srcset="/_ipx/s_800x600/images/test.jpg 1x, /_ipx/s_1600x1200/images/test.jpg 2x" class="scroll-reveal-image" alt="All props" loading="eager" decoding="async" src="/_ipx/s_800x600/images/test.jpg"></div>
6
6
  </figure>"
7
7
  `;
8
8
 
9
9
  exports[`ScrollRevealImage > renders correct HTML structure (default props) 1`] = `
10
- "<figure class="reveal-frame" style="--_frame-height: 540px; --_parallax-offset: 36rem; --_radius: 0px; --_focal-x: 50%;">
11
- <div class="reveal-content"><img width="1920" height="1080" data-nuxt-img="" srcset="/_ipx/s_1920x1080/images/test.jpg 1x, /_ipx/s_3840x2160/images/test.jpg 2x" class="reveal-image" alt="Test image" loading="lazy" decoding="async" src="/_ipx/s_1920x1080/images/test.jpg"></div>
10
+ "<figure class="scroll-reveal-frame">
11
+ <div class="scroll-reveal-frame-content"><img width="1920" height="1080" data-nuxt-img="" srcset="/_ipx/s_1920x1080/images/test.jpg 1x, /_ipx/s_3840x2160/images/test.jpg 2x" class="scroll-reveal-image" alt="Test image" loading="lazy" decoding="async" src="/_ipx/s_1920x1080/images/test.jpg"></div>
12
12
  </figure>"
13
13
  `;
@@ -19,12 +19,33 @@
19
19
  </SectionParallax>
20
20
  ```
21
21
 
22
+ ---
23
+
22
24
  ## Motion
23
25
 
24
26
  The parallax effect (`background-attachment: fixed`) only activates on `(hover: hover) and
25
27
  (pointer: fine)` inputs that support it, and is disabled under `prefers-reduced-motion: reduce`
26
28
  (falls back to `background-attachment: scroll` and the base `--section-parallax-min-height`).
27
29
 
30
+ ---
31
+
32
+ ## No overlay/gradient built in
33
+
34
+ The component has no built-in overlay or gradient scrim — add one via the default slot or a
35
+ `::before` pseudo-element in your consuming-page styles.
36
+
37
+ ---
38
+
39
+ ## Local overrides
40
+
41
+ Set the tokens above on an element you own (a page or section class, or a class added with
42
+ `:style-class-passthrough`): they inherit down into the component. Keep the block **unlayered** (no
43
+ `@layer` wrapper) so it beats the library's `@layer components`. If your own file uses
44
+ `<style scoped>`, tokens set on your element still work, but selectors that reach inside the component need
45
+ `:deep()`. Patterns and examples: `.claude/skills/component-local-style-override.md`.
46
+
47
+ ---
48
+
28
49
  ## Class passthrough
29
50
 
30
51
  Use `styleClassPassthrough` to add classes to the root element — e.g. to override `min-height`
@@ -38,7 +59,3 @@ from a consuming page's own stylesheet instead of inline tokens:
38
59
  }
39
60
  ```
40
61
 
41
- ## No overlay/gradient built in
42
-
43
- The component has no built-in overlay or gradient scrim — add one via the default slot or a
44
- `::before` pseudo-element in your consuming-page styles.