kmcom-nuxt-layers 2.7.5 → 3.0.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 (772) hide show
  1. package/docs/FALLOW-COMPLEXITY-DUPLICATION-AUDIT.md +0 -1
  2. package/docs/LAYOUT.md +34 -61
  3. package/docs/MIGRATION.md +1 -1
  4. package/docs/UPAGE-GRID-INTEGRATION.md +6 -6
  5. package/docs/layout-shift-causes.md +1 -1
  6. package/docs/superpowers/plans/2026-09-03-layout-layer-fluid-rebuild.md +1850 -0
  7. package/docs/superpowers/plans/2026-09-03-vue-element-system.md +1019 -0
  8. package/docs/superpowers/plans/2026-09-04-grid-layer.md +977 -0
  9. package/docs/superpowers/specs/2026-08-30-layer-taxonomy-tier-0-1-design.md +533 -0
  10. package/docs/superpowers/specs/2026-08-30-layer-taxonomy-tier-2-design.md +154 -0
  11. package/docs/superpowers/specs/2026-08-30-layer-taxonomy-tier-3-design.md +109 -0
  12. package/docs/superpowers/specs/2026-08-30-layer-taxonomy-tier-4-design.md +124 -0
  13. package/docs/superpowers/specs/2026-08-30-layer-taxonomy-tier-5-design.md +121 -0
  14. package/docs/superpowers/specs/2026-08-30-layer-taxonomy-tier-6-design.md +77 -0
  15. package/docs/superpowers/specs/2026-08-30-layer-taxonomy-tier-7-design.md +73 -0
  16. package/docs/superpowers/specs/2026-08-31-swiss-grid-layer-design.md +190 -0
  17. package/docs/superpowers/specs/2026-09-03-layout-layer-fluid-rebuild-design.md +312 -0
  18. package/docs/superpowers/specs/2026-09-03-vue-element-system-design.md +342 -0
  19. package/docs/superpowers/specs/2026-09-04-grid-layer-design.md +236 -0
  20. package/layers/content/app/app.config.ts +10 -2
  21. package/layers/content/app/components/Blog/ItemPage.vue +21 -0
  22. package/layers/content/app/components/Blog/Page.vue +25 -0
  23. package/layers/content/app/components/Gallery/ImagePage.vue +5 -1
  24. package/layers/content/app/components/Gallery/Page.vue +4 -1
  25. package/layers/content/app/components/Gallery/SlugPage.vue +5 -1
  26. package/layers/content/app/components/Portfolio/ItemPage.vue +4 -1
  27. package/layers/content/app/components/Portfolio/List.vue +14 -2
  28. package/layers/content/app/components/Portfolio/Page.vue +4 -1
  29. package/layers/content/app/composables/useBlogPosts.ts +6 -19
  30. package/layers/content/app/composables/useCollectionItems.ts +63 -0
  31. package/layers/content/app/composables/useGalleryItems.ts +1 -16
  32. package/layers/content/app/types/content.ts +9 -0
  33. package/layers/content/package.json +3 -0
  34. package/layers/core/app/app.config.ts +34 -17
  35. package/layers/core/app/app.vue +1 -0
  36. package/layers/core/app/assets/css/core.css +4 -1
  37. package/layers/core/app/assets/css/tokens/breakpoints.css +13 -0
  38. package/layers/core/app/assets/css/tokens/container.css +36 -0
  39. package/layers/core/app/assets/css/tokens/spacing-fluid.css +25 -0
  40. package/layers/core/app/components/AppContainer.vue +32 -0
  41. package/layers/core/app/components/Element.test.ts +90 -0
  42. package/layers/core/app/components/Element.vue +78 -0
  43. package/layers/core/app/components/ElementTw.test.ts +64 -0
  44. package/layers/core/app/components/ElementTw.vue +86 -0
  45. package/layers/core/app/components/LoadingScreen.vue +0 -15
  46. package/layers/core/app/composables/useElementGrid.test.ts +33 -0
  47. package/layers/core/app/composables/useElementGrid.ts +29 -0
  48. package/layers/core/app/composables/useElementInteraction.test.ts +27 -0
  49. package/layers/core/app/composables/useElementInteraction.ts +17 -0
  50. package/layers/core/app/composables/useElementLayout.test.ts +41 -0
  51. package/layers/core/app/composables/useElementLayout.ts +26 -0
  52. package/layers/core/app/composables/useElementSizing.test.ts +39 -0
  53. package/layers/core/app/composables/useElementSizing.ts +25 -0
  54. package/layers/core/app/composables/useElementStyle.ts +65 -0
  55. package/layers/core/app/composables/useElementSurface.test.ts +33 -0
  56. package/layers/core/app/composables/useElementSurface.ts +21 -0
  57. package/layers/core/app/composables/useErrorLog.ts +6 -4
  58. package/layers/core/app/composables/useLayoutAttrs.test.ts +47 -0
  59. package/layers/core/app/composables/useLayoutAttrs.ts +94 -0
  60. package/layers/core/app/composables/useLoading.ts +3 -1
  61. package/layers/core/app/error.vue +27 -57
  62. package/layers/core/app/pages/[...slug].vue +1 -29
  63. package/layers/core/app/plugins/loading.client.ts +0 -6
  64. package/layers/core/app/types/element.ts +25 -0
  65. package/layers/core/app/types/index.ts +0 -1
  66. package/layers/core/app/types/notFound.ts +24 -0
  67. package/layers/core/app/types/responsive.ts +15 -0
  68. package/layers/core/app/types/responsive.type-test.ts +22 -0
  69. package/layers/core/app/types/runtime-config.ts +1 -17
  70. package/layers/core/app/types/tokens.ts +29 -0
  71. package/layers/core/app/utils/index.ts +4 -2
  72. package/layers/core/app/utils/scrollGuardClamp.test.ts +36 -0
  73. package/layers/core/app/utils/scrollGuardClamp.ts +22 -0
  74. package/layers/core/app/utils/styleToTailwindClasses.test.ts +31 -0
  75. package/layers/core/app/utils/styleToTailwindClasses.ts +16 -0
  76. package/layers/core/nuxt.config.ts +15 -11
  77. package/layers/core/package.json +2 -1
  78. package/layers/{auth → data/auth}/nuxt.config.ts +1 -1
  79. package/layers/{auth → data/auth}/package.json +1 -1
  80. package/layers/{baseline → data/auth}/tsconfig.json +1 -1
  81. package/layers/{database → data/database}/nuxt.config.ts +1 -1
  82. package/layers/{database → data/database}/package.json +1 -1
  83. package/layers/{database → data/database}/tsconfig.json +1 -1
  84. package/layers/{forms/app/types/app-config.d.ts → data/forms/app/app.config.ts} +4 -0
  85. package/layers/{forms → data/forms}/package.json +1 -1
  86. package/layers/{forms → data/forms}/server/api/forms/status.get.ts +3 -1
  87. package/layers/{animations → data/forms}/tsconfig.json +1 -1
  88. package/layers/{mailer → data/mailer}/nuxt.config.ts +11 -1
  89. package/layers/{mailer → data/mailer}/package.json +1 -1
  90. package/layers/{auth → data/mailer}/tsconfig.json +1 -1
  91. package/layers/data/metadata/app/composables/useMetadataItem.ts +18 -0
  92. package/layers/data/metadata/app/composables/useMetadataSearch.ts +37 -0
  93. package/layers/{metadata → data/metadata}/nuxt.config.ts +1 -1
  94. package/layers/{metadata → data/metadata}/package.json +1 -1
  95. package/layers/{metadata → data/metadata}/providers/comicvine/nuxt.config.ts +1 -1
  96. package/layers/{metadata → data/metadata}/providers/comicvine/package.json +1 -1
  97. package/layers/data/metadata/providers/comicvine/tsconfig.json +7 -0
  98. package/layers/{metadata → data/metadata}/providers/google-books/nuxt.config.ts +1 -1
  99. package/layers/{metadata → data/metadata}/providers/google-books/package.json +1 -1
  100. package/layers/{metadata → data/metadata}/providers/google-books/server/utils/metadata-google-books/client.ts +10 -2
  101. package/layers/data/metadata/providers/google-books/tsconfig.json +7 -0
  102. package/layers/{metadata → data/metadata}/providers/openlibrary/package.json +1 -1
  103. package/layers/{metadata → data/metadata}/providers/openlibrary/server/utils/metadata-openlibrary/client.ts +23 -11
  104. package/layers/data/metadata/providers/openlibrary/tsconfig.json +7 -0
  105. package/layers/{metadata → data/metadata}/providers/themoviedb/nuxt.config.ts +1 -1
  106. package/layers/{metadata → data/metadata}/providers/themoviedb/package.json +1 -1
  107. package/layers/{metadata → data/metadata}/providers/themoviedb/tsconfig.json +1 -1
  108. package/layers/{metadata → data/metadata}/server/utils/metadata/search.ts +11 -4
  109. package/layers/data/metadata/tsconfig.json +7 -0
  110. package/layers/{feeds → delivery/feeds}/app/components/Feeds/Index.vue +6 -2
  111. package/layers/{feeds → delivery/feeds}/app/components/Feeds/RouteCard.vue +2 -0
  112. package/layers/{feeds → delivery/feeds}/app/plugins/feed-head.ts +6 -2
  113. package/layers/{feeds → delivery/feeds}/app/utils/feed-catalog.ts +8 -6
  114. package/layers/{feeds → delivery/feeds}/nuxt.config.ts +1 -1
  115. package/layers/{feeds → delivery/feeds}/package.json +1 -1
  116. package/layers/{feeds → delivery/feeds}/server/utils/feed-config.ts +1 -1
  117. package/layers/{feeds → delivery/feeds}/server/utils/feed-service.ts +2 -1
  118. package/layers/delivery/feeds/tsconfig.json +7 -0
  119. package/layers/{scripts → delivery/scripts}/app/composables/useAnalytics.ts +3 -1
  120. package/layers/{scripts → delivery/scripts}/app/composables/useGtm.ts +8 -2
  121. package/layers/{scripts → delivery/scripts}/app/composables/useScriptsConsent.ts +4 -1
  122. package/layers/{scripts → delivery/scripts}/app/utils/scriptClients.ts +19 -0
  123. package/layers/{scripts → delivery/scripts}/nuxt.config.ts +7 -2
  124. package/layers/{scripts → delivery/scripts}/package.json +3 -2
  125. package/layers/delivery/scripts/tsconfig.json +7 -0
  126. package/layers/delivery/seo/app/composables/useSeoConfig.ts +8 -0
  127. package/layers/{seo → delivery/seo}/app/utils/seoConfig.test.ts +2 -2
  128. package/layers/{seo → delivery/seo}/app/utils/seoConfig.ts +2 -2
  129. package/layers/{seo → delivery/seo}/nuxt.config.ts +1 -1
  130. package/layers/{seo → delivery/seo}/package.json +1 -1
  131. package/layers/delivery/seo/tsconfig.json +7 -0
  132. package/layers/design-system/theming/app/app.config.ts +35 -0
  133. package/layers/design-system/theming/app/assets/css/tokens.css +26 -0
  134. package/layers/{theme → design-system/theming}/app/components/ThemePicker/AccentButton.vue +3 -22
  135. package/layers/{theme → design-system/theming}/app/components/ThemePicker/Colors.vue +3 -4
  136. package/layers/{theme → design-system/theming}/app/composables/useAccentColor.ts +5 -2
  137. package/layers/{theme → design-system/theming}/app/composables/useThemeContrast.ts +1 -1
  138. package/layers/{theme → design-system/theming}/app/composables/useThemeMotion.ts +1 -1
  139. package/layers/{theme → design-system/theming}/app/composables/useThemeTransparency.ts +1 -1
  140. package/layers/{theme → design-system/theming}/app/plugins/theme.client.ts +2 -1
  141. package/layers/design-system/theming/app/types/designSystem.ts +102 -0
  142. package/layers/design-system/theming/app/types/semanticColor.ts +20 -0
  143. package/layers/design-system/theming/app/types/theme.ts +12 -0
  144. package/layers/design-system/theming/app/utils/accentPalette.ts +28 -0
  145. package/layers/design-system/theming/app/utils/themeAdapter.ts +20 -0
  146. package/layers/design-system/theming/nuxt.config.ts +49 -0
  147. package/layers/{ui → design-system/theming}/package.json +5 -6
  148. package/layers/{theme → design-system/theming}/server/plugins/theme-fouc.ts +2 -0
  149. package/layers/{theme → design-system/theming}/server/utils/accent-css.ts +2 -2
  150. package/layers/{theme → design-system/theming}/tsconfig.json +1 -1
  151. package/layers/{typography → design-system/typography}/app/assets/css/typography.css +9 -0
  152. package/layers/design-system/typography/app/components/Typography/CodeBlock.vue +65 -0
  153. package/layers/{typography → design-system/typography}/app/components/Typography/Headline.vue +16 -31
  154. package/layers/{typography/app/components/Typography/HeadlineScreen.vue → design-system/typography/app/components/Typography/QuoteBlock.vue} +27 -29
  155. package/layers/design-system/typography/app/components/Typography/RepeatText.vue +147 -0
  156. package/layers/{typography → design-system/typography}/app/components/Typography/index.vue +6 -4
  157. package/layers/design-system/typography/app/composables/repeatFill.ts +51 -0
  158. package/layers/{typography → design-system/typography}/app/composables/typography.ts +4 -0
  159. package/layers/{typography → design-system/typography}/app/types/typography.ts +8 -0
  160. package/layers/{typography → design-system/typography}/nuxt.config.ts +1 -1
  161. package/layers/design-system/typography/tsconfig.json +7 -0
  162. package/layers/{visual → design-system/visual}/app/app.config.ts +2 -2
  163. package/layers/{visual → design-system/visual}/app/components/Accent/Blob.vue +1 -1
  164. package/layers/{visual → design-system/visual}/app/components/Accent/Scene.vue +2 -3
  165. package/layers/{visual → design-system/visual}/app/components/Gradient/Background.vue +2 -2
  166. package/layers/{visual → design-system/visual}/app/components/Gradient/Text.vue +2 -2
  167. package/layers/{visual → design-system/visual}/app/composables/gradient.ts +1 -1
  168. package/layers/design-system/visual/app/types/breakpoints.ts +67 -0
  169. package/layers/{visual → design-system/visual}/app/types/media.ts +0 -11
  170. package/layers/{visual → design-system/visual}/nuxt.config.ts +1 -1
  171. package/layers/design-system/visual/tsconfig.json +7 -0
  172. package/layers/{animations → motion/animations}/app/components/Motion/Marquee.vue +0 -7
  173. package/layers/{animations → motion/animations}/app/components/Motion/Staggered.vue +4 -1
  174. package/layers/{animations → motion/animations}/nuxt.config.ts +1 -2
  175. package/layers/motion/animations/tsconfig.json +7 -0
  176. package/layers/motion/{package.json → motion/package.json} +1 -1
  177. package/layers/motion/{tsconfig.json → motion/tsconfig.json} +1 -1
  178. package/layers/motion/page-transitions/app/assets/css/page-transitions.css +30 -0
  179. package/layers/{page-transitions → motion/page-transitions}/app/composables/usePageTransition.ts +14 -2
  180. package/layers/{page-transitions → motion/page-transitions}/app/plugins/page-transitions.client.ts +5 -2
  181. package/layers/{page-transitions → motion/page-transitions}/nuxt.config.ts +3 -1
  182. package/layers/motion/page-transitions/tsconfig.json +7 -0
  183. package/layers/motion/scroll/app/app.config.ts +13 -0
  184. package/layers/{scroll → motion/scroll}/app/composables/useSmoothScroll.ts +2 -1
  185. package/layers/{scroll → motion/scroll}/app/plugins/locomotive-scroll.client.ts +2 -1
  186. package/layers/{scroll → motion/scroll}/nuxt.config.ts +1 -1
  187. package/layers/motion/scroll/tsconfig.json +7 -0
  188. package/layers/{transitions → motion/transitions}/nuxt.config.ts +1 -1
  189. package/layers/motion/transitions/tsconfig.json +7 -0
  190. package/layers/{canvas → render/canvas}/app/composables/useRendererCapabilities.ts +0 -8
  191. package/layers/{canvas → render/canvas}/app/composables/useShaderTime.ts +0 -12
  192. package/layers/{canvas → render/canvas}/nuxt.config.ts +1 -4
  193. package/layers/{canvas → render/canvas}/package.json +3 -2
  194. package/layers/{canvas → render/canvas}/tsconfig.json +1 -1
  195. package/layers/render/shader/app/app.config.ts +21 -0
  196. package/layers/{shader → render/shader}/app/shaders/layers/paperShading.ts +1 -1
  197. package/layers/{shader → render/shader}/package.json +1 -1
  198. package/layers/render/shader/tsconfig.json +7 -0
  199. package/layers/structure/grid/app/app.config.ts +92 -0
  200. package/layers/structure/grid/app/assets/css/grid.css +38 -0
  201. package/layers/structure/grid/app/composables/useGridTracks.test.ts +94 -0
  202. package/layers/structure/grid/app/composables/useGridTracks.ts +74 -0
  203. package/layers/structure/grid/app/types/tracks.test.ts +32 -0
  204. package/layers/structure/grid/app/types/tracks.ts +18 -0
  205. package/layers/structure/grid/app/utils/placement.test.ts +19 -0
  206. package/layers/structure/grid/app/utils/placement.ts +15 -0
  207. package/layers/structure/grid/nuxt.config.ts +22 -0
  208. package/layers/{theme → structure/grid}/package.json +3 -3
  209. package/layers/structure/layout/app/app.config.ts +116 -0
  210. package/layers/{layout → structure/layout}/app/assets/css/layout/grids.css +11 -6
  211. package/layers/structure/layout/app/assets/css/layout.css +1 -0
  212. package/layers/structure/layout/app/components/HStack.vue +41 -0
  213. package/layers/{layout → structure/layout}/app/components/Layout/Grid/Debug.vue +5 -3
  214. package/layers/{layout → structure/layout}/app/components/Layout/Grid/Item.vue +4 -10
  215. package/layers/{layout → structure/layout}/app/components/Layout/Main.vue +3 -3
  216. package/layers/{layout → structure/layout}/app/components/Layout/Page/Header.vue +1 -1
  217. package/layers/{layout → structure/layout}/app/components/Layout/Page/index.vue +3 -3
  218. package/layers/{layout → structure/layout}/app/components/Layout/Section/index.vue +1 -1
  219. package/layers/structure/layout/app/components/Spacer.vue +21 -0
  220. package/layers/structure/layout/app/components/VStack.vue +37 -0
  221. package/layers/structure/layout/app/components/ZStack.vue +28 -0
  222. package/layers/structure/layout/app/layouts/default.vue +5 -0
  223. package/layers/{layout → structure/layout}/app/types/layouts.ts +2 -3
  224. package/layers/{layout → structure/layout}/app/utils/gridPlacementStyle.test.ts +7 -42
  225. package/layers/{layout → structure/layout}/app/utils/gridPlacementStyle.ts +4 -18
  226. package/layers/{layout → structure/layout}/nuxt.config.ts +1 -1
  227. package/layers/{layout → structure/layout}/package.json +1 -1
  228. package/layers/structure/layout/tsconfig.json +7 -0
  229. package/layers/{navigation → structure/navigation}/app/app.config.ts +4 -6
  230. package/layers/structure/navigation/app/components/Mast/Header.vue +11 -0
  231. package/layers/{navigation → structure/navigation}/app/components/Mast/Nav.vue +1 -1
  232. package/layers/structure/navigation/app/composables/mastNav.ts +15 -0
  233. package/layers/{navigation → structure/navigation}/app/utils/createModal.ts +22 -3
  234. package/layers/{navigation → structure/navigation}/nuxt.config.ts +1 -1
  235. package/layers/structure/navigation/tsconfig.json +7 -0
  236. package/layers/{routing → structure/routing}/app/app.config.ts +11 -2
  237. package/layers/{routing → structure/routing}/nuxt.config.ts +1 -1
  238. package/layers/{routing → structure/routing}/package.json +1 -1
  239. package/layers/structure/routing/tsconfig.json +7 -0
  240. package/package.json +56 -56
  241. package/docs/fallow-refactor/layers-ui.md +0 -27
  242. package/layers/animations/app/types/animations.ts +0 -8
  243. package/layers/animations/app/types/index.ts +0 -1
  244. package/layers/baseline/nuxt.config.ts +0 -24
  245. package/layers/baseline/package.json +0 -14
  246. package/layers/content/app/components/Blog/Card.vue +0 -43
  247. package/layers/content/app/components/Gallery/AmbientImage.vue +0 -44
  248. package/layers/content/app/components/Gallery/Card.vue +0 -43
  249. package/layers/content/app/components/NuxtContent/Renderer.vue +0 -14
  250. package/layers/content/app/components/Portfolio/Card.vue +0 -43
  251. package/layers/content/app/composables/createPortfolioComposables.ts +0 -50
  252. package/layers/content/app/composables/useBlogPost.ts +0 -3
  253. package/layers/content/app/composables/useGalleryItem.ts +0 -3
  254. package/layers/content/app/composables/usePortfolioItem.ts +0 -3
  255. package/layers/content/app/composables/usePortfolioItems.ts +0 -26
  256. package/layers/content/app/types/app-config.d.ts +0 -14
  257. package/layers/core/app/assets/css-backup.zip +0 -0
  258. package/layers/core/app/composables/useEnv.ts +0 -23
  259. package/layers/core/app/composables/useScrollGuard.ts +0 -243
  260. package/layers/core/app/plugins/feature-detection.client.ts +0 -34
  261. package/layers/core/app/plugins/init.ts +0 -192
  262. package/layers/core/app/plugins/scroll-guard.client.ts +0 -56
  263. package/layers/core/app/types/app-config.d.ts +0 -63
  264. package/layers/core/app/types/scroll-guard.ts +0 -25
  265. package/layers/core/app/utils/helpers.test.ts +0 -55
  266. package/layers/core/app/utils/helpers.ts +0 -248
  267. package/layers/core/app/utils/regex.test.ts +0 -31
  268. package/layers/feeds/tsconfig.json +0 -7
  269. package/layers/forms/app/app.config.ts +0 -3
  270. package/layers/forms/tsconfig.json +0 -7
  271. package/layers/layout/app/app.config.ts +0 -180
  272. package/layers/layout/app/assets/css/layout/modes/fluid.css +0 -109
  273. package/layers/layout/app/assets/css/layout.css +0 -2
  274. package/layers/layout/app/components/Layout/Container.vue +0 -46
  275. package/layers/layout/app/components/Layout/Page/Container.vue +0 -103
  276. package/layers/layout/app/components/Layout/Section/Grid.vue +0 -46
  277. package/layers/layout/app/components/Layout/Section/Sidebar.vue +0 -84
  278. package/layers/layout/app/components/Layout/Section/Stack.vue +0 -63
  279. package/layers/layout/app/components/Layout/Section/Title.vue +0 -33
  280. package/layers/layout/app/composables/GridPlacement.ts +0 -31
  281. package/layers/layout/app/types/app-config.d.ts +0 -14
  282. package/layers/layout/tsconfig.json +0 -7
  283. package/layers/mailer/server/types.d.ts +0 -11
  284. package/layers/mailer/tsconfig.json +0 -7
  285. package/layers/metadata/app/composables/useMetadataItem.ts +0 -15
  286. package/layers/metadata/app/composables/useMetadataSearch.ts +0 -29
  287. package/layers/metadata/providers/comicvine/tsconfig.json +0 -7
  288. package/layers/metadata/providers/google-books/tsconfig.json +0 -7
  289. package/layers/metadata/providers/openlibrary/tsconfig.json +0 -7
  290. package/layers/metadata/tsconfig.json +0 -7
  291. package/layers/motion/app/components/Motion/index.vue +0 -16
  292. package/layers/navigation/app/components/Mast/Header.vue +0 -18
  293. package/layers/navigation/app/components/Mast/Main.vue +0 -7
  294. package/layers/navigation/app/composables/mastNav.ts +0 -26
  295. package/layers/navigation/app/utils/regex.ts +0 -6
  296. package/layers/navigation/tsconfig.json +0 -7
  297. package/layers/page-transitions/tsconfig.json +0 -7
  298. package/layers/routing/app/types/app-config.d.ts +0 -7
  299. package/layers/routing/tsconfig.json +0 -7
  300. package/layers/scripts/app/types/index.ts +0 -1
  301. package/layers/scripts/app/types/scripts.ts +0 -14
  302. package/layers/scripts/tsconfig.json +0 -7
  303. package/layers/scroll/app/app.config.ts +0 -31
  304. package/layers/scroll/tsconfig.json +0 -7
  305. package/layers/seo/app/composables/useSeoConfig.ts +0 -7
  306. package/layers/seo/tsconfig.json +0 -7
  307. package/layers/shader/app/app.config.ts +0 -9
  308. package/layers/shader/app/types/app-config.d.ts +0 -7
  309. package/layers/shader/tsconfig.json +0 -7
  310. package/layers/starter/app/app.config.ts +0 -10
  311. package/layers/starter/app/components/StarterDesignSystem.vue +0 -1913
  312. package/layers/starter/app/components/StarterHome.vue +0 -441
  313. package/layers/starter/nuxt.config.ts +0 -15
  314. package/layers/starter/package.json +0 -10
  315. package/layers/theme/app/app.config.ts +0 -3
  316. package/layers/theme/app/types/app-config.d.ts +0 -10
  317. package/layers/theme/app/types/theme.ts +0 -23
  318. package/layers/theme/nuxt.config.ts +0 -74
  319. package/layers/transitions/tsconfig.json +0 -7
  320. package/layers/typography/app/components/Typography/CodeBlock.vue +0 -41
  321. package/layers/typography/app/components/Typography/QuoteBlock.vue +0 -23
  322. package/layers/typography/tsconfig.json +0 -7
  323. package/layers/ui/app/assets/css/ui.css +0 -4
  324. package/layers/ui/app/layouts/default.vue +0 -8
  325. package/layers/ui/nuxt.config.ts +0 -22
  326. package/layers/ui/tsconfig.json +0 -7
  327. package/layers/visual/app/types/breakpoints.ts +0 -179
  328. package/layers/visual/tsconfig.json +0 -7
  329. /package/layers/{auth → data/auth}/app/middleware/auth.ts +0 -0
  330. /package/layers/{auth → data/auth}/server/routes/auth/github.get.ts +0 -0
  331. /package/layers/{database → data/database}/server/utils/drizzle.ts +0 -0
  332. /package/layers/{database → data/database}/server/utils/sql.ts +0 -0
  333. /package/layers/{forms → data/forms}/app/components/Form/Contact.vue +0 -0
  334. /package/layers/{forms → data/forms}/app/components/Form/Field.vue +0 -0
  335. /package/layers/{forms → data/forms}/app/composables/useFormSchema.ts +0 -0
  336. /package/layers/{forms → data/forms}/app/composables/useFormsFetch.ts +0 -0
  337. /package/layers/{forms → data/forms}/app/config/fields.ts +0 -0
  338. /package/layers/{forms → data/forms}/app/types/fields.ts +0 -0
  339. /package/layers/{forms → data/forms}/app/types/index.ts +0 -0
  340. /package/layers/{forms → data/forms}/app/utils/contact-schema.test.ts +0 -0
  341. /package/layers/{forms → data/forms}/app/utils/contact-schema.ts +0 -0
  342. /package/layers/{forms → data/forms}/app/utils/fieldProps.test.ts +0 -0
  343. /package/layers/{forms → data/forms}/app/utils/fieldProps.ts +0 -0
  344. /package/layers/{forms → data/forms}/nuxt.config.ts +0 -0
  345. /package/layers/{forms → data/forms}/server/api/contact.post.ts +0 -0
  346. /package/layers/{mailer → data/mailer}/app/types/index.ts +0 -0
  347. /package/layers/{mailer → data/mailer}/app/types/mailer.ts +0 -0
  348. /package/layers/{mailer → data/mailer}/server/utils/config.ts +0 -0
  349. /package/layers/{mailer → data/mailer}/server/utils/email.ts +0 -0
  350. /package/layers/{mailer → data/mailer}/server/utils/hooks.ts +0 -0
  351. /package/layers/{metadata → data/metadata}/providers/comicvine/server/plugins/comicvine-register.ts +0 -0
  352. /package/layers/{metadata → data/metadata}/providers/comicvine/server/utils/metadata-comicvine/client.ts +0 -0
  353. /package/layers/{metadata → data/metadata}/providers/comicvine/server/utils/metadata-comicvine/normalise.test.ts +0 -0
  354. /package/layers/{metadata → data/metadata}/providers/comicvine/server/utils/metadata-comicvine/normalise.ts +0 -0
  355. /package/layers/{metadata → data/metadata}/providers/comicvine/server/utils/metadata-comicvine/provider.ts +0 -0
  356. /package/layers/{metadata → data/metadata}/providers/comicvine/server/utils/metadata-comicvine/types.ts +0 -0
  357. /package/layers/{metadata → data/metadata}/providers/google-books/server/plugins/google-books-register.ts +0 -0
  358. /package/layers/{metadata → data/metadata}/providers/google-books/server/utils/metadata-google-books/client.test.ts +0 -0
  359. /package/layers/{metadata → data/metadata}/providers/google-books/server/utils/metadata-google-books/normalise.test.ts +0 -0
  360. /package/layers/{metadata → data/metadata}/providers/google-books/server/utils/metadata-google-books/normalise.ts +0 -0
  361. /package/layers/{metadata → data/metadata}/providers/google-books/server/utils/metadata-google-books/provider.ts +0 -0
  362. /package/layers/{metadata → data/metadata}/providers/google-books/server/utils/metadata-google-books/types.ts +0 -0
  363. /package/layers/{metadata → data/metadata}/providers/openlibrary/nuxt.config.ts +0 -0
  364. /package/layers/{metadata → data/metadata}/providers/openlibrary/server/plugins/openlibrary-register.ts +0 -0
  365. /package/layers/{metadata → data/metadata}/providers/openlibrary/server/utils/metadata-openlibrary/client.test.ts +0 -0
  366. /package/layers/{metadata → data/metadata}/providers/openlibrary/server/utils/metadata-openlibrary/normalise.test.ts +0 -0
  367. /package/layers/{metadata → data/metadata}/providers/openlibrary/server/utils/metadata-openlibrary/normalise.ts +0 -0
  368. /package/layers/{metadata → data/metadata}/providers/openlibrary/server/utils/metadata-openlibrary/provider.ts +0 -0
  369. /package/layers/{metadata → data/metadata}/providers/openlibrary/server/utils/metadata-openlibrary/types.ts +0 -0
  370. /package/layers/{metadata → data/metadata}/providers/themoviedb/server/plugins/tmdb-register.ts +0 -0
  371. /package/layers/{metadata → data/metadata}/providers/themoviedb/server/utils/metadata-tmdb/client.test.ts +0 -0
  372. /package/layers/{metadata → data/metadata}/providers/themoviedb/server/utils/metadata-tmdb/client.ts +0 -0
  373. /package/layers/{metadata → data/metadata}/providers/themoviedb/server/utils/metadata-tmdb/normalise.test.ts +0 -0
  374. /package/layers/{metadata → data/metadata}/providers/themoviedb/server/utils/metadata-tmdb/normalise.ts +0 -0
  375. /package/layers/{metadata → data/metadata}/providers/themoviedb/server/utils/metadata-tmdb/provider.ts +0 -0
  376. /package/layers/{metadata → data/metadata}/providers/themoviedb/server/utils/metadata-tmdb/types.ts +0 -0
  377. /package/layers/{metadata → data/metadata}/server/api/metadata/lookup.get.ts +0 -0
  378. /package/layers/{metadata → data/metadata}/server/api/metadata/providers.get.ts +0 -0
  379. /package/layers/{metadata → data/metadata}/server/api/metadata/search.get.ts +0 -0
  380. /package/layers/{metadata → data/metadata}/server/api/metadata/status.get.ts +0 -0
  381. /package/layers/{metadata → data/metadata}/server/api/metadata/sync.post.ts +0 -0
  382. /package/layers/{metadata → data/metadata}/server/utils/metadata/cache.test.ts +0 -0
  383. /package/layers/{metadata → data/metadata}/server/utils/metadata/cache.ts +0 -0
  384. /package/layers/{metadata → data/metadata}/server/utils/metadata/errors.ts +0 -0
  385. /package/layers/{metadata → data/metadata}/server/utils/metadata/provider-registry.test.ts +0 -0
  386. /package/layers/{metadata → data/metadata}/server/utils/metadata/provider-registry.ts +0 -0
  387. /package/layers/{metadata → data/metadata}/server/utils/metadata/search.test.ts +0 -0
  388. /package/layers/{feeds → delivery/feeds}/app/app.config.ts +0 -0
  389. /package/layers/{feeds → delivery/feeds}/app/assets/css/feeds.css +0 -0
  390. /package/layers/{feeds → delivery/feeds}/public/feed/style.css +0 -0
  391. /package/layers/{feeds → delivery/feeds}/server/routes/feed/[collection]/atom/all.get.ts +0 -0
  392. /package/layers/{feeds → delivery/feeds}/server/routes/feed/[collection]/atom.get.ts +0 -0
  393. /package/layers/{feeds → delivery/feeds}/server/routes/feed/[collection]/json/all.get.ts +0 -0
  394. /package/layers/{feeds → delivery/feeds}/server/routes/feed/[collection]/json.get.ts +0 -0
  395. /package/layers/{feeds → delivery/feeds}/server/routes/feed/[collection]/rss/all.get.ts +0 -0
  396. /package/layers/{feeds → delivery/feeds}/server/routes/feed/[collection]/rss.get.ts +0 -0
  397. /package/layers/{feeds → delivery/feeds}/server/routes/feed/atom/all.get.ts +0 -0
  398. /package/layers/{feeds → delivery/feeds}/server/routes/feed/atom.get.ts +0 -0
  399. /package/layers/{feeds → delivery/feeds}/server/routes/feed/demo.get.ts +0 -0
  400. /package/layers/{feeds → delivery/feeds}/server/routes/feed/index.get.ts +0 -0
  401. /package/layers/{feeds → delivery/feeds}/server/routes/feed/json/all.get.ts +0 -0
  402. /package/layers/{feeds → delivery/feeds}/server/routes/feed/json.get.ts +0 -0
  403. /package/layers/{feeds → delivery/feeds}/server/routes/feed/rss/all.get.ts +0 -0
  404. /package/layers/{feeds → delivery/feeds}/server/routes/feed/rss.get.ts +0 -0
  405. /package/layers/{feeds → delivery/feeds}/server/routes/feed/style.xsl.get.ts +0 -0
  406. /package/layers/{feeds → delivery/feeds}/server/utils/cache.ts +0 -0
  407. /package/layers/{feeds → delivery/feeds}/server/utils/content-adapter.test.ts +0 -0
  408. /package/layers/{feeds → delivery/feeds}/server/utils/content-adapter.ts +0 -0
  409. /package/layers/{feeds → delivery/feeds}/server/utils/feed-author.test.ts +0 -0
  410. /package/layers/{feeds → delivery/feeds}/server/utils/feed-author.ts +0 -0
  411. /package/layers/{feeds → delivery/feeds}/server/utils/feed-config.test.ts +0 -0
  412. /package/layers/{feeds → delivery/feeds}/server/utils/feed-xml.ts +0 -0
  413. /package/layers/{feeds → delivery/feeds}/server/utils/formats/atom.ts +0 -0
  414. /package/layers/{feeds → delivery/feeds}/server/utils/formats/json.ts +0 -0
  415. /package/layers/{feeds → delivery/feeds}/server/utils/formats/rss.ts +0 -0
  416. /package/layers/{feeds → delivery/feeds}/server/utils/formats.test.ts +0 -0
  417. /package/layers/{feeds → delivery/feeds}/server/utils/types.ts +0 -0
  418. /package/layers/{scripts → delivery/scripts}/app/app.config.ts +0 -0
  419. /package/layers/{baseline → delivery/scripts}/app/components/BaselineStatus.vue +0 -0
  420. /package/layers/{scripts → delivery/scripts}/app/composables/useScriptLoader.ts +0 -0
  421. /package/layers/{scripts → delivery/scripts}/app/composables/useYoutubeEmbed.ts +0 -0
  422. /package/layers/{baseline → delivery/scripts}/app/plugins/baseline-status.client.ts +0 -0
  423. /package/layers/{seo → delivery/seo}/app/app.config.ts +0 -0
  424. /package/layers/{theme → design-system/theming}/app/assets/css/theme.css +0 -0
  425. /package/layers/{theme → design-system/theming}/app/components/ThemePicker/Menu.vue +0 -0
  426. /package/layers/{theme → design-system/theming}/app/components/ThemePicker/MenuButton.vue +0 -0
  427. /package/layers/{theme → design-system/theming}/app/composables/useTheme.ts +0 -0
  428. /package/layers/{theme → design-system/theming}/app/composables/useThemePreferenceModels.ts +0 -0
  429. /package/layers/{theme → design-system/theming}/app/composables/useThemePreferences.ts +0 -0
  430. /package/layers/{theme → design-system/theming}/app/types/index.ts +0 -0
  431. /package/layers/{theme → design-system/theming}/server/utils/accent-css.test.ts +0 -0
  432. /package/layers/{theme → design-system/theming}/server/utils/fouc-config.test.ts +0 -0
  433. /package/layers/{theme → design-system/theming}/server/utils/fouc-config.ts +0 -0
  434. /package/layers/{typography → design-system/typography}/app/components/Typography/TextStroke.vue +0 -0
  435. /package/layers/{typography → design-system/typography}/app/composables/color.ts +0 -0
  436. /package/layers/{typography → design-system/typography}/app/types/colors.ts +0 -0
  437. /package/layers/{typography → design-system/typography}/app/types/index.ts +0 -0
  438. /package/layers/{typography → design-system/typography}/package.json +0 -0
  439. /package/layers/{visual → design-system/visual}/app/assets/css/visual.css +0 -0
  440. /package/layers/{visual → design-system/visual}/app/components/Base/Modal.vue +0 -0
  441. /package/layers/{visual → design-system/visual}/app/components/Media/Picture.vue +0 -0
  442. /package/layers/{visual → design-system/visual}/app/components/Progress/Bar.vue +0 -0
  443. /package/layers/{visual → design-system/visual}/app/components/Progress/Circular.vue +0 -0
  444. /package/layers/{visual → design-system/visual}/app/components/Tint/Overlay.vue +0 -0
  445. /package/layers/{visual → design-system/visual}/app/composables/accent.ts +0 -0
  446. /package/layers/{visual → design-system/visual}/app/composables/picture.ts +0 -0
  447. /package/layers/{visual → design-system/visual}/app/composables/tint.ts +0 -0
  448. /package/layers/{visual → design-system/visual}/app/types/accent.ts +0 -0
  449. /package/layers/{visual → design-system/visual}/app/types/gradient.ts +0 -0
  450. /package/layers/{visual → design-system/visual}/app/types/index.ts +0 -0
  451. /package/layers/{visual → design-system/visual}/app/types/tint.ts +0 -0
  452. /package/layers/{visual → design-system/visual}/app/utils/colorTokens.test.ts +0 -0
  453. /package/layers/{visual → design-system/visual}/app/utils/colorTokens.ts +0 -0
  454. /package/layers/{visual → design-system/visual}/app/utils/gradientStyle.test.ts +0 -0
  455. /package/layers/{visual → design-system/visual}/app/utils/gradientStyle.ts +0 -0
  456. /package/layers/{visual → design-system/visual}/app/utils/responsiveSizes.test.ts +0 -0
  457. /package/layers/{visual → design-system/visual}/app/utils/responsiveSizes.ts +0 -0
  458. /package/layers/{visual → design-system/visual}/package.json +0 -0
  459. /package/layers/{animations → motion/animations}/app/components/Motion/CountUp.vue +0 -0
  460. /package/layers/{animations → motion/animations}/app/components/Motion/Cursor.vue +0 -0
  461. /package/layers/{animations → motion/animations}/app/components/Motion/Magnetic.vue +0 -0
  462. /package/layers/{animations → motion/animations}/app/components/Motion/MarqueeText.vue +0 -0
  463. /package/layers/{animations → motion/animations}/app/components/Motion/TextReveal.vue +0 -0
  464. /package/layers/{animations → motion/animations}/app/components/Motion/Tilt.vue +0 -0
  465. /package/layers/{animations → motion/animations}/app/components/Motion/VelocityEffect.vue +0 -0
  466. /package/layers/{animations → motion/animations}/app/composables/useCountUp.ts +0 -0
  467. /package/layers/{animations → motion/animations}/app/composables/useCursorFollower.ts +0 -0
  468. /package/layers/{animations → motion/animations}/app/composables/useMagneticElement.ts +0 -0
  469. /package/layers/{animations → motion/animations}/app/composables/useMarqueeCopies.ts +0 -0
  470. /package/layers/{animations → motion/animations}/app/composables/useMarqueeVelocity.ts +0 -0
  471. /package/layers/{animations → motion/animations}/app/composables/useTiltEffect.ts +0 -0
  472. /package/layers/{animations → motion/animations}/app/utils/pointerMotion.ts +0 -0
  473. /package/layers/{animations → motion/animations}/package.json +0 -0
  474. /package/layers/motion/{nuxt.config.ts → motion/nuxt.config.ts} +0 -0
  475. /package/layers/{page-transitions → motion/page-transitions}/app/app.config.ts +0 -0
  476. /package/layers/{page-transitions → motion/page-transitions}/package.json +0 -0
  477. /package/layers/{scroll → motion/scroll}/app/components/Motion/HorizontalScroll.vue +0 -0
  478. /package/layers/{scroll → motion/scroll}/app/components/Motion/Parallax.vue +0 -0
  479. /package/layers/{scroll → motion/scroll}/app/components/Motion/PinnedSection.vue +0 -0
  480. /package/layers/{scroll → motion/scroll}/app/components/Motion/ScrollLink.vue +0 -0
  481. /package/layers/{scroll → motion/scroll}/app/components/Motion/ScrollProgress.vue +0 -0
  482. /package/layers/{scroll → motion/scroll}/app/components/Motion/ScrollScene.vue +0 -0
  483. /package/layers/{scroll → motion/scroll}/app/components/Motion/ScrollStats.vue +0 -0
  484. /package/layers/{scroll → motion/scroll}/app/components/Motion/ScrollStep.vue +0 -0
  485. /package/layers/{scroll → motion/scroll}/app/composables/useGsap.ts +0 -0
  486. /package/layers/{scroll → motion/scroll}/app/composables/useScrollSteps.ts +0 -0
  487. /package/layers/{scroll → motion/scroll}/app/composables/useSectionProgress.ts +0 -0
  488. /package/layers/{scroll → motion/scroll}/app/types/index.ts +0 -0
  489. /package/layers/{scroll → motion/scroll}/app/types/scroll.ts +0 -0
  490. /package/layers/{scroll → motion/scroll}/app/utils/scroll.ts +0 -0
  491. /package/layers/{scroll → motion/scroll}/package.json +0 -0
  492. /package/layers/{transitions → motion/transitions}/app/assets/css/transitions.css +0 -0
  493. /package/layers/{transitions → motion/transitions}/app/components/Motion/Transition.vue +0 -0
  494. /package/layers/{transitions → motion/transitions}/package.json +0 -0
  495. /package/layers/{canvas → render/canvas}/app/components/ShaderCanvas.vue +0 -0
  496. /package/layers/{canvas → render/canvas}/app/types/index.ts +0 -0
  497. /package/layers/{canvas → render/canvas}/app/types/renderer.ts +0 -0
  498. /package/layers/{shader → render/shader}/app/assets/css/shader.css +0 -0
  499. /package/layers/{shader → render/shader}/app/components/Effect/Bloom.vue +0 -0
  500. /package/layers/{shader → render/shader}/app/components/Effect/ChromaticAberration.vue +0 -0
  501. /package/layers/{shader → render/shader}/app/components/Effect/PostProcessing.vue +0 -0
  502. /package/layers/{shader → render/shader}/app/components/Material/AmbientAurora.client.vue +0 -0
  503. /package/layers/{shader → render/shader}/app/components/Material/AmbientFlow.client.vue +0 -0
  504. /package/layers/{shader → render/shader}/app/components/Material/AmbientGradientMesh.client.vue +0 -0
  505. /package/layers/{shader → render/shader}/app/components/Material/AmbientNebula.client.vue +0 -0
  506. /package/layers/{shader → render/shader}/app/components/Material/AmbientOcean.client.vue +0 -0
  507. /package/layers/{shader → render/shader}/app/components/Material/Fresnel.client.vue +0 -0
  508. /package/layers/{shader → render/shader}/app/components/Material/Gradient.client.vue +0 -0
  509. /package/layers/{shader → render/shader}/app/components/Material/Image.client.vue +0 -0
  510. /package/layers/{shader → render/shader}/app/components/Material/Node.client.vue +0 -0
  511. /package/layers/{shader → render/shader}/app/components/Material/Noise.client.vue +0 -0
  512. /package/layers/{shader → render/shader}/app/components/Mesh/Plane.vue +0 -0
  513. /package/layers/{shader → render/shader}/app/components/Node/Color.client.vue +0 -0
  514. /package/layers/{shader → render/shader}/app/components/Node/Fresnel.client.vue +0 -0
  515. /package/layers/{shader → render/shader}/app/components/Node/Gradient.client.vue +0 -0
  516. /package/layers/{shader → render/shader}/app/components/Node/Mix.client.vue +0 -0
  517. /package/layers/{shader → render/shader}/app/components/Node/Noise.client.vue +0 -0
  518. /package/layers/{shader → render/shader}/app/components/Pipeline/ACESTonemap.client.vue +0 -0
  519. /package/layers/{shader → render/shader}/app/components/Pipeline/AddBlend.client.vue +0 -0
  520. /package/layers/{shader → render/shader}/app/components/Pipeline/AgedFilm.client.vue +0 -0
  521. /package/layers/{shader → render/shader}/app/components/Pipeline/Aurora.client.vue +0 -0
  522. /package/layers/{shader → render/shader}/app/components/Pipeline/BilinearGradient.client.vue +0 -0
  523. /package/layers/{shader → render/shader}/app/components/Pipeline/BillowNoise.client.vue +0 -0
  524. /package/layers/{shader → render/shader}/app/components/Pipeline/BrightnessContrast.client.vue +0 -0
  525. /package/layers/{shader → render/shader}/app/components/Pipeline/CellularNoise.client.vue +0 -0
  526. /package/layers/{shader → render/shader}/app/components/Pipeline/ChannelMixer.client.vue +0 -0
  527. /package/layers/{shader → render/shader}/app/components/Pipeline/ChebyshevNoiseField.client.vue +0 -0
  528. /package/layers/{shader → render/shader}/app/components/Pipeline/Checkerboard.client.vue +0 -0
  529. /package/layers/{shader → render/shader}/app/components/Pipeline/ChromaticAberration.client.vue +0 -0
  530. /package/layers/{shader → render/shader}/app/components/Pipeline/ChromaticScreenWaves.client.vue +0 -0
  531. /package/layers/{shader → render/shader}/app/components/Pipeline/Circle.client.vue +0 -0
  532. /package/layers/{shader → render/shader}/app/components/Pipeline/Clouds.client.vue +0 -0
  533. /package/layers/{shader → render/shader}/app/components/Pipeline/ColorBurnBlend.client.vue +0 -0
  534. /package/layers/{shader → render/shader}/app/components/Pipeline/ColorDodgeBlend.client.vue +0 -0
  535. /package/layers/{shader → render/shader}/app/components/Pipeline/ColourRamp.client.vue +0 -0
  536. /package/layers/{shader → render/shader}/app/components/Pipeline/ComplexPlaneField.client.vue +0 -0
  537. /package/layers/{shader → render/shader}/app/components/Pipeline/ConicGradient.client.vue +0 -0
  538. /package/layers/{shader → render/shader}/app/components/Pipeline/CosinePalette.client.vue +0 -0
  539. /package/layers/{shader → render/shader}/app/components/Pipeline/CoverageAlpha.client.vue +0 -0
  540. /package/layers/{shader → render/shader}/app/components/Pipeline/Cross.client.vue +0 -0
  541. /package/layers/{shader → render/shader}/app/components/Pipeline/CurlNoise.client.vue +0 -0
  542. /package/layers/{shader → render/shader}/app/components/Pipeline/DarkenBlend.client.vue +0 -0
  543. /package/layers/{shader → render/shader}/app/components/Pipeline/DayNightCycle.client.vue +0 -0
  544. /package/layers/{shader → render/shader}/app/components/Pipeline/Desaturate.client.vue +0 -0
  545. /package/layers/{shader → render/shader}/app/components/Pipeline/DiagonalGradient.client.vue +0 -0
  546. /package/layers/{shader → render/shader}/app/components/Pipeline/DiamondGradient.client.vue +0 -0
  547. /package/layers/{shader → render/shader}/app/components/Pipeline/DifferenceBlend.client.vue +0 -0
  548. /package/layers/{shader → render/shader}/app/components/Pipeline/DivideBlend.client.vue +0 -0
  549. /package/layers/{shader → render/shader}/app/components/Pipeline/DomainWarpedNoise.client.vue +0 -0
  550. /package/layers/{shader → render/shader}/app/components/Pipeline/Dots.client.vue +0 -0
  551. /package/layers/{shader → render/shader}/app/components/Pipeline/DuoTone.client.vue +0 -0
  552. /package/layers/{shader → render/shader}/app/components/Pipeline/ExclusionBlend.client.vue +0 -0
  553. /package/layers/{shader → render/shader}/app/components/Pipeline/ExponentialFog.client.vue +0 -0
  554. /package/layers/{shader → render/shader}/app/components/Pipeline/Exposure.client.vue +0 -0
  555. /package/layers/{shader → render/shader}/app/components/Pipeline/FBMNoise.client.vue +0 -0
  556. /package/layers/{shader → render/shader}/app/components/Pipeline/FilmBurn.client.vue +0 -0
  557. /package/layers/{shader → render/shader}/app/components/Pipeline/FilmGrain.client.vue +0 -0
  558. /package/layers/{shader → render/shader}/app/components/Pipeline/FisheyeRay.client.vue +0 -0
  559. /package/layers/{shader → render/shader}/app/components/Pipeline/Flame.client.vue +0 -0
  560. /package/layers/{shader → render/shader}/app/components/Pipeline/FocalGradient.client.vue +0 -0
  561. /package/layers/{shader → render/shader}/app/components/Pipeline/Gamma.client.vue +0 -0
  562. /package/layers/{shader → render/shader}/app/components/Pipeline/GodRays.client.vue +0 -0
  563. /package/layers/{shader → render/shader}/app/components/Pipeline/GradientNoise.client.vue +0 -0
  564. /package/layers/{shader → render/shader}/app/components/Pipeline/Grain.client.vue +0 -0
  565. /package/layers/{shader → render/shader}/app/components/Pipeline/Grid.client.vue +0 -0
  566. /package/layers/{shader → render/shader}/app/components/Pipeline/Halation.client.vue +0 -0
  567. /package/layers/{shader → render/shader}/app/components/Pipeline/Halftone.client.vue +0 -0
  568. /package/layers/{shader → render/shader}/app/components/Pipeline/HardLightBlend.client.vue +0 -0
  569. /package/layers/{shader → render/shader}/app/components/Pipeline/Haze.client.vue +0 -0
  570. /package/layers/{shader → render/shader}/app/components/Pipeline/Hexagon.client.vue +0 -0
  571. /package/layers/{shader → render/shader}/app/components/Pipeline/Hue.client.vue +0 -0
  572. /package/layers/{shader → render/shader}/app/components/Pipeline/Invert.client.vue +0 -0
  573. /package/layers/{shader → render/shader}/app/components/Pipeline/LensFlare.client.vue +0 -0
  574. /package/layers/{shader → render/shader}/app/components/Pipeline/LightenBlend.client.vue +0 -0
  575. /package/layers/{shader → render/shader}/app/components/Pipeline/LinearGradient.client.vue +0 -0
  576. /package/layers/{shader → render/shader}/app/components/Pipeline/LinearGradient4.client.vue +0 -0
  577. /package/layers/{shader → render/shader}/app/components/Pipeline/LinearToSRGB.client.vue +0 -0
  578. /package/layers/{shader → render/shader}/app/components/Pipeline/Marble.client.vue +0 -0
  579. /package/layers/{shader → render/shader}/app/components/Pipeline/MixBlend.client.vue +0 -0
  580. /package/layers/{shader → render/shader}/app/components/Pipeline/MonochromeTint.client.vue +0 -0
  581. /package/layers/{shader → render/shader}/app/components/Pipeline/MultiplyBlend.client.vue +0 -0
  582. /package/layers/{shader → render/shader}/app/components/Pipeline/NoisyGradient.client.vue +0 -0
  583. /package/layers/{shader → render/shader}/app/components/Pipeline/NoisyGradientBlend.client.vue +0 -0
  584. /package/layers/{shader → render/shader}/app/components/Pipeline/OverlayBlend.client.vue +0 -0
  585. /package/layers/{shader → render/shader}/app/components/Pipeline/PaperTexture.client.vue +0 -0
  586. /package/layers/{shader → render/shader}/app/components/Pipeline/Polygon.client.vue +0 -0
  587. /package/layers/{shader → render/shader}/app/components/Pipeline/Posterise.client.vue +0 -0
  588. /package/layers/{shader → render/shader}/app/components/Pipeline/RadialGradient.client.vue +0 -0
  589. /package/layers/{shader → render/shader}/app/components/Pipeline/RayAutoOrbit.client.vue +0 -0
  590. /package/layers/{shader → render/shader}/app/components/Pipeline/RayMouseOrbit.client.vue +0 -0
  591. /package/layers/{shader → render/shader}/app/components/Pipeline/RayRotateX.client.vue +0 -0
  592. /package/layers/{shader → render/shader}/app/components/Pipeline/RayRotateY.client.vue +0 -0
  593. /package/layers/{shader → render/shader}/app/components/Pipeline/RayRotateZ.client.vue +0 -0
  594. /package/layers/{shader → render/shader}/app/components/Pipeline/RayTiltBasis.client.vue +0 -0
  595. /package/layers/{shader → render/shader}/app/components/Pipeline/RaymarchTunnel.client.vue +0 -0
  596. /package/layers/{shader → render/shader}/app/components/Pipeline/Rectangle.client.vue +0 -0
  597. /package/layers/{shader → render/shader}/app/components/Pipeline/ReinhardTonemap.client.vue +0 -0
  598. /package/layers/{shader → render/shader}/app/components/Pipeline/RidgedNoise.client.vue +0 -0
  599. /package/layers/{shader → render/shader}/app/components/Pipeline/Ring.client.vue +0 -0
  600. /package/layers/{shader → render/shader}/app/components/Pipeline/RingField.client.vue +0 -0
  601. /package/layers/{shader → render/shader}/app/components/Pipeline/RisographGrain.client.vue +0 -0
  602. /package/layers/{shader → render/shader}/app/components/Pipeline/RotatedGradientBlend.client.vue +0 -0
  603. /package/layers/{shader → render/shader}/app/components/Pipeline/SDFColourMask.client.vue +0 -0
  604. /package/layers/{shader → render/shader}/app/components/Pipeline/SDFRadialMask.client.vue +0 -0
  605. /package/layers/{shader → render/shader}/app/components/Pipeline/SRGBToLinear.client.vue +0 -0
  606. /package/layers/{shader → render/shader}/app/components/Pipeline/Saturation.client.vue +0 -0
  607. /package/layers/{shader → render/shader}/app/components/Pipeline/Scanlines.client.vue +0 -0
  608. /package/layers/{shader → render/shader}/app/components/Pipeline/ScreenBlend.client.vue +0 -0
  609. /package/layers/{shader → render/shader}/app/components/Pipeline/ShaderDebugger.client.vue +0 -0
  610. /package/layers/{shader → render/shader}/app/components/Pipeline/SimplexNoise.client.vue +0 -0
  611. /package/layers/{shader → render/shader}/app/components/Pipeline/SkyAtmosphere.client.vue +0 -0
  612. /package/layers/{shader → render/shader}/app/components/Pipeline/SoftLightBlend.client.vue +0 -0
  613. /package/layers/{shader → render/shader}/app/components/Pipeline/SolidColour.client.vue +0 -0
  614. /package/layers/{shader → render/shader}/app/components/Pipeline/SplitTone.client.vue +0 -0
  615. /package/layers/{shader → render/shader}/app/components/Pipeline/Star.client.vue +0 -0
  616. /package/layers/{shader → render/shader}/app/components/Pipeline/Starfield.client.vue +0 -0
  617. /package/layers/{shader → render/shader}/app/components/Pipeline/Stripes.client.vue +0 -0
  618. /package/layers/{shader → render/shader}/app/components/Pipeline/SubtractBlend.client.vue +0 -0
  619. /package/layers/{shader → render/shader}/app/components/Pipeline/TanhTonemap.client.vue +0 -0
  620. /package/layers/{shader → render/shader}/app/components/Pipeline/Threshold.client.vue +0 -0
  621. /package/layers/{shader → render/shader}/app/components/Pipeline/Tint.client.vue +0 -0
  622. /package/layers/{shader → render/shader}/app/components/Pipeline/Triangle.client.vue +0 -0
  623. /package/layers/{shader → render/shader}/app/components/Pipeline/UVAspectCorrect.client.vue +0 -0
  624. /package/layers/{shader → render/shader}/app/components/Pipeline/UVBreath.client.vue +0 -0
  625. /package/layers/{shader → render/shader}/app/components/Pipeline/UVBulge.client.vue +0 -0
  626. /package/layers/{shader → render/shader}/app/components/Pipeline/UVClamp.client.vue +0 -0
  627. /package/layers/{shader → render/shader}/app/components/Pipeline/UVColumnOffset.client.vue +0 -0
  628. /package/layers/{shader → render/shader}/app/components/Pipeline/UVFlipX.client.vue +0 -0
  629. /package/layers/{shader → render/shader}/app/components/Pipeline/UVFlipXY.client.vue +0 -0
  630. /package/layers/{shader → render/shader}/app/components/Pipeline/UVFlipY.client.vue +0 -0
  631. /package/layers/{shader → render/shader}/app/components/Pipeline/UVFractBand.client.vue +0 -0
  632. /package/layers/{shader → render/shader}/app/components/Pipeline/UVMousePull.client.vue +0 -0
  633. /package/layers/{shader → render/shader}/app/components/Pipeline/UVNoiseRotate.client.vue +0 -0
  634. /package/layers/{shader → render/shader}/app/components/Pipeline/UVNoiseWarp.client.vue +0 -0
  635. /package/layers/{shader → render/shader}/app/components/Pipeline/UVOrbit.client.vue +0 -0
  636. /package/layers/{shader → render/shader}/app/components/Pipeline/UVParallax.client.vue +0 -0
  637. /package/layers/{shader → render/shader}/app/components/Pipeline/UVPixelate.client.vue +0 -0
  638. /package/layers/{shader → render/shader}/app/components/Pipeline/UVPulse.client.vue +0 -0
  639. /package/layers/{shader → render/shader}/app/components/Pipeline/UVRipple.client.vue +0 -0
  640. /package/layers/{shader → render/shader}/app/components/Pipeline/UVRotate.client.vue +0 -0
  641. /package/layers/{shader → render/shader}/app/components/Pipeline/UVScale.client.vue +0 -0
  642. /package/layers/{shader → render/shader}/app/components/Pipeline/UVScroll.client.vue +0 -0
  643. /package/layers/{shader → render/shader}/app/components/Pipeline/UVScrollX.client.vue +0 -0
  644. /package/layers/{shader → render/shader}/app/components/Pipeline/UVScrollY.client.vue +0 -0
  645. /package/layers/{shader → render/shader}/app/components/Pipeline/UVShear.client.vue +0 -0
  646. /package/layers/{shader → render/shader}/app/components/Pipeline/UVSineWarpXY.client.vue +0 -0
  647. /package/layers/{shader → render/shader}/app/components/Pipeline/UVSwapAxes.client.vue +0 -0
  648. /package/layers/{shader → render/shader}/app/components/Pipeline/UVTile.client.vue +0 -0
  649. /package/layers/{shader → render/shader}/app/components/Pipeline/UVTwirl.client.vue +0 -0
  650. /package/layers/{shader → render/shader}/app/components/Pipeline/UVWarp.client.vue +0 -0
  651. /package/layers/{shader → render/shader}/app/components/Pipeline/VHSBleed.client.vue +0 -0
  652. /package/layers/{shader → render/shader}/app/components/Pipeline/ValueNoise.client.vue +0 -0
  653. /package/layers/{shader → render/shader}/app/components/Pipeline/Vibrance.client.vue +0 -0
  654. /package/layers/{shader → render/shader}/app/components/Pipeline/Vignette.client.vue +0 -0
  655. /package/layers/{shader → render/shader}/app/components/Pipeline/VoronoiEdges.client.vue +0 -0
  656. /package/layers/{shader → render/shader}/app/components/Pipeline/Water.client.vue +0 -0
  657. /package/layers/{shader → render/shader}/app/components/Pipeline/WaveBendLayer.client.vue +0 -0
  658. /package/layers/{shader → render/shader}/app/components/Pipeline/WaveColourLayer.client.vue +0 -0
  659. /package/layers/{shader → render/shader}/app/components/Pipeline/WhiteBalance.client.vue +0 -0
  660. /package/layers/{shader → render/shader}/app/components/Pipeline/Wood.client.vue +0 -0
  661. /package/layers/{shader → render/shader}/app/components/Preset/Aurora.client.vue +0 -0
  662. /package/layers/{shader → render/shader}/app/components/Preset/Flow.client.vue +0 -0
  663. /package/layers/{shader → render/shader}/app/components/Preset/GradientMesh.client.vue +0 -0
  664. /package/layers/{shader → render/shader}/app/components/Preset/Nebula.client.vue +0 -0
  665. /package/layers/{shader → render/shader}/app/components/Preset/Ocean.client.vue +0 -0
  666. /package/layers/{shader → render/shader}/app/components/Preset/ThemeAurora.client.vue +0 -0
  667. /package/layers/{shader → render/shader}/app/components/Preset/ThemeBubble.client.vue +0 -0
  668. /package/layers/{shader → render/shader}/app/components/Preset/ThemeFlow.client.vue +0 -0
  669. /package/layers/{shader → render/shader}/app/components/Preset/ThemeGradient.client.vue +0 -0
  670. /package/layers/{shader → render/shader}/app/components/Preset/ThemeLavaLamp.client.vue +0 -0
  671. /package/layers/{shader → render/shader}/app/components/Preset/ThemePlasma.client.vue +0 -0
  672. /package/layers/{shader → render/shader}/app/components/Preset/ThemeWave.client.vue +0 -0
  673. /package/layers/{shader → render/shader}/app/components/Shader/Background.client.vue +0 -0
  674. /package/layers/{shader → render/shader}/app/components/Shader/Debug.vue +0 -0
  675. /package/layers/{shader → render/shader}/app/components/Shader/Host.client.vue +0 -0
  676. /package/layers/{shader → render/shader}/app/components/Shader/Material.client.vue +0 -0
  677. /package/layers/{shader → render/shader}/app/components/Shader/Pipeline.client.vue +0 -0
  678. /package/layers/{shader → render/shader}/app/components/Shader/PipelineContext.vue +0 -0
  679. /package/layers/{shader → render/shader}/app/components/Shader/Runtime.client.vue +0 -0
  680. /package/layers/{shader → render/shader}/app/composables/useAmbientMaterials.ts +0 -0
  681. /package/layers/{shader → render/shader}/app/composables/useCSSColourUniform.ts +0 -0
  682. /package/layers/{shader → render/shader}/app/composables/useCSSFloatUniform.ts +0 -0
  683. /package/layers/{shader → render/shader}/app/composables/useMousePosition.ts +0 -0
  684. /package/layers/{shader → render/shader}/app/composables/useShader.ts +0 -0
  685. /package/layers/{shader → render/shader}/app/composables/useShaderColor.ts +0 -0
  686. /package/layers/{shader → render/shader}/app/composables/useShaderFloat.ts +0 -0
  687. /package/layers/{shader → render/shader}/app/composables/useShaderGraph.ts +0 -0
  688. /package/layers/{shader → render/shader}/app/composables/useShaderMixBlend.ts +0 -0
  689. /package/layers/{shader → render/shader}/app/composables/useShaderPerf.ts +0 -0
  690. /package/layers/{shader → render/shader}/app/composables/useShaderPipeline.ts +0 -0
  691. /package/layers/{shader → render/shader}/app/composables/useShaderRuntime.ts +0 -0
  692. /package/layers/{shader → render/shader}/app/composables/useShaderVec2.ts +0 -0
  693. /package/layers/{shader → render/shader}/app/composables/useSunDirectionUniform.ts +0 -0
  694. /package/layers/{shader → render/shader}/app/composables/useTSLNodes.ts +0 -0
  695. /package/layers/{shader → render/shader}/app/composables/useThemeColors.ts +0 -0
  696. /package/layers/{shader → render/shader}/app/composables/useThemePreset.ts +0 -0
  697. /package/layers/{shader → render/shader}/app/composables/useUniformWatchers.ts +0 -0
  698. /package/layers/{shader → render/shader}/app/composables/useUniforms.ts +0 -0
  699. /package/layers/{shader → render/shader}/app/plugins/shader.client.ts +0 -0
  700. /package/layers/{shader → render/shader}/app/shaders/common/blend.ts +0 -0
  701. /package/layers/{shader → render/shader}/app/shaders/common/complex.ts +0 -0
  702. /package/layers/{shader → render/shader}/app/shaders/common/effects.ts +0 -0
  703. /package/layers/{shader → render/shader}/app/shaders/common/grain.ts +0 -0
  704. /package/layers/{shader → render/shader}/app/shaders/common/index.ts +0 -0
  705. /package/layers/{shader → render/shader}/app/shaders/common/lighting.ts +0 -0
  706. /package/layers/{shader → render/shader}/app/shaders/common/math.ts +0 -0
  707. /package/layers/{shader → render/shader}/app/shaders/common/nodes.ts +0 -0
  708. /package/layers/{shader → render/shader}/app/shaders/common/noise.ts +0 -0
  709. /package/layers/{shader → render/shader}/app/shaders/common/noiseHelpers.ts +0 -0
  710. /package/layers/{shader → render/shader}/app/shaders/common/palette.ts +0 -0
  711. /package/layers/{shader → render/shader}/app/shaders/common/patterns.ts +0 -0
  712. /package/layers/{shader → render/shader}/app/shaders/common/sdf.ts +0 -0
  713. /package/layers/{shader → render/shader}/app/shaders/common/shapes.ts +0 -0
  714. /package/layers/{shader → render/shader}/app/shaders/common/tonemapping.ts +0 -0
  715. /package/layers/{shader → render/shader}/app/shaders/common/uv.ts +0 -0
  716. /package/layers/{shader → render/shader}/app/shaders/createMaterial.ts +0 -0
  717. /package/layers/{shader → render/shader}/app/shaders/index.ts +0 -0
  718. /package/layers/{shader → render/shader}/app/shaders/layers/aurora.ts +0 -0
  719. /package/layers/{shader → render/shader}/app/shaders/layers/index.ts +0 -0
  720. /package/layers/{shader → render/shader}/app/shaders/layers/meshGradient.ts +0 -0
  721. /package/layers/{shader → render/shader}/app/shaders/layers/shaderGradient.ts +0 -0
  722. /package/layers/{shader → render/shader}/app/shaders/layers/stripe.ts +0 -0
  723. /package/layers/{shader → render/shader}/app/shaders/types.ts +0 -0
  724. /package/layers/{shader → render/shader}/app/types/index.ts +0 -0
  725. /package/layers/{shader → render/shader}/app/types/materials.ts +0 -0
  726. /package/layers/{shader → render/shader}/app/types/renderer.ts +0 -0
  727. /package/layers/{shader → render/shader}/app/types/tsl.ts +0 -0
  728. /package/layers/{shader → render/shader}/app/types/uniforms.ts +0 -0
  729. /package/layers/{shader → render/shader}/app/utils/tsl/animation.ts +0 -0
  730. /package/layers/{shader → render/shader}/app/utils/tsl/color.ts +0 -0
  731. /package/layers/{shader → render/shader}/app/utils/tsl/index.ts +0 -0
  732. /package/layers/{shader → render/shader}/app/utils/tsl/math.ts +0 -0
  733. /package/layers/{shader → render/shader}/app/utils/tsl/noise.ts +0 -0
  734. /package/layers/{shader → render/shader}/app/utils/tsl/oklch.ts +0 -0
  735. /package/layers/{shader → render/shader}/app/utils/tsl/patterns.ts +0 -0
  736. /package/layers/{shader → render/shader}/app/utils/tsl/tween.ts +0 -0
  737. /package/layers/{shader → render/shader}/app/utils/tsl/uv.ts +0 -0
  738. /package/layers/{shader → render/shader}/nuxt.config.ts +0 -0
  739. /package/layers/{layout → structure/layout}/app/components/Layout/Section/Gallery.vue +0 -0
  740. /package/layers/{layout → structure/layout}/app/components/Layout/Section/Hero.vue +0 -0
  741. /package/layers/{layout → structure/layout}/app/components/Layout/Section/Split.vue +0 -0
  742. /package/layers/{layout → structure/layout}/app/composables/useGridConfig.ts +0 -0
  743. /package/layers/{layout → structure/layout}/app/types/index.ts +0 -0
  744. /package/layers/{layout → structure/layout}/tailwind.config.js +0 -0
  745. /package/layers/{navigation → structure/navigation}/app/assets/css/navigation.css +0 -0
  746. /package/layers/{navigation → structure/navigation}/app/components/Links/Group.vue +0 -0
  747. /package/layers/{navigation → structure/navigation}/app/components/Links/Named.vue +0 -0
  748. /package/layers/{navigation → structure/navigation}/app/components/Mast/Footer.vue +0 -0
  749. /package/layers/{navigation → structure/navigation}/app/components/Mast/NavModal.vue +0 -0
  750. /package/layers/{navigation → structure/navigation}/app/components/Site/Subtitle.vue +0 -0
  751. /package/layers/{navigation → structure/navigation}/app/components/Site/Title.vue +0 -0
  752. /package/layers/{navigation → structure/navigation}/app/composables/toast.ts +0 -0
  753. /package/layers/{navigation → structure/navigation}/app/composables/useSite.ts +0 -0
  754. /package/layers/{navigation → structure/navigation}/app/types/index.ts +0 -0
  755. /package/layers/{navigation → structure/navigation}/app/types/nav.ts +0 -0
  756. /package/layers/{core → structure/navigation}/app/utils/regex.ts +0 -0
  757. /package/layers/{navigation → structure/navigation}/app/utils/site.test.ts +0 -0
  758. /package/layers/{navigation → structure/navigation}/app/utils/site.ts +0 -0
  759. /package/layers/{navigation → structure/navigation}/package.json +0 -0
  760. /package/layers/{routing → structure/routing}/app/composables/useFeatureFlags.ts +0 -0
  761. /package/layers/{routing → structure/routing}/app/composables/useMaintenance.ts +0 -0
  762. /package/layers/{routing → structure/routing}/app/composables/useRoutingConfig.ts +0 -0
  763. /package/layers/{routing → structure/routing}/app/middleware/01.maintenance.global.ts +0 -0
  764. /package/layers/{routing → structure/routing}/app/middleware/02.governance.global.ts +0 -0
  765. /package/layers/{routing → structure/routing}/app/plugins/feature-flags.client.ts +0 -0
  766. /package/layers/{routing → structure/routing}/app/plugins/scroll-routing.client.ts +0 -0
  767. /package/layers/{routing → structure/routing}/app/types/index.ts +0 -0
  768. /package/layers/{routing → structure/routing}/app/types/route-meta.d.ts +0 -0
  769. /package/layers/{routing → structure/routing}/app/types/routing.ts +0 -0
  770. /package/layers/{routing → structure/routing}/app/utils/resolveRoute.test.ts +0 -0
  771. /package/layers/{routing → structure/routing}/app/utils/resolveRoute.ts +0 -0
  772. /package/layers/{routing → structure/routing}/server/api/feature-flags.get.ts +0 -0
@@ -0,0 +1,1019 @@
1
+ # Vue Element System Implementation Plan
2
+
3
+ > **For agentic workers:** REQUIRED SUB-SKILL: Use superpowers:subagent-driven-development (recommended) or superpowers:executing-plans to implement this plan task-by-task. Steps use checkbox (`- [ ]`) syntax for tracking.
4
+
5
+ **Goal:** Add a polymorphic `Element` component to `layers/structure/layout` giving Vue templates a small, typed vocabulary (layout/grid/spacing/sizing/surface/interaction) instead of utility-class strings, reusing the layer's existing fluid-token and grid-placement engines.
6
+
7
+ **Architecture:** Six small composables, each resolving one property group to a `Partial<CSSProperties>`, merged inside `Element.vue`'s single computed `style`. Grid item-placement (`colStart`/`colSpan`/`rowStart`/`rowSpan`) delegates directly to the existing `buildGridPlacementStyle` from `gridPlacementStyle.ts` — no new placement math. Spacing (`p`/`px`/`py`/`gap`/`align`/`justify`) delegates to core's `useLayoutAttrs`, extended with `m`/`mx`/`my`. Surface/Sizing/Interaction are new, minimal, raw-CSS-passthrough composables.
8
+
9
+ **Tech Stack:** Vue 3 `<script setup>`, TypeScript, Vitest, Nuxt 4 layers (`#layers/*` aliases).
10
+
11
+ **Spec:** `docs/superpowers/specs/2026-09-03-vue-element-system-design.md`
12
+
13
+ ## Global Constraints
14
+
15
+ - No changes to `LayoutGridItem`, `gridPlacementStyle.ts` placement logic, or any fluid-rebuild-spec territory — read-only reuse.
16
+ - No semantic colour/token system — `bg`/`color`/`border`/`radius`/`shadow` are raw CSS passthrough (`CSSProperties[...]` typed), not token enums.
17
+ - Grid item-placement prop names match `LayoutGridItem`'s existing vocabulary: `colStart`/`colSpan`/`rowStart`/`rowSpan` — not the source doc's `span`/`start`/`end`.
18
+ - No semicolons, single quotes, ES5 trailing commas, max 100 char lines (`.claude/rules/typescript.md`).
19
+ - `<script setup lang="ts">`, script → template → style block order (`.claude/rules/vue-components.md`).
20
+ - `Element` is root-level, unprefixed component name, matching `HStack`/`VStack`/`ZStack`/`Spacer`.
21
+
22
+ ---
23
+
24
+ ## File Structure
25
+
26
+ ```
27
+ layers/core/app/composables/useLayoutAttrs.ts (modify: add m/mx/my)
28
+ layers/core/app/composables/useLayoutAttrs.test.ts (modify: add margin tests, only if file exists — else create)
29
+
30
+ layers/structure/layout/app/composables/
31
+ ├── useElementLayout.ts (new: display mode resolver)
32
+ ├── useElementLayout.test.ts (new)
33
+ ├── useElementGrid.ts (new: container-axis template + item-axis delegate)
34
+ ├── useElementGrid.test.ts (new)
35
+ ├── useElementSizing.ts (new: w/h/min/max/aspect passthrough)
36
+ ├── useElementSizing.test.ts (new)
37
+ ├── useElementSurface.ts (new: bg/color/border/radius/shadow passthrough)
38
+ ├── useElementSurface.test.ts (new)
39
+ ├── useElementInteraction.ts (new: cursor/select/pointer passthrough)
40
+ └── useElementInteraction.test.ts (new)
41
+
42
+ layers/structure/layout/app/types/element.ts (new: ElementProps union)
43
+
44
+ layers/structure/layout/app/components/Element.vue (new)
45
+
46
+ apps/playground/app/pages/element.vue (new: manual verification page)
47
+ ```
48
+
49
+ Each composable owns exactly one property group, mirrors the existing `gridPlacementStyle.ts` / `useLayoutAttrs.ts` pattern (plain exported function, `Partial<CSSProperties>` return), and gets its own test file — matching the existing `gridPlacementStyle.test.ts` convention (`describe`/`it`, vitest, no mocking needed since these are pure functions).
50
+
51
+ ---
52
+
53
+ ### Task 1: Extend `useLayoutAttrs` with margin support
54
+
55
+ **Files:**
56
+
57
+ - Modify: `layers/core/app/composables/useLayoutAttrs.ts`
58
+ - Test: `layers/core/app/composables/useLayoutAttrs.test.ts` (create if it doesn't exist)
59
+
60
+ **Interfaces:**
61
+
62
+ - Consumes: nothing new — extends existing `LayoutAttrsInput`, `Spacing` type from `../types/tokens`, `ResponsiveValue` from `../types/responsive`.
63
+ - Produces: `LayoutAttrsInput` gains `m?`, `mx?`, `my?` fields (same shape as existing `p`/`px`/`py`). `useLayoutAttrs()`'s returned `style` now also sets `margin`/`marginInline`/`marginBlock` when those props are passed.
64
+
65
+ - [ ] **Step 1: Check for an existing test file**
66
+
67
+ Run: `ls layers/core/app/composables/useLayoutAttrs.test.ts 2>/dev/null && echo EXISTS || echo MISSING`
68
+
69
+ If `EXISTS`, read the file first and add new `describe` blocks to it in Step 2 rather than replacing it. If `MISSING`, Step 2 creates the whole file.
70
+
71
+ - [ ] **Step 2: Write the failing tests**
72
+
73
+ Create/extend `layers/core/app/composables/useLayoutAttrs.test.ts`:
74
+
75
+ ```ts
76
+ import { describe, expect, it } from 'vitest'
77
+
78
+ import { useLayoutAttrs } from './useLayoutAttrs'
79
+
80
+ describe('useLayoutAttrs margin support', () => {
81
+ it('sets margin from a static token', () => {
82
+ const { style } = useLayoutAttrs(() => ({ m: 'md' }))
83
+ expect(style.value.margin).toBe('var(--fluid-space-md)')
84
+ })
85
+
86
+ it('sets marginInline from px-equivalent mx', () => {
87
+ const { style } = useLayoutAttrs(() => ({ mx: 'lg' }))
88
+ expect(style.value.marginInline).toBe('var(--fluid-space-lg)')
89
+ })
90
+
91
+ it('sets marginBlock from my', () => {
92
+ const { style } = useLayoutAttrs(() => ({ my: 'sm' }))
93
+ expect(style.value.marginBlock).toBe('var(--fluid-space-sm)')
94
+ })
95
+
96
+ it('resolves none to 0px for margin', () => {
97
+ const { style } = useLayoutAttrs(() => ({ m: 'none' }))
98
+ expect(style.value.margin).toBe('0px')
99
+ })
100
+
101
+ it('omits margin keys entirely when not passed', () => {
102
+ const { style } = useLayoutAttrs(() => ({ gap: 'md' }))
103
+ expect(style.value.margin).toBeUndefined()
104
+ expect(style.value.marginInline).toBeUndefined()
105
+ expect(style.value.marginBlock).toBeUndefined()
106
+ })
107
+
108
+ it('does not regress existing gap/align/justify/padding behavior', () => {
109
+ const { style } = useLayoutAttrs(() => ({
110
+ gap: 'md',
111
+ align: 'center',
112
+ justify: 'between',
113
+ p: 'lg',
114
+ }))
115
+ expect(style.value).toEqual({
116
+ gap: 'var(--fluid-space-md)',
117
+ padding: 'var(--fluid-space-lg)',
118
+ alignItems: 'center',
119
+ justifyContent: 'space-between',
120
+ })
121
+ })
122
+ })
123
+ ```
124
+
125
+ - [ ] **Step 3: Run tests to verify they fail**
126
+
127
+ Run: `cd layers/core && npx vitest run app/composables/useLayoutAttrs.test.ts`
128
+ Expected: FAIL — `style.value.margin` is `undefined` for the `m: 'md'` case (property not implemented yet).
129
+
130
+ - [ ] **Step 4: Implement margin support**
131
+
132
+ Edit `layers/core/app/composables/useLayoutAttrs.ts`:
133
+
134
+ ```ts
135
+ export type LayoutAttrsInput = {
136
+ gap?: ResponsiveValue<Spacing> | Spacing | undefined
137
+ align?: ResponsiveValue<Align> | Align | undefined
138
+ justify?: ResponsiveValue<Justify> | Justify | undefined
139
+ p?: ResponsiveValue<Spacing> | Spacing | undefined
140
+ px?: ResponsiveValue<Spacing> | Spacing | undefined
141
+ py?: ResponsiveValue<Spacing> | Spacing | undefined
142
+ m?: ResponsiveValue<Spacing> | Spacing | undefined
143
+ mx?: ResponsiveValue<Spacing> | Spacing | undefined
144
+ my?: ResponsiveValue<Spacing> | Spacing | undefined
145
+ }
146
+ ```
147
+
148
+ Update the `applySpacing` call signature to accept the margin CSS props, then extend `useLayoutAttrs`'s `computed`:
149
+
150
+ ```ts
151
+ function applySpacing(
152
+ result: CSSProperties,
153
+ cssProp:
154
+ | 'gap'
155
+ | 'padding'
156
+ | 'paddingInline'
157
+ | 'paddingBlock'
158
+ | 'margin'
159
+ | 'marginInline'
160
+ | 'marginBlock',
161
+ value: ResponsiveValue<Spacing> | Spacing | undefined
162
+ ): void {
163
+ const resolved = resolveDefault(value)
164
+ if (resolved) result[cssProp] = spacingVar(resolved)
165
+ }
166
+
167
+ export function useLayoutAttrs(input: MaybeRefOrGetter<LayoutAttrsInput>): {
168
+ style: ComputedRef<CSSProperties>
169
+ } {
170
+ const style = computed((): CSSProperties => {
171
+ const { gap, align, justify, p, px, py, m, mx, my } = toValue(input)
172
+ const result: CSSProperties = {}
173
+
174
+ applySpacing(result, 'gap', gap)
175
+ applySpacing(result, 'padding', p)
176
+ applySpacing(result, 'paddingInline', px)
177
+ applySpacing(result, 'paddingBlock', py)
178
+ applySpacing(result, 'margin', m)
179
+ applySpacing(result, 'marginInline', mx)
180
+ applySpacing(result, 'marginBlock', my)
181
+
182
+ const resolvedAlign = resolveDefault(align)
183
+ if (resolvedAlign) result.alignItems = ALIGN_MAP[resolvedAlign]
184
+
185
+ const resolvedJustify = resolveDefault(justify)
186
+ if (resolvedJustify) result.justifyContent = JUSTIFY_MAP[resolvedJustify]
187
+
188
+ return result
189
+ })
190
+
191
+ return { style }
192
+ }
193
+ ```
194
+
195
+ - [ ] **Step 5: Run tests to verify they pass**
196
+
197
+ Run: `cd layers/core && npx vitest run app/composables/useLayoutAttrs.test.ts`
198
+ Expected: PASS, all 6 new tests green.
199
+
200
+ - [ ] **Step 6: Run the full core test suite to check for regressions**
201
+
202
+ Run: `cd layers/core && npx vitest run`
203
+ Expected: PASS — no existing test touching `useLayoutAttrs` breaks.
204
+
205
+ - [ ] **Step 7: Commit**
206
+
207
+ ```bash
208
+ git add layers/core/app/composables/useLayoutAttrs.ts layers/core/app/composables/useLayoutAttrs.test.ts
209
+ git commit -m "feat(core): add margin support to useLayoutAttrs
210
+
211
+ Co-Authored-By: Claude Sonnet 5 <noreply@anthropic.com>
212
+ Claude-Session: https://claude.ai/code/session_017vMSCbNb6g9hyb9sBUsAQN"
213
+ ```
214
+
215
+ ---
216
+
217
+ ### Task 2: `useElementLayout` — display mode composable
218
+
219
+ **Files:**
220
+
221
+ - Create: `layers/structure/layout/app/composables/useElementLayout.ts`
222
+ - Test: `layers/structure/layout/app/composables/useElementLayout.test.ts`
223
+
224
+ **Interfaces:**
225
+
226
+ - Consumes: nothing (pure function, no imports beyond Vue's `CSSProperties` type).
227
+ - Produces: `ElementLayoutProps` type (`{ block?: boolean; flex?: boolean; grid?: boolean; hidden?: boolean }`) and `useElementLayout(props: ElementLayoutProps): Partial<CSSProperties>`. Both are imported by Task 6 (`Element.vue`).
228
+
229
+ - [ ] **Step 1: Write the failing tests**
230
+
231
+ Create `layers/structure/layout/app/composables/useElementLayout.test.ts`:
232
+
233
+ ```ts
234
+ import { describe, expect, it } from 'vitest'
235
+
236
+ import { useElementLayout } from './useElementLayout'
237
+
238
+ describe('useElementLayout', () => {
239
+ it('returns no display when no mode prop is set', () => {
240
+ expect(useElementLayout({})).toEqual({ display: undefined })
241
+ })
242
+
243
+ it('resolves block to display: block', () => {
244
+ expect(useElementLayout({ block: true })).toEqual({ display: 'block' })
245
+ })
246
+
247
+ it('resolves flex to display: flex', () => {
248
+ expect(useElementLayout({ flex: true })).toEqual({ display: 'flex' })
249
+ })
250
+
251
+ it('resolves grid to display: grid', () => {
252
+ expect(useElementLayout({ grid: true })).toEqual({ display: 'grid' })
253
+ })
254
+
255
+ it('resolves hidden to display: none', () => {
256
+ expect(useElementLayout({ hidden: true })).toEqual({ display: 'none' })
257
+ })
258
+
259
+ it('prioritizes hidden over grid, flex, and block when multiple are set', () => {
260
+ expect(useElementLayout({ hidden: true, grid: true, flex: true, block: true })).toEqual({
261
+ display: 'none',
262
+ })
263
+ })
264
+
265
+ it('prioritizes grid over flex and block', () => {
266
+ expect(useElementLayout({ grid: true, flex: true, block: true })).toEqual({
267
+ display: 'grid',
268
+ })
269
+ })
270
+
271
+ it('prioritizes flex over block', () => {
272
+ expect(useElementLayout({ flex: true, block: true })).toEqual({ display: 'flex' })
273
+ })
274
+ })
275
+ ```
276
+
277
+ - [ ] **Step 2: Run tests to verify they fail**
278
+
279
+ Run: `cd layers/structure/layout && npx vitest run app/composables/useElementLayout.test.ts`
280
+ Expected: FAIL — module `./useElementLayout` not found.
281
+
282
+ - [ ] **Step 3: Write the implementation**
283
+
284
+ Create `layers/structure/layout/app/composables/useElementLayout.ts`:
285
+
286
+ ```ts
287
+ import type { CSSProperties } from 'vue'
288
+
289
+ export interface ElementLayoutProps {
290
+ block?: boolean
291
+ flex?: boolean
292
+ grid?: boolean
293
+ hidden?: boolean
294
+ }
295
+
296
+ type Mode = 'hidden' | 'grid' | 'flex' | 'block'
297
+
298
+ const DISPLAY_FOR: Record<Mode, CSSProperties['display']> = {
299
+ hidden: 'none',
300
+ grid: 'grid',
301
+ flex: 'flex',
302
+ block: 'block',
303
+ }
304
+
305
+ export function useElementLayout(props: ElementLayoutProps): Partial<CSSProperties> {
306
+ const mode = (['hidden', 'grid', 'flex', 'block'] as const).find((m) => props[m])
307
+ return {
308
+ display: mode && DISPLAY_FOR[mode],
309
+ }
310
+ }
311
+ ```
312
+
313
+ - [ ] **Step 4: Run tests to verify they pass**
314
+
315
+ Run: `cd layers/structure/layout && npx vitest run app/composables/useElementLayout.test.ts`
316
+ Expected: PASS, all 8 tests green.
317
+
318
+ - [ ] **Step 5: Commit**
319
+
320
+ ```bash
321
+ git add layers/structure/layout/app/composables/useElementLayout.ts layers/structure/layout/app/composables/useElementLayout.test.ts
322
+ git commit -m "feat(layout): add useElementLayout display-mode composable
323
+
324
+ Co-Authored-By: Claude Sonnet 5 <noreply@anthropic.com>
325
+ Claude-Session: https://claude.ai/code/session_017vMSCbNb6g9hyb9sBUsAQN"
326
+ ```
327
+
328
+ ---
329
+
330
+ ### Task 3: `useElementSizing` — dimension composable
331
+
332
+ **Files:**
333
+
334
+ - Create: `layers/structure/layout/app/composables/useElementSizing.ts`
335
+ - Test: `layers/structure/layout/app/composables/useElementSizing.test.ts`
336
+
337
+ **Interfaces:**
338
+
339
+ - Consumes: nothing.
340
+ - Produces: `ElementSizingProps` type and `useElementSizing(props: ElementSizingProps): Partial<CSSProperties>`, imported by Task 6.
341
+
342
+ - [ ] **Step 1: Write the failing tests**
343
+
344
+ Create `layers/structure/layout/app/composables/useElementSizing.test.ts`:
345
+
346
+ ```ts
347
+ import { describe, expect, it } from 'vitest'
348
+
349
+ import { useElementSizing } from './useElementSizing'
350
+
351
+ describe('useElementSizing', () => {
352
+ it('returns all-undefined style when no props are set', () => {
353
+ expect(useElementSizing({})).toEqual({
354
+ width: undefined,
355
+ height: undefined,
356
+ minWidth: undefined,
357
+ maxWidth: undefined,
358
+ minHeight: undefined,
359
+ maxHeight: undefined,
360
+ aspectRatio: undefined,
361
+ })
362
+ })
363
+
364
+ it('maps every prop to its CSS property 1:1', () => {
365
+ expect(
366
+ useElementSizing({
367
+ w: '80px',
368
+ h: '40px',
369
+ minW: '10rem',
370
+ maxW: '20rem',
371
+ minH: '5rem',
372
+ maxH: '15rem',
373
+ aspect: '16 / 9',
374
+ })
375
+ ).toEqual({
376
+ width: '80px',
377
+ height: '40px',
378
+ minWidth: '10rem',
379
+ maxWidth: '20rem',
380
+ minHeight: '5rem',
381
+ maxHeight: '15rem',
382
+ aspectRatio: '16 / 9',
383
+ })
384
+ })
385
+ })
386
+ ```
387
+
388
+ - [ ] **Step 2: Run tests to verify they fail**
389
+
390
+ Run: `cd layers/structure/layout && npx vitest run app/composables/useElementSizing.test.ts`
391
+ Expected: FAIL — module not found.
392
+
393
+ - [ ] **Step 3: Write the implementation**
394
+
395
+ Create `layers/structure/layout/app/composables/useElementSizing.ts`:
396
+
397
+ ```ts
398
+ import type { CSSProperties } from 'vue'
399
+
400
+ export interface ElementSizingProps {
401
+ w?: CSSProperties['width']
402
+ h?: CSSProperties['height']
403
+ minW?: CSSProperties['minWidth']
404
+ maxW?: CSSProperties['maxWidth']
405
+ minH?: CSSProperties['minHeight']
406
+ maxH?: CSSProperties['maxHeight']
407
+ aspect?: CSSProperties['aspectRatio']
408
+ }
409
+
410
+ export function useElementSizing(props: ElementSizingProps): Partial<CSSProperties> {
411
+ return {
412
+ width: props.w,
413
+ height: props.h,
414
+ minWidth: props.minW,
415
+ maxWidth: props.maxW,
416
+ minHeight: props.minH,
417
+ maxHeight: props.maxH,
418
+ aspectRatio: props.aspect,
419
+ }
420
+ }
421
+ ```
422
+
423
+ - [ ] **Step 4: Run tests to verify they pass**
424
+
425
+ Run: `cd layers/structure/layout && npx vitest run app/composables/useElementSizing.test.ts`
426
+ Expected: PASS, both tests green.
427
+
428
+ - [ ] **Step 5: Commit**
429
+
430
+ ```bash
431
+ git add layers/structure/layout/app/composables/useElementSizing.ts layers/structure/layout/app/composables/useElementSizing.test.ts
432
+ git commit -m "feat(layout): add useElementSizing composable
433
+
434
+ Co-Authored-By: Claude Sonnet 5 <noreply@anthropic.com>
435
+ Claude-Session: https://claude.ai/code/session_017vMSCbNb6g9hyb9sBUsAQN"
436
+ ```
437
+
438
+ ---
439
+
440
+ ### Task 4: `useElementSurface` and `useElementInteraction` — surface & interaction composables
441
+
442
+ **Files:**
443
+
444
+ - Create: `layers/structure/layout/app/composables/useElementSurface.ts`
445
+ - Create: `layers/structure/layout/app/composables/useElementInteraction.ts`
446
+ - Test: `layers/structure/layout/app/composables/useElementSurface.test.ts`
447
+ - Test: `layers/structure/layout/app/composables/useElementInteraction.test.ts`
448
+
449
+ **Interfaces:**
450
+
451
+ - Consumes: nothing.
452
+ - Produces: `ElementSurfaceProps`/`useElementSurface()` and `ElementInteractionProps`/`useElementInteraction()`, both imported by Task 6.
453
+
454
+ - [ ] **Step 1: Write the failing surface test**
455
+
456
+ Create `layers/structure/layout/app/composables/useElementSurface.test.ts`:
457
+
458
+ ```ts
459
+ import { describe, expect, it } from 'vitest'
460
+
461
+ import { useElementSurface } from './useElementSurface'
462
+
463
+ describe('useElementSurface', () => {
464
+ it('returns all-undefined style when no props are set', () => {
465
+ expect(useElementSurface({})).toEqual({
466
+ background: undefined,
467
+ color: undefined,
468
+ border: undefined,
469
+ borderRadius: undefined,
470
+ boxShadow: undefined,
471
+ })
472
+ })
473
+
474
+ it('maps every prop to its CSS property 1:1', () => {
475
+ expect(
476
+ useElementSurface({
477
+ bg: 'var(--ui-bg-elevated)',
478
+ color: 'var(--ui-text)',
479
+ border: '1px solid var(--ui-border)',
480
+ radius: '0.5rem',
481
+ shadow: '0 4px 12px rgb(0 0 0 / 0.15)',
482
+ })
483
+ ).toEqual({
484
+ background: 'var(--ui-bg-elevated)',
485
+ color: 'var(--ui-text)',
486
+ border: '1px solid var(--ui-border)',
487
+ borderRadius: '0.5rem',
488
+ boxShadow: '0 4px 12px rgb(0 0 0 / 0.15)',
489
+ })
490
+ })
491
+ })
492
+ ```
493
+
494
+ - [ ] **Step 2: Write the failing interaction test**
495
+
496
+ Create `layers/structure/layout/app/composables/useElementInteraction.test.ts`:
497
+
498
+ ```ts
499
+ import { describe, expect, it } from 'vitest'
500
+
501
+ import { useElementInteraction } from './useElementInteraction'
502
+
503
+ describe('useElementInteraction', () => {
504
+ it('returns all-undefined style when no props are set', () => {
505
+ expect(useElementInteraction({})).toEqual({
506
+ cursor: undefined,
507
+ userSelect: undefined,
508
+ pointerEvents: undefined,
509
+ })
510
+ })
511
+
512
+ it('maps every prop to its CSS property 1:1', () => {
513
+ expect(
514
+ useElementInteraction({
515
+ cursor: 'pointer',
516
+ select: 'none',
517
+ pointer: 'none',
518
+ })
519
+ ).toEqual({
520
+ cursor: 'pointer',
521
+ userSelect: 'none',
522
+ pointerEvents: 'none',
523
+ })
524
+ })
525
+ })
526
+ ```
527
+
528
+ - [ ] **Step 3: Run both tests to verify they fail**
529
+
530
+ Run: `cd layers/structure/layout && npx vitest run app/composables/useElementSurface.test.ts app/composables/useElementInteraction.test.ts`
531
+ Expected: FAIL — modules not found.
532
+
533
+ - [ ] **Step 4: Write the surface implementation**
534
+
535
+ Create `layers/structure/layout/app/composables/useElementSurface.ts`:
536
+
537
+ ```ts
538
+ import type { CSSProperties } from 'vue'
539
+
540
+ export interface ElementSurfaceProps {
541
+ bg?: CSSProperties['background']
542
+ color?: CSSProperties['color']
543
+ border?: CSSProperties['border']
544
+ radius?: CSSProperties['borderRadius']
545
+ shadow?: CSSProperties['boxShadow']
546
+ }
547
+
548
+ export function useElementSurface(props: ElementSurfaceProps): Partial<CSSProperties> {
549
+ return {
550
+ background: props.bg,
551
+ color: props.color,
552
+ border: props.border,
553
+ borderRadius: props.radius,
554
+ boxShadow: props.shadow,
555
+ }
556
+ }
557
+ ```
558
+
559
+ - [ ] **Step 5: Write the interaction implementation**
560
+
561
+ Create `layers/structure/layout/app/composables/useElementInteraction.ts`:
562
+
563
+ ```ts
564
+ import type { CSSProperties } from 'vue'
565
+
566
+ export interface ElementInteractionProps {
567
+ cursor?: CSSProperties['cursor']
568
+ select?: CSSProperties['userSelect']
569
+ pointer?: CSSProperties['pointerEvents']
570
+ }
571
+
572
+ export function useElementInteraction(props: ElementInteractionProps): Partial<CSSProperties> {
573
+ return {
574
+ cursor: props.cursor,
575
+ userSelect: props.select,
576
+ pointerEvents: props.pointer,
577
+ }
578
+ }
579
+ ```
580
+
581
+ - [ ] **Step 6: Run both tests to verify they pass**
582
+
583
+ Run: `cd layers/structure/layout && npx vitest run app/composables/useElementSurface.test.ts app/composables/useElementInteraction.test.ts`
584
+ Expected: PASS, all 4 tests green.
585
+
586
+ - [ ] **Step 7: Commit**
587
+
588
+ ```bash
589
+ git add layers/structure/layout/app/composables/useElementSurface.ts layers/structure/layout/app/composables/useElementSurface.test.ts layers/structure/layout/app/composables/useElementInteraction.ts layers/structure/layout/app/composables/useElementInteraction.test.ts
590
+ git commit -m "feat(layout): add useElementSurface and useElementInteraction composables
591
+
592
+ Co-Authored-By: Claude Sonnet 5 <noreply@anthropic.com>
593
+ Claude-Session: https://claude.ai/code/session_017vMSCbNb6g9hyb9sBUsAQN"
594
+ ```
595
+
596
+ ---
597
+
598
+ ### Task 5: `useElementGrid` — container-axis template + item-axis delegate
599
+
600
+ **Files:**
601
+
602
+ - Create: `layers/structure/layout/app/composables/useElementGrid.ts`
603
+ - Test: `layers/structure/layout/app/composables/useElementGrid.test.ts`
604
+
605
+ **Interfaces:**
606
+
607
+ - Consumes: `buildGridPlacementStyle`, `GridPlacementInput` from `../utils/gridPlacementStyle` (existing, unmodified — see `layers/structure/layout/app/utils/gridPlacementStyle.ts:132`).
608
+ - Produces: `ElementGridProps` type and `useElementGrid(props: ElementGridProps): Partial<CSSProperties>`, imported by Task 6. `ElementGridProps` shape: `{ grid?: boolean; cols?: number | string; rows?: number | string; colStart?: number | ResponsiveValue<number>; colSpan?: number | 'full' | ResponsiveValue<number>; rowStart?: number | ResponsiveValue<number>; rowSpan?: number | ResponsiveValue<number> }`.
609
+
610
+ - [ ] **Step 1: Write the failing tests**
611
+
612
+ Create `layers/structure/layout/app/composables/useElementGrid.test.ts`:
613
+
614
+ ```ts
615
+ import { describe, expect, it } from 'vitest'
616
+
617
+ import { useElementGrid } from './useElementGrid'
618
+
619
+ describe('useElementGrid container axis', () => {
620
+ it('returns no grid-template properties when grid is not set', () => {
621
+ const result = useElementGrid({ cols: 12 })
622
+ expect(result.gridTemplateColumns).toBeUndefined()
623
+ expect(result.gridTemplateRows).toBeUndefined()
624
+ })
625
+
626
+ it('converts a numeric cols to a repeat() track when grid is set', () => {
627
+ const result = useElementGrid({ grid: true, cols: 12 })
628
+ expect(result.gridTemplateColumns).toBe('repeat(12, 1fr)')
629
+ })
630
+
631
+ it('converts a numeric rows to a repeat() track when grid is set', () => {
632
+ const result = useElementGrid({ grid: true, rows: 4 })
633
+ expect(result.gridTemplateRows).toBe('repeat(4, 1fr)')
634
+ })
635
+
636
+ it('passes a string cols track through unchanged', () => {
637
+ const result = useElementGrid({ grid: true, cols: '1fr 2fr 1fr' })
638
+ expect(result.gridTemplateColumns).toBe('1fr 2fr 1fr')
639
+ })
640
+
641
+ it('sets display: grid when grid is true', () => {
642
+ const result = useElementGrid({ grid: true, cols: 12 })
643
+ expect(result.display).toBe('grid')
644
+ })
645
+ })
646
+
647
+ describe('useElementGrid item axis (delegates to buildGridPlacementStyle)', () => {
648
+ it('sets gridColumn span from colSpan alone', () => {
649
+ const result = useElementGrid({ colSpan: 8 })
650
+ expect(result.gridColumn).toBe('1 / -1')
651
+ })
652
+
653
+ it('sets --_ce custom property when colSpan is not full', () => {
654
+ const result = useElementGrid({ colStart: 3, colSpan: 6 })
655
+ expect(result['--_cs']).toBe('3')
656
+ expect(result['--_ce']).toBe('6')
657
+ })
658
+
659
+ it('produces identical output to buildGridPlacementStyle for the same input', async () => {
660
+ const { buildGridPlacementStyle } = await import('../utils/gridPlacementStyle')
661
+ const direct = buildGridPlacementStyle({ colStart: 2, colSpan: 4, rowSpan: 2 })
662
+ const viaElement = useElementGrid({ colStart: 2, colSpan: 4, rowSpan: 2 })
663
+ expect(viaElement).toMatchObject(direct)
664
+ })
665
+ })
666
+ ```
667
+
668
+ - [ ] **Step 2: Run tests to verify they fail**
669
+
670
+ Run: `cd layers/structure/layout && npx vitest run app/composables/useElementGrid.test.ts`
671
+ Expected: FAIL — module not found.
672
+
673
+ - [ ] **Step 3: Write the implementation**
674
+
675
+ Create `layers/structure/layout/app/composables/useElementGrid.ts`:
676
+
677
+ ```ts
678
+ import type { CSSProperties } from 'vue'
679
+
680
+ import type { ResponsiveValue } from '../types/layouts'
681
+ import { buildGridPlacementStyle } from '../utils/gridPlacementStyle'
682
+
683
+ export interface ElementGridProps {
684
+ grid?: boolean
685
+ cols?: number | string
686
+ rows?: number | string
687
+ colStart?: number | ResponsiveValue<number>
688
+ colSpan?: number | 'full' | ResponsiveValue<number>
689
+ rowStart?: number | ResponsiveValue<number>
690
+ rowSpan?: number | ResponsiveValue<number>
691
+ }
692
+
693
+ function track(value: number | string | undefined): string | undefined {
694
+ return typeof value === 'number' ? `repeat(${value}, 1fr)` : value
695
+ }
696
+
697
+ export function useElementGrid(props: ElementGridProps): Partial<CSSProperties> {
698
+ const placement = buildGridPlacementStyle({
699
+ colStart: props.colStart,
700
+ colSpan: props.colSpan,
701
+ rowStart: props.rowStart,
702
+ rowSpan: props.rowSpan,
703
+ })
704
+
705
+ return {
706
+ ...placement,
707
+ ...(props.grid && {
708
+ display: 'grid',
709
+ gridTemplateColumns: track(props.cols),
710
+ gridTemplateRows: track(props.rows),
711
+ }),
712
+ }
713
+ }
714
+ ```
715
+
716
+ - [ ] **Step 4: Confirm the `ResponsiveValue` import path**
717
+
718
+ Run: `grep -n "export type ResponsiveValue" layers/structure/layout/app/types/layouts.ts`
719
+ Expected: one match — confirms `../types/layouts` is the correct import path for the layer's own `ResponsiveValue` (distinct from `core`'s — see spec §13). If the grep finds no match, locate the actual export and adjust the import in Step 3 before proceeding.
720
+
721
+ - [ ] **Step 5: Run tests to verify they pass**
722
+
723
+ Run: `cd layers/structure/layout && npx vitest run app/composables/useElementGrid.test.ts`
724
+ Expected: PASS, all 8 tests green.
725
+
726
+ - [ ] **Step 6: Run the full layout test suite to check for regressions**
727
+
728
+ Run: `cd layers/structure/layout && npx vitest run`
729
+ Expected: PASS — `gridPlacementStyle.test.ts` and all others still green; confirms `buildGridPlacementStyle` itself was not touched.
730
+
731
+ - [ ] **Step 7: Commit**
732
+
733
+ ```bash
734
+ git add layers/structure/layout/app/composables/useElementGrid.ts layers/structure/layout/app/composables/useElementGrid.test.ts
735
+ git commit -m "feat(layout): add useElementGrid composable, reusing buildGridPlacementStyle
736
+
737
+ Co-Authored-By: Claude Sonnet 5 <noreply@anthropic.com>
738
+ Claude-Session: https://claude.ai/code/session_017vMSCbNb6g9hyb9sBUsAQN"
739
+ ```
740
+
741
+ ---
742
+
743
+ ### Task 6: `Element.vue` + `ElementProps` type + playground verification page
744
+
745
+ **Files:**
746
+
747
+ - Create: `layers/structure/layout/app/types/element.ts`
748
+ - Create: `layers/structure/layout/app/components/Element.vue`
749
+ - Test: `layers/structure/layout/app/components/Element.test.ts`
750
+ - Create: `apps/playground/app/pages/element.vue`
751
+
752
+ **Interfaces:**
753
+
754
+ - Consumes: `ElementLayoutProps`/`useElementLayout` (Task 2), `ElementGridProps`/`useElementGrid` (Task 5), `ElementSizingProps`/`useElementSizing` (Task 3), `ElementSurfaceProps`/`useElementSurface` (Task 4), `ElementInteractionProps`/`useElementInteraction` (Task 4), `LayoutAttrsInput`/`useLayoutAttrs` (core, Task 1).
755
+ - Produces: `ElementProps` type (exported union) and the `<Element>` component itself — the final deliverable, consumed by application pages.
756
+
757
+ - [ ] **Step 1: Write the failing component test**
758
+
759
+ Create `layers/structure/layout/app/components/Element.test.ts`:
760
+
761
+ ```ts
762
+ import { mount } from '@vue/test-utils'
763
+ import { describe, expect, it } from 'vitest'
764
+
765
+ import Element from './Element.vue'
766
+
767
+ describe('Element', () => {
768
+ it('renders as a div by default', () => {
769
+ const wrapper = mount(Element)
770
+ expect(wrapper.element.tagName).toBe('DIV')
771
+ })
772
+
773
+ it('renders as the tag passed via the as prop', () => {
774
+ const wrapper = mount(Element, { props: { as: 'section' } })
775
+ expect(wrapper.element.tagName).toBe('SECTION')
776
+ })
777
+
778
+ it('renders slot content', () => {
779
+ const wrapper = mount(Element, { slots: { default: 'hello' } })
780
+ expect(wrapper.text()).toBe('hello')
781
+ })
782
+
783
+ it('merges layout, sizing, and surface styles into one style attribute', () => {
784
+ const wrapper = mount(Element, {
785
+ props: {
786
+ flex: true,
787
+ w: '80px',
788
+ bg: 'var(--ui-bg-elevated)',
789
+ },
790
+ })
791
+ const style = wrapper.attributes('style') ?? ''
792
+ expect(style).toContain('display: flex')
793
+ expect(style).toContain('width: 80px')
794
+ expect(style).toContain('background: var(--ui-bg-elevated)')
795
+ })
796
+
797
+ it('merges spacing (via useLayoutAttrs) and grid item-placement styles together', () => {
798
+ const wrapper = mount(Element, {
799
+ props: {
800
+ p: 'md',
801
+ colSpan: 6,
802
+ },
803
+ })
804
+ const style = wrapper.attributes('style') ?? ''
805
+ expect(style).toContain('padding: var(--fluid-space-md)')
806
+ expect(style).toContain('--_ce: 6')
807
+ })
808
+ })
809
+ ```
810
+
811
+ - [ ] **Step 2: Run test to verify it fails**
812
+
813
+ Run: `cd layers/structure/layout && npx vitest run app/components/Element.test.ts`
814
+ Expected: FAIL — `Element.vue` not found.
815
+
816
+ - [ ] **Step 3: Write the ElementProps type**
817
+
818
+ Create `layers/structure/layout/app/types/element.ts`:
819
+
820
+ ```ts
821
+ import type { Component } from 'vue'
822
+ import type { LayoutAttrsInput } from '#layers/core/app/composables/useLayoutAttrs'
823
+
824
+ import type { ElementGridProps } from '../composables/useElementGrid'
825
+ import type { ElementInteractionProps } from '../composables/useElementInteraction'
826
+ import type { ElementLayoutProps } from '../composables/useElementLayout'
827
+ import type { ElementSizingProps } from '../composables/useElementSizing'
828
+ import type { ElementSurfaceProps } from '../composables/useElementSurface'
829
+
830
+ export type ElementProps = ElementLayoutProps &
831
+ ElementGridProps &
832
+ LayoutAttrsInput &
833
+ ElementSizingProps &
834
+ ElementSurfaceProps &
835
+ ElementInteractionProps & {
836
+ as?: string | Component
837
+ }
838
+ ```
839
+
840
+ - [ ] **Step 4: Write Element.vue**
841
+
842
+ Create `layers/structure/layout/app/components/Element.vue`:
843
+
844
+ ```vue
845
+ <script setup lang="ts">
846
+ import type { CSSProperties } from 'vue'
847
+
848
+ import type { ElementProps } from '../types/element'
849
+
850
+ const props = withDefaults(defineProps<ElementProps>(), {
851
+ as: 'div',
852
+ })
853
+
854
+ const style = computed<CSSProperties>(() => ({
855
+ ...useElementLayout(props),
856
+ ...useLayoutAttrs(() => props).style.value,
857
+ ...useElementGrid(props),
858
+ ...useElementSizing(props),
859
+ ...useElementSurface(props),
860
+ ...useElementInteraction(props),
861
+ }))
862
+ </script>
863
+
864
+ <template>
865
+ <component :is="as" :style>
866
+ <slot />
867
+ </component>
868
+ </template>
869
+ ```
870
+
871
+ `useElementLayout`, `useLayoutAttrs`, `useElementGrid`, `useElementSizing`, `useElementSurface`, `useElementInteraction` are all Nuxt auto-imports (composables in `app/composables/` are auto-imported within the layer, and `useLayoutAttrs` is auto-imported from `core` since `layout` extends `core` — see `layers/structure/layout/nuxt.config.ts:7`). No explicit imports needed in the `<script setup>` block for them.
872
+
873
+ - [ ] **Step 5: Run test to verify it passes**
874
+
875
+ Run: `cd layers/structure/layout && npx vitest run app/components/Element.test.ts`
876
+ Expected: PASS, all 5 tests green.
877
+
878
+ If auto-imports aren't resolved in the Vitest environment (composables not globally available outside a running Nuxt instance), explicitly import them at the top of `Element.vue`'s `<script setup>` instead:
879
+
880
+ ```ts
881
+ import { useLayoutAttrs } from '#layers/core/app/composables/useLayoutAttrs'
882
+
883
+ import { useElementGrid } from '../composables/useElementGrid'
884
+ import { useElementInteraction } from '../composables/useElementInteraction'
885
+ import { useElementLayout } from '../composables/useElementLayout'
886
+ import { useElementSizing } from '../composables/useElementSizing'
887
+ import { useElementSurface } from '../composables/useElementSurface'
888
+ ```
889
+
890
+ Re-run the test after adding imports if the auto-import approach fails.
891
+
892
+ - [ ] **Step 6: Create the playground verification page**
893
+
894
+ Create `apps/playground/app/pages/element.vue`:
895
+
896
+ ```vue
897
+ <template>
898
+ <Element block p="xl">
899
+ <h2>Grid container + item placement</h2>
900
+ <Element grid :cols="12" gap="lg" p="lg" bg="var(--ui-bg-elevated)" radius="0.5rem">
901
+ <Element :col-span="12" bg="var(--color-green-400)" color="white" p="md" radius="0.25rem">
902
+ colSpan 12
903
+ </Element>
904
+ <Element :col-span="8" bg="var(--color-green-500)" color="white" p="md" radius="0.25rem">
905
+ colSpan 8
906
+ </Element>
907
+ <Element :col-span="4" bg="var(--color-green-600)" color="white" p="md" radius="0.25rem">
908
+ colSpan 4
909
+ </Element>
910
+ <Element
911
+ :col-start="3"
912
+ :col-span="6"
913
+ bg="var(--color-green-700)"
914
+ color="white"
915
+ p="md"
916
+ radius="0.25rem"
917
+ >
918
+ colStart 3 / colSpan 6
919
+ </Element>
920
+ </Element>
921
+ </Element>
922
+
923
+ <Element block p="xl">
924
+ <h2>Flex + sizing + interaction</h2>
925
+ <Element flex gap="md" p="lg" bg="var(--ui-bg-elevated)" radius="0.5rem">
926
+ <Element
927
+ w="80px"
928
+ h="80px"
929
+ bg="var(--color-green-400)"
930
+ radius="9999px"
931
+ cursor="pointer"
932
+ select="none"
933
+ />
934
+ <Element
935
+ w="160px"
936
+ h="80px"
937
+ bg="var(--color-green-500)"
938
+ color="white"
939
+ p="sm"
940
+ radius="0.5rem"
941
+ shadow="0 4px 12px rgb(0 0 0 / 0.15)"
942
+ >
943
+ card
944
+ </Element>
945
+ <Element
946
+ min-w="120px"
947
+ max-w="240px"
948
+ h="80px"
949
+ bg="var(--color-green-600)"
950
+ color="white"
951
+ p="sm"
952
+ radius="0.5rem"
953
+ >
954
+ min/max width
955
+ </Element>
956
+ </Element>
957
+ </Element>
958
+
959
+ <Element block p="xl">
960
+ <h2>Layout modes</h2>
961
+ <Element flex gap="sm">
962
+ <Element block bg="var(--color-green-400)" p="sm" radius="0.25rem" color="white"
963
+ >block</Element
964
+ >
965
+ <Element flex bg="var(--color-green-500)" p="sm" radius="0.25rem" color="white">flex</Element>
966
+ <Element hidden bg="var(--color-green-600)" p="sm" radius="0.25rem" color="white">
967
+ hidden (not rendered visibly)
968
+ </Element>
969
+ </Element>
970
+ </Element>
971
+
972
+ <Element block p="xl">
973
+ <h2>Margin (Task 1 verification)</h2>
974
+ <Element bg="var(--ui-bg-elevated)" p="md">
975
+ <Element bg="var(--color-green-500)" color="white" p="sm" m="lg" radius="0.25rem">
976
+ m="lg" pushes this box away from its siblings
977
+ </Element>
978
+ </Element>
979
+ </Element>
980
+ </template>
981
+ ```
982
+
983
+ - [ ] **Step 7: Manually verify in the browser**
984
+
985
+ Run: `PLAYGROUND_LAYERS=core,layout pnpm dev` from the repo root, then navigate to `/element`.
986
+
987
+ Verify: the 12-column grid row renders with correctly spanned/positioned green blocks, the flex row shows a circle/card/min-max box, the layout-modes row hides the third box, and the margin box visibly indents from its container. Confirm no console errors.
988
+
989
+ - [ ] **Step 8: Run full test suite one more time**
990
+
991
+ Run: `pnpm --filter layers/core --filter layers/structure/layout test` (or `cd` into each and run `npx vitest run` if the filter form doesn't match this repo's script names — check `package.json`'s `scripts.test` first with `cat layers/core/package.json layers/structure/layout/package.json | grep -A2 '"scripts"'`)
992
+ Expected: PASS across both layers, zero regressions.
993
+
994
+ - [ ] **Step 9: Run typecheck**
995
+
996
+ Run: `pnpm typecheck`
997
+ Expected: PASS — no new type errors from `ElementProps`, `Element.vue`, or the modified `LayoutAttrsInput`.
998
+
999
+ - [ ] **Step 10: Commit**
1000
+
1001
+ ```bash
1002
+ git add layers/structure/layout/app/types/element.ts layers/structure/layout/app/components/Element.vue layers/structure/layout/app/components/Element.test.ts apps/playground/app/pages/element.vue
1003
+ git commit -m "feat(layout): add Element polymorphic primitive
1004
+
1005
+ Co-Authored-By: Claude Sonnet 5 <noreply@anthropic.com>
1006
+ Claude-Session: https://claude.ai/code/session_017vMSCbNb6g9hyb9sBUsAQN"
1007
+ ```
1008
+
1009
+ ---
1010
+
1011
+ ## Self-Review
1012
+
1013
+ **Spec coverage:**
1014
+
1015
+ - §3.1 Layout group → Task 2. §3.2 Spacing (incl. margin) → Task 1. §3.3 Grid (both axes) → Task 5. §3.4 Sizing → Task 3. §3.5 Surface → Task 4. §3.6 Interaction → Task 4. §4 `Element.vue` → Task 6. §5 `ElementProps` type → Task 6. §6 out-of-scope items — no task touches them (confirmed: no typography props, no semantic colour, no align/justify/bleed/density/layer exposed on Element, no LayoutGridItem/gridPlacementStyle edits, no new Grid/Section container component). §7 file layout → matches the File Structure section above exactly, plus a playground page for manual verification not explicitly required by the spec but implied by its own worked examples (§4, §5). §8 testing → per-composable unit tests (Task 1–5) plus an `Element.vue` mount test (Task 6) covering `as` passthrough, slot rendering, and style merge order, matching the spec's stated testing requirements. §9 success criteria — criterion 3 ("zero changes to LayoutGridItem/gridPlacementStyle.ts") is enforced by Task 5 Step 6 (full layout suite re-run) and the Global Constraints section; criterion 4 (HStack/VStack unaffected) is enforced by Task 1 Step 6.
1016
+
1017
+ **Placeholder scan:** No TBD/TODO/"add appropriate handling" patterns present. Every step has literal code or an exact command.
1018
+
1019
+ **Type consistency:** `ElementGridProps`, `ElementSizingProps`, `ElementSurfaceProps`, `ElementInteractionProps`, `ElementLayoutProps`, `LayoutAttrsInput` are named identically everywhere they're referenced across Tasks 2–6. `useElementGrid`/`useElementSizing`/`useElementSurface`/`useElementInteraction`/`useElementLayout` function names match between their defining task and their `Element.vue` usage (Task 6). `ElementProps`'s field list in Task 6 Step 3 is the exact union of every composable's Props type defined in Tasks 1–5, nothing added or missing.