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
@@ -0,0 +1,84 @@
1
+ # AlertContent — Consumer Styling Guide
2
+
3
+ Covers `AlertContent` and its inner `AlertContentInner`. The inner tokens also apply inside
4
+ `AlertMaskedContent`, which has its own guide for its outer shape.
5
+
6
+ ## Public token API
7
+
8
+ ### Outer shape (`.alert-content`)
9
+
10
+ | Token | Default | Controls |
11
+ |---|---|---|
12
+ | `--alert-content-accent` | `var(--theme-accent)` | Accent stripe colour (the root's background, showing at the left edge) |
13
+ | `--alert-content-accent-width` | `0.6rem` | Accent stripe width |
14
+ | `--alert-content-border` | `0.1rem solid var(--theme-border)` | Border (shorthand) |
15
+ | `--alert-content-border-radius-start` | `0.8rem` | Left-hand corner radii (also rounds the inner panel) |
16
+ | `--alert-content-border-radius-end` | `0.4rem` | Right-hand corner radii |
17
+
18
+ ### Inside (`.alert-content-inner`)
19
+
20
+ | Token | Default | Controls |
21
+ |---|---|---|
22
+ | `--alert-content-inner-background` | `var(--theme-surface-subtle)` | Panel background |
23
+ | `--alert-content-text-colour` | `var(--theme-text)` | Text colour (icon, title, message and dismiss inherit it) |
24
+ | `--alert-content-padding` | `1.2rem 1.5rem` | Panel padding |
25
+ | `--alert-content-gap` | `1.2rem` | Gap between icon, message column and dismiss button |
26
+ | `--alert-content-icon-colour` | `currentColor` | Theme icon colour |
27
+ | `--alert-content-icon-size` | `2.5rem` | Theme icon size (`font-size`) |
28
+ | `--alert-content-body-gap` | `0.4rem` | Gap between title and message |
29
+ | `--alert-content-title-font-size` | `var(--step-4)` | Title size |
30
+ | `--alert-content-text-font-size` | `var(--step-3)` | Message size |
31
+ | `--alert-content-actions-spacing` | `1.2rem` | Space between the message and the actions row |
32
+ | `--alert-content-actions-gap` | `0.8rem` | Gap between action controls |
33
+ | `--alert-content-actions-justify` | `flex-end` | Horizontal alignment of the actions row (`justify-content`) |
34
+
35
+ ### Dismiss button
36
+
37
+ | Token | Default | Controls |
38
+ |---|---|---|
39
+ | `--alert-content-dismiss-border-colour` | `var(--theme-border)` | Button border |
40
+ | `--alert-content-dismiss-icon-size` | `1.5rem` | Close icon size |
41
+ | `--alert-content-dismiss-background-hover` | `var(--theme-surface-hover)` | Background on hover/focus |
42
+ | `--alert-content-dismiss-colour-hover` | `var(--theme-on-surface)` | Icon colour on hover/focus |
43
+ | `--alert-content-dismiss-ring` | `var(--theme-ring)` | Focus/hover outline colour |
44
+
45
+ > **Changed 2026-09-27**: every value above except `--alert-content-inner-background` was hardcoded
46
+ > (or read a `--theme-*` token directly, CLAUDE.md pitfall #14). Defaults are unchanged apart from
47
+ > the px radii and stripe width, which are now the same sizes in rem. The icon and dismiss colours now
48
+ > inherit the text colour (still `--theme-text` by default) so one token recolours all of it.
49
+
50
+ Private tokens (not public API): `--_radius-start`/`--_radius-end` on `.alert-content`, resolving the
51
+ radius tokens once for the four corners.
52
+
53
+ ## State hooks
54
+
55
+ - `data-theme` on `.alert-content`, from the required `theme` prop. It sets the `--theme-*` tokens
56
+ that every default above reads, so it drives all the colours, in light and dark mode.
57
+ - Classes: `.alert-content` > `.alert-content-inner` > `.alert-content-icon` (when `showIcon`),
58
+ `.alert-content-main` > (`.alert-content-body` > `.alert-content-title`, `.alert-content-text`) +
59
+ `.alert-content-actions` (when the `#actions` slot is used), then `.alert-content-dismiss`
60
+ (when `dismissible`).
61
+ - `data-test-id`: `alert-icon`, `alert-title`, `alert-content`, `alert-actions`, `alert-dismiss`.
62
+
63
+ > **Changed 2026-09-27**: `.title`/`.content` renamed to `.alert-content-title`/`.alert-content-text`
64
+ > (generic names collide with site CSS when the alert renders inline). The body and new actions row
65
+ > are wrapped in `.alert-content-main`.
66
+
67
+ ## Local overrides
68
+
69
+ Set the tokens above on an element you own (a page or section class, or a plain `class` on the
70
+ component, which falls through to the root `.alert-content`): they inherit down into the component.
71
+ Keep the block **unlayered** (no `@layer` wrapper) so it beats the library's `@layer components`. If
72
+ your own file uses `<style scoped>`, tokens set on your element still work, but selectors that reach
73
+ inside the component need `:deep()`. Patterns and examples:
74
+ `.claude/skills/component-local-style-override.md`.
75
+
76
+ **Caveat:** `.alert-content` sets `data-theme` on itself, so `--theme-*` values set on an ancestor
77
+ don't reach it: the alert always uses its own `theme` prop's palette. Override the `--alert-content-*`
78
+ tokens instead. When it's rendered by `DisplayToast`/`DisplayToastProvider` it's teleported to
79
+ `<body>`, so set tokens globally or through the toast's own hooks rather than on a page wrapper.
80
+
81
+ ## Class passthrough
82
+
83
+ No `style-class-passthrough` prop. A plain `class` attribute falls through to the root `.alert-content`
84
+ (`AlertContent` has a single root), which is enough for setting tokens on one instance.
@@ -1,5 +1,6 @@
1
1
  import type { Meta, StoryObj } from "@nuxtjs/storybook";
2
2
  import AlertContent from "../AlertContent.vue";
3
+ import InputButton from "../../../05.forms/input-button/InputButton.vue";
3
4
 
4
5
  const meta: Meta<typeof AlertContent> = {
5
6
  title: "Molecules/AlertContent",
@@ -16,6 +17,11 @@ const meta: Meta<typeof AlertContent> = {
16
17
  description: "Iconify icon name to override the default theme icon",
17
18
  table: { category: "Appearance" },
18
19
  },
20
+ showIcon: {
21
+ control: "boolean",
22
+ description: "Render the theme icon column",
23
+ table: { category: "Appearance" },
24
+ },
19
25
  dismissible: {
20
26
  control: "boolean",
21
27
  description: "Show a close button (emits 'dismiss' on click)",
@@ -26,6 +32,7 @@ const meta: Meta<typeof AlertContent> = {
26
32
  },
27
33
  args: {
28
34
  theme: "info",
35
+ showIcon: true,
29
36
  dismissible: false,
30
37
  },
31
38
  };
@@ -129,3 +136,35 @@ export const AllThemes: Story = {
129
136
  `,
130
137
  }),
131
138
  };
139
+
140
+ /** Actions — a row of buttons under the message, e.g. for a consent or confirm prompt. */
141
+ export const WithActions: Story = {
142
+ name: "With Actions",
143
+ args: { theme: "info", customIcon: "material-symbols:cookie-outline" },
144
+ render: (args) => ({
145
+ components: { AlertContent, InputButton },
146
+ setup() {
147
+ return { args };
148
+ },
149
+ template: `
150
+ <div :data-theme="args.theme" style="max-width: 600px; padding: 2rem;">
151
+ <AlertContent v-bind="args">
152
+ <template #title>Cookies</template>
153
+ <template #content>This site uses cookies to understand how it's used. You can accept or reject them.</template>
154
+ <template #actions>
155
+ <InputButton type="button" variant="tertiary" button-text="Reject" />
156
+ <InputButton type="button" variant="primary" button-text="Accept" />
157
+ </template>
158
+ </AlertContent>
159
+ </div>
160
+ `,
161
+ }),
162
+ parameters: {
163
+ docs: {
164
+ description: {
165
+ story:
166
+ "The #actions slot renders a wrapping row under the message, outside the aria-live/contentId body so the buttons aren't announced or pulled into aria-describedby. Actions are right-aligned by default (--alert-content-actions-justify). The cookie icon comes from customIcon; set showIcon to false to drop the icon column.",
167
+ },
168
+ },
169
+ },
170
+ };
@@ -132,4 +132,36 @@ describe("AlertContent", () => {
132
132
  });
133
133
  expect(wrapper.find(".sr-only").text()).toBe("Close");
134
134
  });
135
+
136
+ // ─── showIcon / actions (added 2026-09-27) ──────────────────────────────────
137
+
138
+ it("omits the icon region when showIcon is false", async () => {
139
+ const wrapper = await mountSuspended(AlertContent, { props: { theme: "info", showIcon: false } });
140
+ expect(wrapper.find("[data-test-id='alert-icon']").exists()).toBe(false);
141
+ });
142
+
143
+ it("renders the #actions slot in its own row, outside the live/described body", async () => {
144
+ const wrapper = await mountSuspended(AlertContent, {
145
+ props: { theme: "info", contentId: "msg-1", ariaLive: "polite" },
146
+ slots: { content: "Body", actions: '<button type="button" class="act">Do it</button>' },
147
+ });
148
+ const actions = wrapper.find("[data-test-id='alert-actions']");
149
+ expect(actions.exists()).toBe(true);
150
+ expect(actions.find(".act").exists()).toBe(true);
151
+ expect(wrapper.find(".alert-content-body").find(".act").exists()).toBe(false);
152
+ });
153
+
154
+ it("does not render the actions row without the #actions slot", async () => {
155
+ const wrapper = await mountSuspended(AlertContent, { props: { theme: "info" }, slots: { content: "Body" } });
156
+ expect(wrapper.find("[data-test-id='alert-actions']").exists()).toBe(false);
157
+ });
158
+
159
+ it("uses component-prefixed classes for the title and text", async () => {
160
+ const wrapper = await mountSuspended(AlertContent, {
161
+ props: { theme: "info" },
162
+ slots: { title: "T", content: "C" },
163
+ });
164
+ expect(wrapper.find(".alert-content-title").exists()).toBe(true);
165
+ expect(wrapper.find(".alert-content-text").exists()).toBe(true);
166
+ });
135
167
  });
@@ -132,4 +132,36 @@ describe("AlertContentInner", () => {
132
132
  });
133
133
  expect(wrapper.find(".sr-only").text()).toBe("Close");
134
134
  });
135
+
136
+ // ─── showIcon / actions (added 2026-09-27) ──────────────────────────────────
137
+
138
+ it("omits the icon region when showIcon is false", async () => {
139
+ const wrapper = await mountSuspended(AlertContentInner, { props: { theme: "info", showIcon: false } });
140
+ expect(wrapper.find("[data-test-id='alert-icon']").exists()).toBe(false);
141
+ });
142
+
143
+ it("renders the #actions slot in its own row, outside the live/described body", async () => {
144
+ const wrapper = await mountSuspended(AlertContentInner, {
145
+ props: { theme: "info", contentId: "msg-1", ariaLive: "polite" },
146
+ slots: { content: "Body", actions: '<button type="button" class="act">Do it</button>' },
147
+ });
148
+ const actions = wrapper.find("[data-test-id='alert-actions']");
149
+ expect(actions.exists()).toBe(true);
150
+ expect(actions.find(".act").exists()).toBe(true);
151
+ expect(wrapper.find(".alert-content-body").find(".act").exists()).toBe(false);
152
+ });
153
+
154
+ it("does not render the actions row without the #actions slot", async () => {
155
+ const wrapper = await mountSuspended(AlertContentInner, { props: { theme: "info" }, slots: { content: "Body" } });
156
+ expect(wrapper.find("[data-test-id='alert-actions']").exists()).toBe(false);
157
+ });
158
+
159
+ it("uses component-prefixed classes for the title and text", async () => {
160
+ const wrapper = await mountSuspended(AlertContentInner, {
161
+ props: { theme: "info" },
162
+ slots: { title: "T", content: "C" },
163
+ });
164
+ expect(wrapper.find(".alert-content-title").exists()).toBe(true);
165
+ expect(wrapper.find(".alert-content-text").exists()).toBe(true);
166
+ });
135
167
  });
@@ -4,6 +4,7 @@
4
4
  <AlertContentInner
5
5
  :theme="theme"
6
6
  :custom-icon="customIcon"
7
+ :show-icon="showIcon"
7
8
  :dismissible="dismissible"
8
9
  :content-id="contentId"
9
10
  :aria-live="ariaLive"
@@ -18,6 +19,9 @@
18
19
  <template v-if="slots.content" #content>
19
20
  <slot name="content"></slot>
20
21
  </template>
22
+ <template v-if="slots.actions" #actions>
23
+ <slot name="actions"></slot>
24
+ </template>
21
25
  <template v-if="slots.dismissIcon" #dismissIcon>
22
26
  <slot name="dismissIcon"></slot>
23
27
  </template>
@@ -35,6 +39,7 @@ import type { SemanticTheme, AlertMaskConfig } from "~/types/components";
35
39
  interface Props {
36
40
  theme: SemanticTheme;
37
41
  customIcon?: string;
42
+ showIcon?: boolean;
38
43
  dismissible?: boolean;
39
44
  contentId?: string;
40
45
  ariaLive?: "polite" | "assertive" | "off";
@@ -43,6 +48,7 @@ interface Props {
43
48
 
44
49
  const props = withDefaults(defineProps<Props>(), {
45
50
  customIcon: undefined,
51
+ showIcon: true,
46
52
  dismissible: false,
47
53
  contentId: undefined,
48
54
  ariaLive: undefined,
@@ -55,8 +61,8 @@ const slots = useSlots();
55
61
 
56
62
  // Shape matches AlertContent: 8px left radius, 4px right, 6px accent bar on left, 1px border elsewhere
57
63
  const resolvedMaskConfig = computed<AlertMaskConfig>(() => ({
58
- borderColour: "var(--theme-accent)",
59
- backgroundColour: "rgba(0, 0, 0, 0.3)",
64
+ borderColour: "var(--alert-masked-content-border-colour, var(--theme-accent))",
65
+ backgroundColour: "var(--alert-masked-content-background, color-mix(in oklab, var(--theme-surface-subtle) 80%, transparent))",
60
66
  radiusLeft: 8,
61
67
  radiusRight: 4,
62
68
  borderLeft: 6,
@@ -70,9 +76,7 @@ const resolvedMaskConfig = computed<AlertMaskConfig>(() => ({
70
76
  <style lang="css">
71
77
  @layer components {
72
78
  .alert-masked-content {
73
- .alert-content-inner {
74
- --_alert-content-inner-bg: transparent;
75
- }
79
+ --alert-content-inner-background: transparent;
76
80
  }
77
81
  }
78
82
  </style>
@@ -0,0 +1,73 @@
1
+ # AlertMaskedContent — Consumer Styling Guide
2
+
3
+ `AlertMaskedContent` is `AlertContentInner` (icon, title, body, dismiss button) wrapped in
4
+ `AlertMaskCore`'s SVG mask: an accent-coloured border drawn as a cut-out, and a translucent fill,
5
+ so whatever sits behind the alert stays visible. It's the variant `DisplayToast`
6
+ (`appearance.masked`) and `DisplayPrompt` (`masked`) swap in.
7
+
8
+ ## Public token API
9
+
10
+ ### Mask colours
11
+
12
+ | Token | Default | Controls |
13
+ |---|---|---|
14
+ | `--alert-masked-content-border-colour` | `var(--theme-accent)` | Border colour (6px accent bar on the left, 1px elsewhere). |
15
+ | `--alert-masked-content-background` | `color-mix(in oklab, var(--theme-surface-subtle) 80%, transparent)` | Translucent fill behind the content: the theme's own surface colour at 80%, so text contrast matches `AlertContent` in light and dark mode. |
16
+
17
+ These reach the SVG as `fill` styles, so they resolve like any inherited custom property. A
18
+ `maskConfig.borderColour` / `maskConfig.backgroundColour` prop value replaces the token entirely
19
+ for that instance.
20
+
21
+ ### Mask geometry
22
+
23
+ Radius and border thickness aren't tokens: `AlertMaskCore` computes the SVG path from them in JS.
24
+ Set them with the `maskConfig` prop (`AlertMaskConfig`). Defaults: `radiusLeft: 8`,
25
+ `radiusRight: 4`, `borderLeft: 6`, `borderTop`/`borderRight`/`borderBottom: 1`.
26
+
27
+ ### Content
28
+
29
+ Icon, text and dismiss button styling come from `AlertContentInner` and follow the `data-theme`
30
+ set on the root (`--theme-text`, `--theme-border`, etc.).
31
+
32
+ ### Private tokens
33
+
34
+ None of its own. `AlertMaskCore`'s `--_height` / `--_inset-*` are measured plumbing, not public API.
35
+
36
+ ## State hooks
37
+
38
+ - `data-theme="info" | "success" | "warning" | "error"` on the root `.alert-masked-content`,
39
+ from the `theme` prop. Drives `--theme-accent` and the content colours.
40
+ - Inner classes: `.alert-mask-core` > `.alert-mask-decorator` (the SVG) + `.alert-mask-content` >
41
+ `.alert-content-inner` > `.alert-content-icon`, `.alert-content-main` > (`.alert-content-body` >
42
+ `.alert-content-title`, `.alert-content-text`) + `.alert-content-actions`, then `.alert-content-dismiss`.
43
+ The inner content tokens (`--alert-content-gap`, `-padding`, `-text-colour`, `-icon-size`, `-title-font-size`,
44
+ `-actions-gap`, the dismiss-button tokens, ...) apply here too; see `AlertContent`'s CONSUMER-STYLING.md.
45
+ Its outer-shape tokens (`--alert-content-accent`, `-border`, `-border-radius-*`, `-accent-width`) don't:
46
+ the masked shape comes from `maskConfig`.
47
+
48
+ > **Changed 2026-09-27**: `.title`/`.content` renamed to `.alert-content-title`/`.alert-content-text`,
49
+ > and body + actions now sit in `.alert-content-main`.
50
+
51
+ ## Local overrides
52
+
53
+ Set the tokens above on an element you own (a page or section class, or a plain `class` on
54
+ `<AlertMaskedContent>`, which falls through to the root since there's no passthrough prop): they
55
+ inherit down into the component. Keep the block **unlayered** (no `@layer` wrapper) so it beats the
56
+ library's `@layer components`. If your own file uses `<style scoped>`, tokens set on your element
57
+ still work, but selectors that reach inside the component need `:deep()`. Patterns and examples:
58
+ `.claude/skills/component-local-style-override.md`.
59
+
60
+ **Caveat:** the root sets `--alert-content-inner-background: transparent` on itself, so an
61
+ ancestor value of that token never reaches the masked variant. That's deliberate: an opaque inner
62
+ background would hide the mask. Change the fill with `--alert-masked-content-background` instead.
63
+
64
+ ## Class passthrough
65
+
66
+ There's no `styleClassPassthrough` prop. A plain `class` attribute falls through to the root
67
+ `.alert-masked-content` element.
68
+
69
+ ## Notes
70
+
71
+ - The default fill is the theme's own surface (`--theme-surface-subtle`) at 80%, matching the
72
+ surface `--theme-text` is designed for, so contrast holds in light and dark mode. Lowering the
73
+ percentage shows more backdrop but costs contrast; check it over your real imagery.
@@ -1,5 +1,6 @@
1
1
  import type { Meta, StoryObj } from "@nuxtjs/storybook";
2
2
  import AlertMaskedContent from "../AlertMaskedContent.vue";
3
+ import AlertContent from "../../alert-content/AlertContent.vue";
3
4
 
4
5
  const meta: Meta<typeof AlertMaskedContent> = {
5
6
  title: "Molecules/AlertMaskedContent",
@@ -34,22 +35,18 @@ const meta: Meta<typeof AlertMaskedContent> = {
34
35
  export default meta;
35
36
  type Story = StoryObj<typeof AlertMaskedContent>;
36
37
 
37
- const wrapperStyle = `
38
- max-width: 600px;
39
- padding: 2rem;
40
- background: linear-gradient(135deg, oklch(40% 0.15 250), oklch(25% 0.1 300));
41
- border-radius: 8px;
42
- `;
38
+ const wrapperStyle =
39
+ "max-width: 600px; padding: 2rem; background: linear-gradient(135deg, oklch(40% 0.15 250), oklch(25% 0.1 300)); border-radius: 8px;";
43
40
 
44
41
  /** Default — info theme over a coloured background to show the glass effect. */
45
42
  export const Default: Story = {
46
43
  render: (args) => ({
47
44
  components: { AlertMaskedContent },
48
45
  setup() {
49
- return { args };
46
+ return { args, wrapperStyle };
50
47
  },
51
48
  template: `
52
- <div :data-theme="args.theme" :style="'${wrapperStyle}'">
49
+ <div :data-theme="args.theme" :style="wrapperStyle">
53
50
  <AlertMaskedContent v-bind="args">
54
51
  <template #title>Alert title</template>
55
52
  <template #content>This is the alert body. It describes what happened and what the user should do next.</template>
@@ -65,10 +62,10 @@ export const Dismissible: Story = {
65
62
  render: (args) => ({
66
63
  components: { AlertMaskedContent },
67
64
  setup() {
68
- return { args };
65
+ return { args, wrapperStyle };
69
66
  },
70
67
  template: `
71
- <div :data-theme="args.theme" :style="'${wrapperStyle}'">
68
+ <div :data-theme="args.theme" :style="wrapperStyle">
72
69
  <AlertMaskedContent v-bind="args">
73
70
  <template #title>Dismissible alert</template>
74
71
  <template #content>Click the close button to emit the dismiss event.</template>
@@ -130,3 +127,87 @@ export const BackgroundVariants: Story = {
130
127
  `,
131
128
  }),
132
129
  };
130
+
131
+ const busyBackdrop = [
132
+ "repeating-linear-gradient(45deg, oklch(100% 0 0 / 0.18) 0 1.2rem, transparent 1.2rem 2.4rem)",
133
+ "linear-gradient(120deg, oklch(70% 0.2 30), oklch(75% 0.18 90) 35%, oklch(65% 0.2 200) 70%, oklch(55% 0.22 300))",
134
+ ].join(", ");
135
+
136
+ /**
137
+ * Over imagery — the mask only reads as a mask with something busy behind it. Each row pairs
138
+ * the plain AlertContent (opaque surface) with AlertMaskedContent over the same backdrop, so the
139
+ * translucent fill and the cut-out accent border are directly comparable.
140
+ */
141
+ export const OverImagery: Story = {
142
+ name: "Over Imagery (mask in action)",
143
+ args: { theme: "info", dismissible: true },
144
+ render: (args) => ({
145
+ components: { AlertMaskedContent, AlertContent },
146
+ setup() {
147
+ const backdrops = [
148
+ { label: "Photo", style: "background: url('/images/banners/video/lake-banner.jpg') center / cover;" },
149
+ { label: "Photo", style: "background: url('/images/page/hero/hero-blonde.jpg') center 30% / cover;" },
150
+ { label: "Striped gradient", style: `background: ${busyBackdrop};` },
151
+ ];
152
+ return { args, backdrops };
153
+ },
154
+ template: `
155
+ <div style="display: grid; gap: 2.4rem; max-width: 110rem;">
156
+ <p style="margin: 0; font-family: sans-serif; font-size: 1.4rem; max-width: 70ch;">
157
+ Left: <strong>AlertContent</strong> (opaque surface). Right: <strong>AlertMaskedContent</strong>:
158
+ the SVG mask draws only the accent border and a translucent fill, so the backdrop stays visible
159
+ through the body and around the border's cut-out.
160
+ </p>
161
+ <div
162
+ v-for="(backdrop, i) in backdrops"
163
+ :key="i"
164
+ :data-theme="args.theme"
165
+ :style="backdrop.style + ' display: grid; grid-template-columns: repeat(auto-fit, minmax(32rem, 1fr)); gap: 2.4rem; padding: 4rem 2.4rem; border-radius: 1.2rem;'"
166
+ >
167
+ <AlertContent v-bind="args">
168
+ <template #title>AlertContent ({{ backdrop.label }})</template>
169
+ <template #content>Opaque surface: nothing behind it shows through.</template>
170
+ </AlertContent>
171
+ <AlertMaskedContent v-bind="args">
172
+ <template #title>AlertMaskedContent ({{ backdrop.label }})</template>
173
+ <template #content>Translucent fill and cut-out border: the backdrop shows through.</template>
174
+ </AlertMaskedContent>
175
+ </div>
176
+ </div>
177
+ `,
178
+ }),
179
+ parameters: {
180
+ docs: {
181
+ description: {
182
+ story:
183
+ "Photos and a striped gradient behind each pair. Compare the opaque AlertContent on the left with the masked variant on the right.",
184
+ },
185
+ },
186
+ },
187
+ };
188
+
189
+ /** Token overrides — the public colour tokens set on a wrapper you own, over the same busy backdrop. */
190
+ export const TokenOverrides: Story = {
191
+ name: "Token Overrides",
192
+ args: { theme: "warning", dismissible: false },
193
+ render: (args) => ({
194
+ components: { AlertMaskedContent },
195
+ setup() {
196
+ return { args, busyBackdrop };
197
+ },
198
+ template: `
199
+ <div :data-theme="args.theme" :style="'background: ' + busyBackdrop + '; padding: 4rem 2.4rem; border-radius: 1.2rem; display: grid; gap: 2.4rem; max-width: 60rem;'">
200
+ <AlertMaskedContent v-bind="args">
201
+ <template #title>Default tokens</template>
202
+ <template #content>--theme-accent border, --theme-surface-subtle fill at 80%.</template>
203
+ </AlertMaskedContent>
204
+ <div style="--alert-masked-content-border-colour: white; --alert-masked-content-background: color-mix(in oklab, var(--theme-surface-subtle) 55%, transparent);">
205
+ <AlertMaskedContent v-bind="args">
206
+ <template #title>Overridden tokens</template>
207
+ <template #content>White border, fill dropped to 55% so more of the backdrop shows (at some cost to contrast).</template>
208
+ </AlertMaskedContent>
209
+ </div>
210
+ </div>
211
+ `,
212
+ }),
213
+ };
@@ -142,6 +142,26 @@ describe("AlertMaskedContent", () => {
142
142
  expect(style.getPropertyValue("--_inset-block-end")).toBe("1px");
143
143
  });
144
144
 
145
+ it("routes the default mask colours through public tokens", async () => {
146
+ const wrapper = await mountSuspended(AlertMaskedContent, { props: { theme: "info" } });
147
+ const paths = wrapper.findAll(".alert-mask-decorator > path");
148
+ expect((paths[0]!.element as unknown as SVGElement).style.fill).toBe(
149
+ "var(--alert-masked-content-border-colour, var(--theme-accent))"
150
+ );
151
+ expect((paths[1]!.element as unknown as SVGElement).style.fill).toBe(
152
+ "var(--alert-masked-content-background, color-mix(in oklab, var(--theme-surface-subtle) 80%, transparent))"
153
+ );
154
+ });
155
+
156
+ it("lets maskConfig colours replace the token defaults", async () => {
157
+ const wrapper = await mountSuspended(AlertMaskedContent, {
158
+ props: { theme: "info", maskConfig: { borderColour: "red", backgroundColour: "blue" } },
159
+ });
160
+ const paths = wrapper.findAll(".alert-mask-decorator > path");
161
+ expect((paths[0]!.element as unknown as SVGElement).style.fill).toBe("red");
162
+ expect((paths[1]!.element as unknown as SVGElement).style.fill).toBe("blue");
163
+ });
164
+
145
165
  it("merges custom maskConfig over defaults", async () => {
146
166
  const wrapper = await mountSuspended(AlertMaskedContent, {
147
167
  props: { theme: "info", maskConfig: { borderLeft: 12 } },
@@ -150,4 +170,36 @@ describe("AlertMaskedContent", () => {
150
170
  const style = (contentEl.element as HTMLElement).style;
151
171
  expect(style.getPropertyValue("--_inset-inline-start")).toBe("12px");
152
172
  });
173
+
174
+ // ─── showIcon / actions (added 2026-09-27) ──────────────────────────────────
175
+
176
+ it("omits the icon region when showIcon is false", async () => {
177
+ const wrapper = await mountSuspended(AlertMaskedContent, { props: { theme: "info", showIcon: false } });
178
+ expect(wrapper.find("[data-test-id='alert-icon']").exists()).toBe(false);
179
+ });
180
+
181
+ it("renders the #actions slot in its own row, outside the live/described body", async () => {
182
+ const wrapper = await mountSuspended(AlertMaskedContent, {
183
+ props: { theme: "info", contentId: "msg-1", ariaLive: "polite" },
184
+ slots: { content: "Body", actions: '<button type="button" class="act">Do it</button>' },
185
+ });
186
+ const actions = wrapper.find("[data-test-id='alert-actions']");
187
+ expect(actions.exists()).toBe(true);
188
+ expect(actions.find(".act").exists()).toBe(true);
189
+ expect(wrapper.find(".alert-content-body").find(".act").exists()).toBe(false);
190
+ });
191
+
192
+ it("does not render the actions row without the #actions slot", async () => {
193
+ const wrapper = await mountSuspended(AlertMaskedContent, { props: { theme: "info" }, slots: { content: "Body" } });
194
+ expect(wrapper.find("[data-test-id='alert-actions']").exists()).toBe(false);
195
+ });
196
+
197
+ it("uses component-prefixed classes for the title and text", async () => {
198
+ const wrapper = await mountSuspended(AlertMaskedContent, {
199
+ props: { theme: "info" },
200
+ slots: { title: "T", content: "C" },
201
+ });
202
+ expect(wrapper.find(".alert-content-title").exists()).toBe(true);
203
+ expect(wrapper.find(".alert-content-text").exists()).toBe(true);
204
+ });
153
205
  });
@@ -0,0 +1,95 @@
1
+ # CookieConsentBanner — Consumer Styling Guide
2
+
3
+ The banner is a fixed, teleported wrapper around `AlertContent`. The panel itself (background, text
4
+ colour, border, radius, padding, accent stripe, icon, title and message sizes, actions alignment) is
5
+ `AlertContent`'s, styled with its `--alert-content-*` tokens: see
6
+ `app/components/02.molecules/alert-content/CONSUMER-STYLING.md`. This guide covers what the banner
7
+ adds: position, motion and the two buttons.
8
+
9
+ > **Changed 2026-09-27**: rebuilt on `AlertContent`. The banner's own panel tokens
10
+ > (`--cookie-consent-banner-padding`, `-gap`, `-border-radius`, `-border`, `-accent-border-width`,
11
+ > `-background`, `-text-colour`, `-actions-gap`) are gone; use the matching `--alert-content-*`
12
+ > tokens. The panel now follows `data-theme` in light and dark mode (a theme-tinted surface) instead
13
+ > of a fixed white panel, with a left accent stripe instead of a top border.
14
+ >
15
+ > Earlier the same day: classes, tokens and `data-test-id`s renamed from `privacy-notice-banner` to
16
+ > `cookie-consent-banner`. The consent cookie's own name (`privacy-notice-consent`, owned by
17
+ > `useCookieConsent`) is unchanged.
18
+
19
+ ## Public token API
20
+
21
+ ### Position and motion
22
+
23
+ | Token | Default | Controls |
24
+ |---|---|---|
25
+ | `--cookie-consent-banner-z-index` | `999999` | Stacking order (matches `DisplayDialog`/`DisplayToast`) |
26
+ | `--cookie-consent-banner-gutter` | `1.6rem` | Distance from the viewport's bottom and side edges |
27
+ | `--cookie-consent-banner-max-width` | `64rem` | Maximum width (centred) |
28
+ | `--cookie-consent-banner-transition-duration` | `200ms` | Close fade and button hover transitions |
29
+
30
+ ### Buttons
31
+
32
+ | Token | Default | Controls |
33
+ |---|---|---|
34
+ | `--cookie-consent-banner-accent` | `var(--theme-accent)` | Accept background and reject hover border |
35
+ | `--cookie-consent-banner-button-padding` | `0.8rem 1.6rem` | Button padding |
36
+ | `--cookie-consent-banner-button-border-radius` | `0.4rem` | Button corner radius |
37
+ | `--cookie-consent-banner-focus-ring` | `var(--theme-border-focus)` | `:focus-visible` outline colour on both buttons |
38
+ | `--cookie-consent-banner-reject-border-colour` | `var(--theme-border)` | Reject button border, resting |
39
+ | `--cookie-consent-banner-reject-border-colour-hover` | `var(--cookie-consent-banner-accent)` | Reject button border, hover/focus |
40
+ | `--cookie-consent-banner-accept-background` | `var(--cookie-consent-banner-accent)` | Accept button background |
41
+ | `--cookie-consent-banner-accept-text-colour` | `var(--theme-on-surface)` | Accept button text |
42
+
43
+ The gap between the buttons and their alignment (right by default) are `AlertContent`'s
44
+ `--alert-content-actions-gap` and `--alert-content-actions-justify`.
45
+
46
+ Private tokens (not public API): `--_gutter`, `--_transition-duration`, `--_accent` on the root,
47
+ each resolving a public token once for reuse.
48
+
49
+ ## State hooks
50
+
51
+ - `data-theme` on the root and on the inner `.alert-content`, from the `theme` prop or `app.config`
52
+ (default `info`). It drives every `--theme-*` default, for the panel and the buttons.
53
+ - `.closed` on the root once consent is granted or denied. The banner fades out and becomes
54
+ `visibility: hidden`, so its buttons leave the tab order and the accessibility tree.
55
+ - Classes: `.cookie-consent-banner` > `.cookie-consent-banner-inner` (the `role="region"`) >
56
+ `.alert-content` (see its guide for the inner structure); the buttons are
57
+ `.cookie-consent-banner-reject` and `.cookie-consent-banner-accept` inside `.alert-content-actions`.
58
+ - `data-test-id`: `cookie-consent-banner`, `cookie-consent-banner-reject`, `cookie-consent-banner-accept`,
59
+ plus `AlertContent`'s `alert-icon`, `alert-title`, `alert-content`, `alert-actions`.
60
+
61
+ ## Motion
62
+
63
+ Closing fades opacity and collapses `grid-template-rows` over the transition duration. Under
64
+ `prefers-reduced-motion: reduce` it closes instantly.
65
+
66
+ ## Local overrides
67
+
68
+ Set the tokens above on an element you own (a page or section class, or a class added with
69
+ `:style-class-passthrough`): they inherit down into the component. Keep the block **unlayered** (no
70
+ `@layer` wrapper) so it beats the library's `@layer components`. If your own file uses
71
+ `<style scoped>`, tokens set on your element still work, but selectors that reach inside the
72
+ component need `:deep()`. Patterns and examples: `.claude/skills/component-local-style-override.md`.
73
+
74
+ **Caveat:** the banner is teleported to `<body>`, so tokens set on a page or section wrapper never
75
+ reach it. Set them on `:root`/`html`, on `body`, or on the banner itself through
76
+ `style-class-passthrough`. That includes the `--alert-content-*` panel tokens; setting them on the
77
+ banner scopes them to the banner, leaving other alerts on the page alone.
78
+
79
+ ## Recipe: neutral panel
80
+
81
+ The pre-2026-09-27 look (white panel, dark text, no tint), scoped to the banner:
82
+
83
+ ```css
84
+ .cookie-consent-banner {
85
+ --alert-content-inner-background: var(--slate-00);
86
+ --alert-content-text-colour: var(--slate-10);
87
+ --alert-content-border: 0.1rem solid var(--slate-10);
88
+ }
89
+ ```
90
+
91
+ ## Class passthrough
92
+
93
+ `style-class-passthrough` adds classes to the teleported root `.cookie-consent-banner`, next to
94
+ `data-theme` and `.closed`. It's reachable in normal use and is the most reliable place to set
95
+ tokens for this component, since ancestor wrappers don't contain it.