kmcom-nuxt-layers 2.7.4 → 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.
- package/docs/FALLOW-COMPLEXITY-DUPLICATION-AUDIT.md +0 -1
- package/docs/LAYOUT.md +34 -61
- package/docs/MIGRATION.md +1 -1
- package/docs/UPAGE-GRID-INTEGRATION.md +6 -6
- package/docs/layout-shift-causes.md +1 -1
- package/docs/superpowers/plans/2026-09-03-layout-layer-fluid-rebuild.md +1850 -0
- package/docs/superpowers/plans/2026-09-03-vue-element-system.md +1019 -0
- package/docs/superpowers/plans/2026-09-04-grid-layer.md +977 -0
- package/docs/superpowers/specs/2026-08-30-layer-taxonomy-tier-0-1-design.md +533 -0
- package/docs/superpowers/specs/2026-08-30-layer-taxonomy-tier-2-design.md +154 -0
- package/docs/superpowers/specs/2026-08-30-layer-taxonomy-tier-3-design.md +109 -0
- package/docs/superpowers/specs/2026-08-30-layer-taxonomy-tier-4-design.md +124 -0
- package/docs/superpowers/specs/2026-08-30-layer-taxonomy-tier-5-design.md +121 -0
- package/docs/superpowers/specs/2026-08-30-layer-taxonomy-tier-6-design.md +77 -0
- package/docs/superpowers/specs/2026-08-30-layer-taxonomy-tier-7-design.md +73 -0
- package/docs/superpowers/specs/2026-08-31-swiss-grid-layer-design.md +190 -0
- package/docs/superpowers/specs/2026-09-03-layout-layer-fluid-rebuild-design.md +312 -0
- package/docs/superpowers/specs/2026-09-03-vue-element-system-design.md +342 -0
- package/docs/superpowers/specs/2026-09-04-grid-layer-design.md +236 -0
- package/layers/content/app/app.config.ts +10 -2
- package/layers/content/app/components/Blog/ItemPage.vue +21 -0
- package/layers/content/app/components/Blog/Page.vue +25 -0
- package/layers/content/app/components/Gallery/ImagePage.vue +5 -1
- package/layers/content/app/components/Gallery/Page.vue +4 -1
- package/layers/content/app/components/Gallery/SlugPage.vue +5 -1
- package/layers/content/app/components/Portfolio/ItemPage.vue +4 -1
- package/layers/content/app/components/Portfolio/List.vue +14 -2
- package/layers/content/app/components/Portfolio/Page.vue +4 -1
- package/layers/content/app/composables/useBlogPosts.ts +6 -19
- package/layers/content/app/composables/useCollectionItems.ts +63 -0
- package/layers/content/app/composables/useGalleryItems.ts +1 -16
- package/layers/content/app/types/content.ts +9 -0
- package/layers/content/package.json +3 -0
- package/layers/core/app/app.config.ts +34 -17
- package/layers/core/app/app.vue +1 -0
- package/layers/core/app/assets/css/core.css +10 -0
- package/layers/core/app/assets/css/tokens/breakpoints.css +13 -0
- package/layers/core/app/assets/css/tokens/container.css +36 -0
- package/layers/core/app/assets/css/tokens/spacing-fluid.css +25 -0
- package/layers/core/app/components/AppContainer.vue +32 -0
- package/layers/core/app/components/Element.test.ts +90 -0
- package/layers/core/app/components/Element.vue +78 -0
- package/layers/core/app/components/ElementTw.test.ts +64 -0
- package/layers/core/app/components/ElementTw.vue +86 -0
- package/layers/core/app/components/LoadingScreen.vue +0 -15
- package/layers/core/app/composables/useElementGrid.test.ts +33 -0
- package/layers/core/app/composables/useElementGrid.ts +29 -0
- package/layers/core/app/composables/useElementInteraction.test.ts +27 -0
- package/layers/core/app/composables/useElementInteraction.ts +17 -0
- package/layers/core/app/composables/useElementLayout.test.ts +41 -0
- package/layers/core/app/composables/useElementLayout.ts +26 -0
- package/layers/core/app/composables/useElementSizing.test.ts +39 -0
- package/layers/core/app/composables/useElementSizing.ts +25 -0
- package/layers/core/app/composables/useElementStyle.ts +65 -0
- package/layers/core/app/composables/useElementSurface.test.ts +33 -0
- package/layers/core/app/composables/useElementSurface.ts +21 -0
- package/layers/core/app/composables/useErrorLog.ts +6 -4
- package/layers/core/app/composables/useLayoutAttrs.test.ts +47 -0
- package/layers/core/app/composables/useLayoutAttrs.ts +94 -0
- package/layers/core/app/composables/useLoading.ts +3 -1
- package/layers/core/app/error.vue +27 -57
- package/layers/core/app/pages/[...slug].vue +1 -29
- package/layers/core/app/plugins/icon-fetch-fix.ts +12 -0
- package/layers/core/app/plugins/loading.client.ts +0 -6
- package/layers/core/app/types/element.ts +25 -0
- package/layers/core/app/types/index.ts +0 -1
- package/layers/core/app/types/notFound.ts +24 -0
- package/layers/core/app/types/responsive.ts +15 -0
- package/layers/core/app/types/responsive.type-test.ts +22 -0
- package/layers/core/app/types/runtime-config.ts +1 -17
- package/layers/core/app/types/tokens.ts +29 -0
- package/layers/core/app/utils/index.ts +4 -2
- package/layers/core/app/utils/scrollGuardClamp.test.ts +36 -0
- package/layers/core/app/utils/scrollGuardClamp.ts +22 -0
- package/layers/core/app/utils/styleToTailwindClasses.test.ts +31 -0
- package/layers/core/app/utils/styleToTailwindClasses.ts +16 -0
- package/layers/core/nuxt.config.ts +15 -11
- package/layers/core/package.json +5 -1
- package/layers/{auth → data/auth}/nuxt.config.ts +1 -1
- package/layers/{auth → data/auth}/package.json +1 -1
- package/layers/{baseline → data/auth}/tsconfig.json +1 -1
- package/layers/{database → data/database}/nuxt.config.ts +1 -1
- package/layers/{database → data/database}/package.json +1 -1
- package/layers/{database → data/database}/tsconfig.json +1 -1
- package/layers/{forms/app/types/app-config.d.ts → data/forms/app/app.config.ts} +4 -0
- package/layers/{forms → data/forms}/package.json +1 -1
- package/layers/{forms → data/forms}/server/api/forms/status.get.ts +3 -1
- package/layers/{animations → data/forms}/tsconfig.json +1 -1
- package/layers/{mailer → data/mailer}/nuxt.config.ts +11 -1
- package/layers/{mailer → data/mailer}/package.json +1 -1
- package/layers/{auth → data/mailer}/tsconfig.json +1 -1
- package/layers/data/metadata/app/composables/useMetadataItem.ts +18 -0
- package/layers/data/metadata/app/composables/useMetadataSearch.ts +37 -0
- package/layers/{metadata → data/metadata}/nuxt.config.ts +1 -1
- package/layers/{metadata → data/metadata}/package.json +1 -1
- package/layers/{metadata → data/metadata}/providers/comicvine/nuxt.config.ts +1 -1
- package/layers/{metadata → data/metadata}/providers/comicvine/package.json +1 -1
- package/layers/data/metadata/providers/comicvine/tsconfig.json +7 -0
- package/layers/{metadata → data/metadata}/providers/google-books/nuxt.config.ts +1 -1
- package/layers/{metadata → data/metadata}/providers/google-books/package.json +1 -1
- package/layers/{metadata → data/metadata}/providers/google-books/server/utils/metadata-google-books/client.ts +10 -2
- package/layers/data/metadata/providers/google-books/tsconfig.json +7 -0
- package/layers/{metadata → data/metadata}/providers/openlibrary/package.json +1 -1
- package/layers/{metadata → data/metadata}/providers/openlibrary/server/utils/metadata-openlibrary/client.ts +23 -11
- package/layers/data/metadata/providers/openlibrary/tsconfig.json +7 -0
- package/layers/{metadata → data/metadata}/providers/themoviedb/nuxt.config.ts +1 -1
- package/layers/{metadata → data/metadata}/providers/themoviedb/package.json +1 -1
- package/layers/{metadata → data/metadata}/providers/themoviedb/tsconfig.json +1 -1
- package/layers/{metadata → data/metadata}/server/utils/metadata/search.ts +11 -4
- package/layers/data/metadata/tsconfig.json +7 -0
- package/layers/{feeds → delivery/feeds}/app/components/Feeds/Index.vue +6 -2
- package/layers/{feeds → delivery/feeds}/app/components/Feeds/RouteCard.vue +2 -0
- package/layers/{feeds → delivery/feeds}/app/plugins/feed-head.ts +6 -2
- package/layers/{feeds → delivery/feeds}/app/utils/feed-catalog.ts +8 -6
- package/layers/{feeds → delivery/feeds}/nuxt.config.ts +1 -1
- package/layers/{feeds → delivery/feeds}/package.json +1 -1
- package/layers/{feeds → delivery/feeds}/server/utils/feed-config.ts +1 -1
- package/layers/{feeds → delivery/feeds}/server/utils/feed-service.ts +2 -1
- package/layers/delivery/feeds/tsconfig.json +7 -0
- package/layers/{scripts → delivery/scripts}/app/composables/useAnalytics.ts +3 -1
- package/layers/{scripts → delivery/scripts}/app/composables/useGtm.ts +8 -2
- package/layers/{scripts → delivery/scripts}/app/composables/useScriptsConsent.ts +4 -1
- package/layers/{scripts → delivery/scripts}/app/utils/scriptClients.ts +19 -0
- package/layers/{scripts → delivery/scripts}/nuxt.config.ts +7 -2
- package/layers/{scripts → delivery/scripts}/package.json +3 -2
- package/layers/delivery/scripts/tsconfig.json +7 -0
- package/layers/delivery/seo/app/composables/useSeoConfig.ts +8 -0
- package/layers/{seo → delivery/seo}/app/utils/seoConfig.test.ts +2 -2
- package/layers/{seo → delivery/seo}/app/utils/seoConfig.ts +2 -2
- package/layers/{seo → delivery/seo}/nuxt.config.ts +1 -1
- package/layers/{seo → delivery/seo}/package.json +1 -1
- package/layers/delivery/seo/tsconfig.json +7 -0
- package/layers/design-system/theming/app/app.config.ts +35 -0
- package/layers/design-system/theming/app/assets/css/tokens.css +26 -0
- package/layers/{theme → design-system/theming}/app/components/ThemePicker/AccentButton.vue +3 -22
- package/layers/{theme → design-system/theming}/app/components/ThemePicker/Colors.vue +3 -4
- package/layers/{theme → design-system/theming}/app/composables/useAccentColor.ts +5 -2
- package/layers/{theme → design-system/theming}/app/composables/useThemeContrast.ts +1 -1
- package/layers/{theme → design-system/theming}/app/composables/useThemeMotion.ts +1 -1
- package/layers/{theme → design-system/theming}/app/composables/useThemeTransparency.ts +1 -1
- package/layers/{theme → design-system/theming}/app/plugins/theme.client.ts +2 -1
- package/layers/design-system/theming/app/types/designSystem.ts +102 -0
- package/layers/design-system/theming/app/types/semanticColor.ts +20 -0
- package/layers/design-system/theming/app/types/theme.ts +12 -0
- package/layers/design-system/theming/app/utils/accentPalette.ts +28 -0
- package/layers/design-system/theming/app/utils/themeAdapter.ts +20 -0
- package/layers/design-system/theming/nuxt.config.ts +49 -0
- package/layers/{ui → design-system/theming}/package.json +5 -6
- package/layers/{theme → design-system/theming}/server/plugins/theme-fouc.ts +2 -0
- package/layers/{theme → design-system/theming}/server/utils/accent-css.ts +2 -2
- package/layers/{theme → design-system/theming}/tsconfig.json +1 -1
- package/layers/{typography → design-system/typography}/app/assets/css/typography.css +13 -10
- package/layers/design-system/typography/app/components/Typography/CodeBlock.vue +65 -0
- package/layers/{typography → design-system/typography}/app/components/Typography/Headline.vue +16 -31
- package/layers/{typography/app/components/Typography/HeadlineScreen.vue → design-system/typography/app/components/Typography/QuoteBlock.vue} +27 -29
- package/layers/design-system/typography/app/components/Typography/RepeatText.vue +147 -0
- package/layers/{typography → design-system/typography}/app/components/Typography/index.vue +6 -4
- package/layers/design-system/typography/app/composables/repeatFill.ts +51 -0
- package/layers/{typography → design-system/typography}/app/composables/typography.ts +4 -0
- package/layers/{typography → design-system/typography}/app/types/typography.ts +8 -0
- package/layers/{typography → design-system/typography}/nuxt.config.ts +1 -3
- package/layers/design-system/typography/tsconfig.json +7 -0
- package/layers/{visual → design-system/visual}/app/app.config.ts +2 -2
- package/layers/{visual → design-system/visual}/app/components/Accent/Blob.vue +1 -1
- package/layers/{visual → design-system/visual}/app/components/Accent/Scene.vue +2 -3
- package/layers/{visual → design-system/visual}/app/components/Gradient/Background.vue +2 -2
- package/layers/{visual → design-system/visual}/app/components/Gradient/Text.vue +2 -2
- package/layers/{visual → design-system/visual}/app/composables/gradient.ts +1 -1
- package/layers/design-system/visual/app/types/breakpoints.ts +67 -0
- package/layers/{visual → design-system/visual}/app/types/media.ts +0 -11
- package/layers/{visual → design-system/visual}/nuxt.config.ts +1 -1
- package/layers/design-system/visual/tsconfig.json +7 -0
- package/layers/{animations → motion/animations}/app/components/Motion/Marquee.vue +0 -7
- package/layers/{animations → motion/animations}/app/components/Motion/Staggered.vue +4 -1
- package/layers/{animations → motion/animations}/nuxt.config.ts +1 -2
- package/layers/motion/animations/tsconfig.json +7 -0
- package/layers/motion/{package.json → motion/package.json} +1 -1
- package/layers/motion/{tsconfig.json → motion/tsconfig.json} +1 -1
- package/layers/motion/page-transitions/app/assets/css/page-transitions.css +30 -0
- package/layers/{page-transitions → motion/page-transitions}/app/composables/usePageTransition.ts +14 -2
- package/layers/{page-transitions → motion/page-transitions}/app/plugins/page-transitions.client.ts +5 -2
- package/layers/{page-transitions → motion/page-transitions}/nuxt.config.ts +3 -1
- package/layers/motion/page-transitions/tsconfig.json +7 -0
- package/layers/motion/scroll/app/app.config.ts +13 -0
- package/layers/{scroll → motion/scroll}/app/composables/useSmoothScroll.ts +2 -1
- package/layers/{scroll → motion/scroll}/app/plugins/locomotive-scroll.client.ts +2 -1
- package/layers/{scroll → motion/scroll}/nuxt.config.ts +1 -1
- package/layers/motion/scroll/tsconfig.json +7 -0
- package/layers/{transitions → motion/transitions}/nuxt.config.ts +1 -1
- package/layers/motion/transitions/tsconfig.json +7 -0
- package/layers/{canvas → render/canvas}/app/composables/useRendererCapabilities.ts +0 -8
- package/layers/{canvas → render/canvas}/app/composables/useShaderTime.ts +0 -12
- package/layers/{canvas → render/canvas}/nuxt.config.ts +1 -4
- package/layers/{canvas → render/canvas}/package.json +3 -2
- package/layers/{canvas → render/canvas}/tsconfig.json +1 -1
- package/layers/render/shader/app/app.config.ts +21 -0
- package/layers/{shader → render/shader}/app/shaders/layers/paperShading.ts +1 -1
- package/layers/{shader → render/shader}/package.json +1 -1
- package/layers/render/shader/tsconfig.json +7 -0
- package/layers/structure/grid/app/app.config.ts +92 -0
- package/layers/structure/grid/app/assets/css/grid.css +38 -0
- package/layers/structure/grid/app/composables/useGridTracks.test.ts +94 -0
- package/layers/structure/grid/app/composables/useGridTracks.ts +74 -0
- package/layers/structure/grid/app/types/tracks.test.ts +32 -0
- package/layers/structure/grid/app/types/tracks.ts +18 -0
- package/layers/structure/grid/app/utils/placement.test.ts +19 -0
- package/layers/structure/grid/app/utils/placement.ts +15 -0
- package/layers/structure/grid/nuxt.config.ts +22 -0
- package/layers/{theme → structure/grid}/package.json +3 -3
- package/layers/structure/layout/app/app.config.ts +116 -0
- package/layers/{layout → structure/layout}/app/assets/css/layout/grids.css +11 -6
- package/layers/structure/layout/app/assets/css/layout.css +1 -0
- package/layers/structure/layout/app/components/HStack.vue +41 -0
- package/layers/{layout → structure/layout}/app/components/Layout/Grid/Debug.vue +5 -3
- package/layers/{layout → structure/layout}/app/components/Layout/Grid/Item.vue +4 -10
- package/layers/{layout → structure/layout}/app/components/Layout/Main.vue +3 -3
- package/layers/{layout → structure/layout}/app/components/Layout/Page/Header.vue +1 -1
- package/layers/{layout → structure/layout}/app/components/Layout/Page/index.vue +3 -3
- package/layers/{layout → structure/layout}/app/components/Layout/Section/index.vue +1 -1
- package/layers/structure/layout/app/components/Spacer.vue +21 -0
- package/layers/structure/layout/app/components/VStack.vue +37 -0
- package/layers/structure/layout/app/components/ZStack.vue +28 -0
- package/layers/structure/layout/app/layouts/default.vue +5 -0
- package/layers/{layout → structure/layout}/app/types/layouts.ts +2 -3
- package/layers/{layout → structure/layout}/app/utils/gridPlacementStyle.test.ts +7 -42
- package/layers/{layout → structure/layout}/app/utils/gridPlacementStyle.ts +4 -18
- package/layers/{layout → structure/layout}/nuxt.config.ts +1 -1
- package/layers/{layout → structure/layout}/package.json +1 -1
- package/layers/structure/layout/tsconfig.json +7 -0
- package/layers/{navigation → structure/navigation}/app/app.config.ts +4 -6
- package/layers/structure/navigation/app/components/Mast/Header.vue +11 -0
- package/layers/{navigation → structure/navigation}/app/components/Mast/Nav.vue +1 -1
- package/layers/structure/navigation/app/composables/mastNav.ts +15 -0
- package/layers/{navigation → structure/navigation}/app/utils/createModal.ts +22 -3
- package/layers/{navigation → structure/navigation}/nuxt.config.ts +1 -1
- package/layers/structure/navigation/tsconfig.json +7 -0
- package/layers/{routing → structure/routing}/app/app.config.ts +11 -2
- package/layers/{routing → structure/routing}/nuxt.config.ts +1 -1
- package/layers/{routing → structure/routing}/package.json +1 -1
- package/layers/structure/routing/tsconfig.json +7 -0
- package/package.json +56 -56
- package/docs/fallow-refactor/layers-ui.md +0 -27
- package/layers/animations/app/types/animations.ts +0 -8
- package/layers/animations/app/types/index.ts +0 -1
- package/layers/baseline/nuxt.config.ts +0 -24
- package/layers/baseline/package.json +0 -14
- package/layers/content/app/components/Blog/Card.vue +0 -43
- package/layers/content/app/components/Gallery/AmbientImage.vue +0 -44
- package/layers/content/app/components/Gallery/Card.vue +0 -43
- package/layers/content/app/components/NuxtContent/Renderer.vue +0 -14
- package/layers/content/app/components/Portfolio/Card.vue +0 -43
- package/layers/content/app/composables/createPortfolioComposables.ts +0 -50
- package/layers/content/app/composables/useBlogPost.ts +0 -3
- package/layers/content/app/composables/useGalleryItem.ts +0 -3
- package/layers/content/app/composables/usePortfolioItem.ts +0 -3
- package/layers/content/app/composables/usePortfolioItems.ts +0 -26
- package/layers/content/app/types/app-config.d.ts +0 -14
- package/layers/core/app/assets/css-backup.zip +0 -0
- package/layers/core/app/composables/useEnv.ts +0 -23
- package/layers/core/app/composables/useScrollGuard.ts +0 -243
- package/layers/core/app/plugins/feature-detection.client.ts +0 -34
- package/layers/core/app/plugins/init.ts +0 -192
- package/layers/core/app/plugins/scroll-guard.client.ts +0 -56
- package/layers/core/app/types/app-config.d.ts +0 -63
- package/layers/core/app/types/scroll-guard.ts +0 -25
- package/layers/core/app/utils/helpers.test.ts +0 -55
- package/layers/core/app/utils/helpers.ts +0 -248
- package/layers/core/app/utils/regex.test.ts +0 -31
- package/layers/feeds/tsconfig.json +0 -7
- package/layers/forms/app/app.config.ts +0 -3
- package/layers/forms/tsconfig.json +0 -7
- package/layers/layout/app/app.config.ts +0 -180
- package/layers/layout/app/assets/css/layout/modes/fluid.css +0 -109
- package/layers/layout/app/assets/css/layout.css +0 -2
- package/layers/layout/app/components/Layout/Container.vue +0 -46
- package/layers/layout/app/components/Layout/Page/Container.vue +0 -103
- package/layers/layout/app/components/Layout/Section/Grid.vue +0 -46
- package/layers/layout/app/components/Layout/Section/Sidebar.vue +0 -84
- package/layers/layout/app/components/Layout/Section/Stack.vue +0 -63
- package/layers/layout/app/components/Layout/Section/Title.vue +0 -33
- package/layers/layout/app/composables/GridPlacement.ts +0 -31
- package/layers/layout/app/types/app-config.d.ts +0 -14
- package/layers/layout/tsconfig.json +0 -7
- package/layers/mailer/server/types.d.ts +0 -11
- package/layers/mailer/tsconfig.json +0 -7
- package/layers/metadata/app/composables/useMetadataItem.ts +0 -15
- package/layers/metadata/app/composables/useMetadataSearch.ts +0 -29
- package/layers/metadata/providers/comicvine/tsconfig.json +0 -7
- package/layers/metadata/providers/google-books/tsconfig.json +0 -7
- package/layers/metadata/providers/openlibrary/tsconfig.json +0 -7
- package/layers/metadata/tsconfig.json +0 -7
- package/layers/motion/app/components/Motion/index.vue +0 -16
- package/layers/navigation/app/components/Mast/Header.vue +0 -18
- package/layers/navigation/app/components/Mast/Main.vue +0 -7
- package/layers/navigation/app/composables/mastNav.ts +0 -26
- package/layers/navigation/app/utils/regex.ts +0 -6
- package/layers/navigation/tsconfig.json +0 -7
- package/layers/page-transitions/tsconfig.json +0 -7
- package/layers/routing/app/types/app-config.d.ts +0 -7
- package/layers/routing/tsconfig.json +0 -7
- package/layers/scripts/app/types/index.ts +0 -1
- package/layers/scripts/app/types/scripts.ts +0 -14
- package/layers/scripts/tsconfig.json +0 -7
- package/layers/scroll/app/app.config.ts +0 -31
- package/layers/scroll/tsconfig.json +0 -7
- package/layers/seo/app/composables/useSeoConfig.ts +0 -7
- package/layers/seo/tsconfig.json +0 -7
- package/layers/shader/app/app.config.ts +0 -9
- package/layers/shader/app/types/app-config.d.ts +0 -7
- package/layers/shader/tsconfig.json +0 -7
- package/layers/starter/app/app.config.ts +0 -10
- package/layers/starter/app/components/StarterDesignSystem.vue +0 -1913
- package/layers/starter/app/components/StarterHome.vue +0 -441
- package/layers/starter/nuxt.config.ts +0 -15
- package/layers/starter/package.json +0 -10
- package/layers/theme/app/app.config.ts +0 -3
- package/layers/theme/app/types/app-config.d.ts +0 -10
- package/layers/theme/app/types/theme.ts +0 -23
- package/layers/theme/nuxt.config.ts +0 -74
- package/layers/transitions/tsconfig.json +0 -7
- package/layers/typography/app/components/Typography/CodeBlock.vue +0 -41
- package/layers/typography/app/components/Typography/QuoteBlock.vue +0 -23
- package/layers/typography/tsconfig.json +0 -7
- package/layers/ui/app/assets/css/ui.css +0 -4
- package/layers/ui/app/layouts/default.vue +0 -8
- package/layers/ui/nuxt.config.ts +0 -22
- package/layers/ui/tsconfig.json +0 -7
- package/layers/visual/app/types/breakpoints.ts +0 -179
- package/layers/visual/tsconfig.json +0 -7
- /package/layers/{auth → data/auth}/app/middleware/auth.ts +0 -0
- /package/layers/{auth → data/auth}/server/routes/auth/github.get.ts +0 -0
- /package/layers/{database → data/database}/server/utils/drizzle.ts +0 -0
- /package/layers/{database → data/database}/server/utils/sql.ts +0 -0
- /package/layers/{forms → data/forms}/app/components/Form/Contact.vue +0 -0
- /package/layers/{forms → data/forms}/app/components/Form/Field.vue +0 -0
- /package/layers/{forms → data/forms}/app/composables/useFormSchema.ts +0 -0
- /package/layers/{forms → data/forms}/app/composables/useFormsFetch.ts +0 -0
- /package/layers/{forms → data/forms}/app/config/fields.ts +0 -0
- /package/layers/{forms → data/forms}/app/types/fields.ts +0 -0
- /package/layers/{forms → data/forms}/app/types/index.ts +0 -0
- /package/layers/{forms → data/forms}/app/utils/contact-schema.test.ts +0 -0
- /package/layers/{forms → data/forms}/app/utils/contact-schema.ts +0 -0
- /package/layers/{forms → data/forms}/app/utils/fieldProps.test.ts +0 -0
- /package/layers/{forms → data/forms}/app/utils/fieldProps.ts +0 -0
- /package/layers/{forms → data/forms}/nuxt.config.ts +0 -0
- /package/layers/{forms → data/forms}/server/api/contact.post.ts +0 -0
- /package/layers/{mailer → data/mailer}/app/types/index.ts +0 -0
- /package/layers/{mailer → data/mailer}/app/types/mailer.ts +0 -0
- /package/layers/{mailer → data/mailer}/server/utils/config.ts +0 -0
- /package/layers/{mailer → data/mailer}/server/utils/email.ts +0 -0
- /package/layers/{mailer → data/mailer}/server/utils/hooks.ts +0 -0
- /package/layers/{metadata → data/metadata}/providers/comicvine/server/plugins/comicvine-register.ts +0 -0
- /package/layers/{metadata → data/metadata}/providers/comicvine/server/utils/metadata-comicvine/client.ts +0 -0
- /package/layers/{metadata → data/metadata}/providers/comicvine/server/utils/metadata-comicvine/normalise.test.ts +0 -0
- /package/layers/{metadata → data/metadata}/providers/comicvine/server/utils/metadata-comicvine/normalise.ts +0 -0
- /package/layers/{metadata → data/metadata}/providers/comicvine/server/utils/metadata-comicvine/provider.ts +0 -0
- /package/layers/{metadata → data/metadata}/providers/comicvine/server/utils/metadata-comicvine/types.ts +0 -0
- /package/layers/{metadata → data/metadata}/providers/google-books/server/plugins/google-books-register.ts +0 -0
- /package/layers/{metadata → data/metadata}/providers/google-books/server/utils/metadata-google-books/client.test.ts +0 -0
- /package/layers/{metadata → data/metadata}/providers/google-books/server/utils/metadata-google-books/normalise.test.ts +0 -0
- /package/layers/{metadata → data/metadata}/providers/google-books/server/utils/metadata-google-books/normalise.ts +0 -0
- /package/layers/{metadata → data/metadata}/providers/google-books/server/utils/metadata-google-books/provider.ts +0 -0
- /package/layers/{metadata → data/metadata}/providers/google-books/server/utils/metadata-google-books/types.ts +0 -0
- /package/layers/{metadata → data/metadata}/providers/openlibrary/nuxt.config.ts +0 -0
- /package/layers/{metadata → data/metadata}/providers/openlibrary/server/plugins/openlibrary-register.ts +0 -0
- /package/layers/{metadata → data/metadata}/providers/openlibrary/server/utils/metadata-openlibrary/client.test.ts +0 -0
- /package/layers/{metadata → data/metadata}/providers/openlibrary/server/utils/metadata-openlibrary/normalise.test.ts +0 -0
- /package/layers/{metadata → data/metadata}/providers/openlibrary/server/utils/metadata-openlibrary/normalise.ts +0 -0
- /package/layers/{metadata → data/metadata}/providers/openlibrary/server/utils/metadata-openlibrary/provider.ts +0 -0
- /package/layers/{metadata → data/metadata}/providers/openlibrary/server/utils/metadata-openlibrary/types.ts +0 -0
- /package/layers/{metadata → data/metadata}/providers/themoviedb/server/plugins/tmdb-register.ts +0 -0
- /package/layers/{metadata → data/metadata}/providers/themoviedb/server/utils/metadata-tmdb/client.test.ts +0 -0
- /package/layers/{metadata → data/metadata}/providers/themoviedb/server/utils/metadata-tmdb/client.ts +0 -0
- /package/layers/{metadata → data/metadata}/providers/themoviedb/server/utils/metadata-tmdb/normalise.test.ts +0 -0
- /package/layers/{metadata → data/metadata}/providers/themoviedb/server/utils/metadata-tmdb/normalise.ts +0 -0
- /package/layers/{metadata → data/metadata}/providers/themoviedb/server/utils/metadata-tmdb/provider.ts +0 -0
- /package/layers/{metadata → data/metadata}/providers/themoviedb/server/utils/metadata-tmdb/types.ts +0 -0
- /package/layers/{metadata → data/metadata}/server/api/metadata/lookup.get.ts +0 -0
- /package/layers/{metadata → data/metadata}/server/api/metadata/providers.get.ts +0 -0
- /package/layers/{metadata → data/metadata}/server/api/metadata/search.get.ts +0 -0
- /package/layers/{metadata → data/metadata}/server/api/metadata/status.get.ts +0 -0
- /package/layers/{metadata → data/metadata}/server/api/metadata/sync.post.ts +0 -0
- /package/layers/{metadata → data/metadata}/server/utils/metadata/cache.test.ts +0 -0
- /package/layers/{metadata → data/metadata}/server/utils/metadata/cache.ts +0 -0
- /package/layers/{metadata → data/metadata}/server/utils/metadata/errors.ts +0 -0
- /package/layers/{metadata → data/metadata}/server/utils/metadata/provider-registry.test.ts +0 -0
- /package/layers/{metadata → data/metadata}/server/utils/metadata/provider-registry.ts +0 -0
- /package/layers/{metadata → data/metadata}/server/utils/metadata/search.test.ts +0 -0
- /package/layers/{feeds → delivery/feeds}/app/app.config.ts +0 -0
- /package/layers/{feeds → delivery/feeds}/app/assets/css/feeds.css +0 -0
- /package/layers/{feeds → delivery/feeds}/public/feed/style.css +0 -0
- /package/layers/{feeds → delivery/feeds}/server/routes/feed/[collection]/atom/all.get.ts +0 -0
- /package/layers/{feeds → delivery/feeds}/server/routes/feed/[collection]/atom.get.ts +0 -0
- /package/layers/{feeds → delivery/feeds}/server/routes/feed/[collection]/json/all.get.ts +0 -0
- /package/layers/{feeds → delivery/feeds}/server/routes/feed/[collection]/json.get.ts +0 -0
- /package/layers/{feeds → delivery/feeds}/server/routes/feed/[collection]/rss/all.get.ts +0 -0
- /package/layers/{feeds → delivery/feeds}/server/routes/feed/[collection]/rss.get.ts +0 -0
- /package/layers/{feeds → delivery/feeds}/server/routes/feed/atom/all.get.ts +0 -0
- /package/layers/{feeds → delivery/feeds}/server/routes/feed/atom.get.ts +0 -0
- /package/layers/{feeds → delivery/feeds}/server/routes/feed/demo.get.ts +0 -0
- /package/layers/{feeds → delivery/feeds}/server/routes/feed/index.get.ts +0 -0
- /package/layers/{feeds → delivery/feeds}/server/routes/feed/json/all.get.ts +0 -0
- /package/layers/{feeds → delivery/feeds}/server/routes/feed/json.get.ts +0 -0
- /package/layers/{feeds → delivery/feeds}/server/routes/feed/rss/all.get.ts +0 -0
- /package/layers/{feeds → delivery/feeds}/server/routes/feed/rss.get.ts +0 -0
- /package/layers/{feeds → delivery/feeds}/server/routes/feed/style.xsl.get.ts +0 -0
- /package/layers/{feeds → delivery/feeds}/server/utils/cache.ts +0 -0
- /package/layers/{feeds → delivery/feeds}/server/utils/content-adapter.test.ts +0 -0
- /package/layers/{feeds → delivery/feeds}/server/utils/content-adapter.ts +0 -0
- /package/layers/{feeds → delivery/feeds}/server/utils/feed-author.test.ts +0 -0
- /package/layers/{feeds → delivery/feeds}/server/utils/feed-author.ts +0 -0
- /package/layers/{feeds → delivery/feeds}/server/utils/feed-config.test.ts +0 -0
- /package/layers/{feeds → delivery/feeds}/server/utils/feed-xml.ts +0 -0
- /package/layers/{feeds → delivery/feeds}/server/utils/formats/atom.ts +0 -0
- /package/layers/{feeds → delivery/feeds}/server/utils/formats/json.ts +0 -0
- /package/layers/{feeds → delivery/feeds}/server/utils/formats/rss.ts +0 -0
- /package/layers/{feeds → delivery/feeds}/server/utils/formats.test.ts +0 -0
- /package/layers/{feeds → delivery/feeds}/server/utils/types.ts +0 -0
- /package/layers/{scripts → delivery/scripts}/app/app.config.ts +0 -0
- /package/layers/{baseline → delivery/scripts}/app/components/BaselineStatus.vue +0 -0
- /package/layers/{scripts → delivery/scripts}/app/composables/useScriptLoader.ts +0 -0
- /package/layers/{scripts → delivery/scripts}/app/composables/useYoutubeEmbed.ts +0 -0
- /package/layers/{baseline → delivery/scripts}/app/plugins/baseline-status.client.ts +0 -0
- /package/layers/{seo → delivery/seo}/app/app.config.ts +0 -0
- /package/layers/{theme → design-system/theming}/app/assets/css/theme.css +0 -0
- /package/layers/{theme → design-system/theming}/app/components/ThemePicker/Menu.vue +0 -0
- /package/layers/{theme → design-system/theming}/app/components/ThemePicker/MenuButton.vue +0 -0
- /package/layers/{theme → design-system/theming}/app/composables/useTheme.ts +0 -0
- /package/layers/{theme → design-system/theming}/app/composables/useThemePreferenceModels.ts +0 -0
- /package/layers/{theme → design-system/theming}/app/composables/useThemePreferences.ts +0 -0
- /package/layers/{theme → design-system/theming}/app/types/index.ts +0 -0
- /package/layers/{theme → design-system/theming}/server/utils/accent-css.test.ts +0 -0
- /package/layers/{theme → design-system/theming}/server/utils/fouc-config.test.ts +0 -0
- /package/layers/{theme → design-system/theming}/server/utils/fouc-config.ts +0 -0
- /package/layers/{typography → design-system/typography}/app/components/Typography/TextStroke.vue +0 -0
- /package/layers/{typography → design-system/typography}/app/composables/color.ts +0 -0
- /package/layers/{typography → design-system/typography}/app/types/colors.ts +0 -0
- /package/layers/{typography → design-system/typography}/app/types/index.ts +0 -0
- /package/layers/{typography → design-system/typography}/package.json +0 -0
- /package/layers/{visual → design-system/visual}/app/assets/css/visual.css +0 -0
- /package/layers/{visual → design-system/visual}/app/components/Base/Modal.vue +0 -0
- /package/layers/{visual → design-system/visual}/app/components/Media/Picture.vue +0 -0
- /package/layers/{visual → design-system/visual}/app/components/Progress/Bar.vue +0 -0
- /package/layers/{visual → design-system/visual}/app/components/Progress/Circular.vue +0 -0
- /package/layers/{visual → design-system/visual}/app/components/Tint/Overlay.vue +0 -0
- /package/layers/{visual → design-system/visual}/app/composables/accent.ts +0 -0
- /package/layers/{visual → design-system/visual}/app/composables/picture.ts +0 -0
- /package/layers/{visual → design-system/visual}/app/composables/tint.ts +0 -0
- /package/layers/{visual → design-system/visual}/app/types/accent.ts +0 -0
- /package/layers/{visual → design-system/visual}/app/types/gradient.ts +0 -0
- /package/layers/{visual → design-system/visual}/app/types/index.ts +0 -0
- /package/layers/{visual → design-system/visual}/app/types/tint.ts +0 -0
- /package/layers/{visual → design-system/visual}/app/utils/colorTokens.test.ts +0 -0
- /package/layers/{visual → design-system/visual}/app/utils/colorTokens.ts +0 -0
- /package/layers/{visual → design-system/visual}/app/utils/gradientStyle.test.ts +0 -0
- /package/layers/{visual → design-system/visual}/app/utils/gradientStyle.ts +0 -0
- /package/layers/{visual → design-system/visual}/app/utils/responsiveSizes.test.ts +0 -0
- /package/layers/{visual → design-system/visual}/app/utils/responsiveSizes.ts +0 -0
- /package/layers/{visual → design-system/visual}/package.json +0 -0
- /package/layers/{animations → motion/animations}/app/components/Motion/CountUp.vue +0 -0
- /package/layers/{animations → motion/animations}/app/components/Motion/Cursor.vue +0 -0
- /package/layers/{animations → motion/animations}/app/components/Motion/Magnetic.vue +0 -0
- /package/layers/{animations → motion/animations}/app/components/Motion/MarqueeText.vue +0 -0
- /package/layers/{animations → motion/animations}/app/components/Motion/TextReveal.vue +0 -0
- /package/layers/{animations → motion/animations}/app/components/Motion/Tilt.vue +0 -0
- /package/layers/{animations → motion/animations}/app/components/Motion/VelocityEffect.vue +0 -0
- /package/layers/{animations → motion/animations}/app/composables/useCountUp.ts +0 -0
- /package/layers/{animations → motion/animations}/app/composables/useCursorFollower.ts +0 -0
- /package/layers/{animations → motion/animations}/app/composables/useMagneticElement.ts +0 -0
- /package/layers/{animations → motion/animations}/app/composables/useMarqueeCopies.ts +0 -0
- /package/layers/{animations → motion/animations}/app/composables/useMarqueeVelocity.ts +0 -0
- /package/layers/{animations → motion/animations}/app/composables/useTiltEffect.ts +0 -0
- /package/layers/{animations → motion/animations}/app/utils/pointerMotion.ts +0 -0
- /package/layers/{animations → motion/animations}/package.json +0 -0
- /package/layers/motion/{nuxt.config.ts → motion/nuxt.config.ts} +0 -0
- /package/layers/{page-transitions → motion/page-transitions}/app/app.config.ts +0 -0
- /package/layers/{page-transitions → motion/page-transitions}/package.json +0 -0
- /package/layers/{scroll → motion/scroll}/app/components/Motion/HorizontalScroll.vue +0 -0
- /package/layers/{scroll → motion/scroll}/app/components/Motion/Parallax.vue +0 -0
- /package/layers/{scroll → motion/scroll}/app/components/Motion/PinnedSection.vue +0 -0
- /package/layers/{scroll → motion/scroll}/app/components/Motion/ScrollLink.vue +0 -0
- /package/layers/{scroll → motion/scroll}/app/components/Motion/ScrollProgress.vue +0 -0
- /package/layers/{scroll → motion/scroll}/app/components/Motion/ScrollScene.vue +0 -0
- /package/layers/{scroll → motion/scroll}/app/components/Motion/ScrollStats.vue +0 -0
- /package/layers/{scroll → motion/scroll}/app/components/Motion/ScrollStep.vue +0 -0
- /package/layers/{scroll → motion/scroll}/app/composables/useGsap.ts +0 -0
- /package/layers/{scroll → motion/scroll}/app/composables/useScrollSteps.ts +0 -0
- /package/layers/{scroll → motion/scroll}/app/composables/useSectionProgress.ts +0 -0
- /package/layers/{scroll → motion/scroll}/app/types/index.ts +0 -0
- /package/layers/{scroll → motion/scroll}/app/types/scroll.ts +0 -0
- /package/layers/{scroll → motion/scroll}/app/utils/scroll.ts +0 -0
- /package/layers/{scroll → motion/scroll}/package.json +0 -0
- /package/layers/{transitions → motion/transitions}/app/assets/css/transitions.css +0 -0
- /package/layers/{transitions → motion/transitions}/app/components/Motion/Transition.vue +0 -0
- /package/layers/{transitions → motion/transitions}/package.json +0 -0
- /package/layers/{canvas → render/canvas}/app/components/ShaderCanvas.vue +0 -0
- /package/layers/{canvas → render/canvas}/app/types/index.ts +0 -0
- /package/layers/{canvas → render/canvas}/app/types/renderer.ts +0 -0
- /package/layers/{shader → render/shader}/app/assets/css/shader.css +0 -0
- /package/layers/{shader → render/shader}/app/components/Effect/Bloom.vue +0 -0
- /package/layers/{shader → render/shader}/app/components/Effect/ChromaticAberration.vue +0 -0
- /package/layers/{shader → render/shader}/app/components/Effect/PostProcessing.vue +0 -0
- /package/layers/{shader → render/shader}/app/components/Material/AmbientAurora.client.vue +0 -0
- /package/layers/{shader → render/shader}/app/components/Material/AmbientFlow.client.vue +0 -0
- /package/layers/{shader → render/shader}/app/components/Material/AmbientGradientMesh.client.vue +0 -0
- /package/layers/{shader → render/shader}/app/components/Material/AmbientNebula.client.vue +0 -0
- /package/layers/{shader → render/shader}/app/components/Material/AmbientOcean.client.vue +0 -0
- /package/layers/{shader → render/shader}/app/components/Material/Fresnel.client.vue +0 -0
- /package/layers/{shader → render/shader}/app/components/Material/Gradient.client.vue +0 -0
- /package/layers/{shader → render/shader}/app/components/Material/Image.client.vue +0 -0
- /package/layers/{shader → render/shader}/app/components/Material/Node.client.vue +0 -0
- /package/layers/{shader → render/shader}/app/components/Material/Noise.client.vue +0 -0
- /package/layers/{shader → render/shader}/app/components/Mesh/Plane.vue +0 -0
- /package/layers/{shader → render/shader}/app/components/Node/Color.client.vue +0 -0
- /package/layers/{shader → render/shader}/app/components/Node/Fresnel.client.vue +0 -0
- /package/layers/{shader → render/shader}/app/components/Node/Gradient.client.vue +0 -0
- /package/layers/{shader → render/shader}/app/components/Node/Mix.client.vue +0 -0
- /package/layers/{shader → render/shader}/app/components/Node/Noise.client.vue +0 -0
- /package/layers/{shader → render/shader}/app/components/Pipeline/ACESTonemap.client.vue +0 -0
- /package/layers/{shader → render/shader}/app/components/Pipeline/AddBlend.client.vue +0 -0
- /package/layers/{shader → render/shader}/app/components/Pipeline/AgedFilm.client.vue +0 -0
- /package/layers/{shader → render/shader}/app/components/Pipeline/Aurora.client.vue +0 -0
- /package/layers/{shader → render/shader}/app/components/Pipeline/BilinearGradient.client.vue +0 -0
- /package/layers/{shader → render/shader}/app/components/Pipeline/BillowNoise.client.vue +0 -0
- /package/layers/{shader → render/shader}/app/components/Pipeline/BrightnessContrast.client.vue +0 -0
- /package/layers/{shader → render/shader}/app/components/Pipeline/CellularNoise.client.vue +0 -0
- /package/layers/{shader → render/shader}/app/components/Pipeline/ChannelMixer.client.vue +0 -0
- /package/layers/{shader → render/shader}/app/components/Pipeline/ChebyshevNoiseField.client.vue +0 -0
- /package/layers/{shader → render/shader}/app/components/Pipeline/Checkerboard.client.vue +0 -0
- /package/layers/{shader → render/shader}/app/components/Pipeline/ChromaticAberration.client.vue +0 -0
- /package/layers/{shader → render/shader}/app/components/Pipeline/ChromaticScreenWaves.client.vue +0 -0
- /package/layers/{shader → render/shader}/app/components/Pipeline/Circle.client.vue +0 -0
- /package/layers/{shader → render/shader}/app/components/Pipeline/Clouds.client.vue +0 -0
- /package/layers/{shader → render/shader}/app/components/Pipeline/ColorBurnBlend.client.vue +0 -0
- /package/layers/{shader → render/shader}/app/components/Pipeline/ColorDodgeBlend.client.vue +0 -0
- /package/layers/{shader → render/shader}/app/components/Pipeline/ColourRamp.client.vue +0 -0
- /package/layers/{shader → render/shader}/app/components/Pipeline/ComplexPlaneField.client.vue +0 -0
- /package/layers/{shader → render/shader}/app/components/Pipeline/ConicGradient.client.vue +0 -0
- /package/layers/{shader → render/shader}/app/components/Pipeline/CosinePalette.client.vue +0 -0
- /package/layers/{shader → render/shader}/app/components/Pipeline/CoverageAlpha.client.vue +0 -0
- /package/layers/{shader → render/shader}/app/components/Pipeline/Cross.client.vue +0 -0
- /package/layers/{shader → render/shader}/app/components/Pipeline/CurlNoise.client.vue +0 -0
- /package/layers/{shader → render/shader}/app/components/Pipeline/DarkenBlend.client.vue +0 -0
- /package/layers/{shader → render/shader}/app/components/Pipeline/DayNightCycle.client.vue +0 -0
- /package/layers/{shader → render/shader}/app/components/Pipeline/Desaturate.client.vue +0 -0
- /package/layers/{shader → render/shader}/app/components/Pipeline/DiagonalGradient.client.vue +0 -0
- /package/layers/{shader → render/shader}/app/components/Pipeline/DiamondGradient.client.vue +0 -0
- /package/layers/{shader → render/shader}/app/components/Pipeline/DifferenceBlend.client.vue +0 -0
- /package/layers/{shader → render/shader}/app/components/Pipeline/DivideBlend.client.vue +0 -0
- /package/layers/{shader → render/shader}/app/components/Pipeline/DomainWarpedNoise.client.vue +0 -0
- /package/layers/{shader → render/shader}/app/components/Pipeline/Dots.client.vue +0 -0
- /package/layers/{shader → render/shader}/app/components/Pipeline/DuoTone.client.vue +0 -0
- /package/layers/{shader → render/shader}/app/components/Pipeline/ExclusionBlend.client.vue +0 -0
- /package/layers/{shader → render/shader}/app/components/Pipeline/ExponentialFog.client.vue +0 -0
- /package/layers/{shader → render/shader}/app/components/Pipeline/Exposure.client.vue +0 -0
- /package/layers/{shader → render/shader}/app/components/Pipeline/FBMNoise.client.vue +0 -0
- /package/layers/{shader → render/shader}/app/components/Pipeline/FilmBurn.client.vue +0 -0
- /package/layers/{shader → render/shader}/app/components/Pipeline/FilmGrain.client.vue +0 -0
- /package/layers/{shader → render/shader}/app/components/Pipeline/FisheyeRay.client.vue +0 -0
- /package/layers/{shader → render/shader}/app/components/Pipeline/Flame.client.vue +0 -0
- /package/layers/{shader → render/shader}/app/components/Pipeline/FocalGradient.client.vue +0 -0
- /package/layers/{shader → render/shader}/app/components/Pipeline/Gamma.client.vue +0 -0
- /package/layers/{shader → render/shader}/app/components/Pipeline/GodRays.client.vue +0 -0
- /package/layers/{shader → render/shader}/app/components/Pipeline/GradientNoise.client.vue +0 -0
- /package/layers/{shader → render/shader}/app/components/Pipeline/Grain.client.vue +0 -0
- /package/layers/{shader → render/shader}/app/components/Pipeline/Grid.client.vue +0 -0
- /package/layers/{shader → render/shader}/app/components/Pipeline/Halation.client.vue +0 -0
- /package/layers/{shader → render/shader}/app/components/Pipeline/Halftone.client.vue +0 -0
- /package/layers/{shader → render/shader}/app/components/Pipeline/HardLightBlend.client.vue +0 -0
- /package/layers/{shader → render/shader}/app/components/Pipeline/Haze.client.vue +0 -0
- /package/layers/{shader → render/shader}/app/components/Pipeline/Hexagon.client.vue +0 -0
- /package/layers/{shader → render/shader}/app/components/Pipeline/Hue.client.vue +0 -0
- /package/layers/{shader → render/shader}/app/components/Pipeline/Invert.client.vue +0 -0
- /package/layers/{shader → render/shader}/app/components/Pipeline/LensFlare.client.vue +0 -0
- /package/layers/{shader → render/shader}/app/components/Pipeline/LightenBlend.client.vue +0 -0
- /package/layers/{shader → render/shader}/app/components/Pipeline/LinearGradient.client.vue +0 -0
- /package/layers/{shader → render/shader}/app/components/Pipeline/LinearGradient4.client.vue +0 -0
- /package/layers/{shader → render/shader}/app/components/Pipeline/LinearToSRGB.client.vue +0 -0
- /package/layers/{shader → render/shader}/app/components/Pipeline/Marble.client.vue +0 -0
- /package/layers/{shader → render/shader}/app/components/Pipeline/MixBlend.client.vue +0 -0
- /package/layers/{shader → render/shader}/app/components/Pipeline/MonochromeTint.client.vue +0 -0
- /package/layers/{shader → render/shader}/app/components/Pipeline/MultiplyBlend.client.vue +0 -0
- /package/layers/{shader → render/shader}/app/components/Pipeline/NoisyGradient.client.vue +0 -0
- /package/layers/{shader → render/shader}/app/components/Pipeline/NoisyGradientBlend.client.vue +0 -0
- /package/layers/{shader → render/shader}/app/components/Pipeline/OverlayBlend.client.vue +0 -0
- /package/layers/{shader → render/shader}/app/components/Pipeline/PaperTexture.client.vue +0 -0
- /package/layers/{shader → render/shader}/app/components/Pipeline/Polygon.client.vue +0 -0
- /package/layers/{shader → render/shader}/app/components/Pipeline/Posterise.client.vue +0 -0
- /package/layers/{shader → render/shader}/app/components/Pipeline/RadialGradient.client.vue +0 -0
- /package/layers/{shader → render/shader}/app/components/Pipeline/RayAutoOrbit.client.vue +0 -0
- /package/layers/{shader → render/shader}/app/components/Pipeline/RayMouseOrbit.client.vue +0 -0
- /package/layers/{shader → render/shader}/app/components/Pipeline/RayRotateX.client.vue +0 -0
- /package/layers/{shader → render/shader}/app/components/Pipeline/RayRotateY.client.vue +0 -0
- /package/layers/{shader → render/shader}/app/components/Pipeline/RayRotateZ.client.vue +0 -0
- /package/layers/{shader → render/shader}/app/components/Pipeline/RayTiltBasis.client.vue +0 -0
- /package/layers/{shader → render/shader}/app/components/Pipeline/RaymarchTunnel.client.vue +0 -0
- /package/layers/{shader → render/shader}/app/components/Pipeline/Rectangle.client.vue +0 -0
- /package/layers/{shader → render/shader}/app/components/Pipeline/ReinhardTonemap.client.vue +0 -0
- /package/layers/{shader → render/shader}/app/components/Pipeline/RidgedNoise.client.vue +0 -0
- /package/layers/{shader → render/shader}/app/components/Pipeline/Ring.client.vue +0 -0
- /package/layers/{shader → render/shader}/app/components/Pipeline/RingField.client.vue +0 -0
- /package/layers/{shader → render/shader}/app/components/Pipeline/RisographGrain.client.vue +0 -0
- /package/layers/{shader → render/shader}/app/components/Pipeline/RotatedGradientBlend.client.vue +0 -0
- /package/layers/{shader → render/shader}/app/components/Pipeline/SDFColourMask.client.vue +0 -0
- /package/layers/{shader → render/shader}/app/components/Pipeline/SDFRadialMask.client.vue +0 -0
- /package/layers/{shader → render/shader}/app/components/Pipeline/SRGBToLinear.client.vue +0 -0
- /package/layers/{shader → render/shader}/app/components/Pipeline/Saturation.client.vue +0 -0
- /package/layers/{shader → render/shader}/app/components/Pipeline/Scanlines.client.vue +0 -0
- /package/layers/{shader → render/shader}/app/components/Pipeline/ScreenBlend.client.vue +0 -0
- /package/layers/{shader → render/shader}/app/components/Pipeline/ShaderDebugger.client.vue +0 -0
- /package/layers/{shader → render/shader}/app/components/Pipeline/SimplexNoise.client.vue +0 -0
- /package/layers/{shader → render/shader}/app/components/Pipeline/SkyAtmosphere.client.vue +0 -0
- /package/layers/{shader → render/shader}/app/components/Pipeline/SoftLightBlend.client.vue +0 -0
- /package/layers/{shader → render/shader}/app/components/Pipeline/SolidColour.client.vue +0 -0
- /package/layers/{shader → render/shader}/app/components/Pipeline/SplitTone.client.vue +0 -0
- /package/layers/{shader → render/shader}/app/components/Pipeline/Star.client.vue +0 -0
- /package/layers/{shader → render/shader}/app/components/Pipeline/Starfield.client.vue +0 -0
- /package/layers/{shader → render/shader}/app/components/Pipeline/Stripes.client.vue +0 -0
- /package/layers/{shader → render/shader}/app/components/Pipeline/SubtractBlend.client.vue +0 -0
- /package/layers/{shader → render/shader}/app/components/Pipeline/TanhTonemap.client.vue +0 -0
- /package/layers/{shader → render/shader}/app/components/Pipeline/Threshold.client.vue +0 -0
- /package/layers/{shader → render/shader}/app/components/Pipeline/Tint.client.vue +0 -0
- /package/layers/{shader → render/shader}/app/components/Pipeline/Triangle.client.vue +0 -0
- /package/layers/{shader → render/shader}/app/components/Pipeline/UVAspectCorrect.client.vue +0 -0
- /package/layers/{shader → render/shader}/app/components/Pipeline/UVBreath.client.vue +0 -0
- /package/layers/{shader → render/shader}/app/components/Pipeline/UVBulge.client.vue +0 -0
- /package/layers/{shader → render/shader}/app/components/Pipeline/UVClamp.client.vue +0 -0
- /package/layers/{shader → render/shader}/app/components/Pipeline/UVColumnOffset.client.vue +0 -0
- /package/layers/{shader → render/shader}/app/components/Pipeline/UVFlipX.client.vue +0 -0
- /package/layers/{shader → render/shader}/app/components/Pipeline/UVFlipXY.client.vue +0 -0
- /package/layers/{shader → render/shader}/app/components/Pipeline/UVFlipY.client.vue +0 -0
- /package/layers/{shader → render/shader}/app/components/Pipeline/UVFractBand.client.vue +0 -0
- /package/layers/{shader → render/shader}/app/components/Pipeline/UVMousePull.client.vue +0 -0
- /package/layers/{shader → render/shader}/app/components/Pipeline/UVNoiseRotate.client.vue +0 -0
- /package/layers/{shader → render/shader}/app/components/Pipeline/UVNoiseWarp.client.vue +0 -0
- /package/layers/{shader → render/shader}/app/components/Pipeline/UVOrbit.client.vue +0 -0
- /package/layers/{shader → render/shader}/app/components/Pipeline/UVParallax.client.vue +0 -0
- /package/layers/{shader → render/shader}/app/components/Pipeline/UVPixelate.client.vue +0 -0
- /package/layers/{shader → render/shader}/app/components/Pipeline/UVPulse.client.vue +0 -0
- /package/layers/{shader → render/shader}/app/components/Pipeline/UVRipple.client.vue +0 -0
- /package/layers/{shader → render/shader}/app/components/Pipeline/UVRotate.client.vue +0 -0
- /package/layers/{shader → render/shader}/app/components/Pipeline/UVScale.client.vue +0 -0
- /package/layers/{shader → render/shader}/app/components/Pipeline/UVScroll.client.vue +0 -0
- /package/layers/{shader → render/shader}/app/components/Pipeline/UVScrollX.client.vue +0 -0
- /package/layers/{shader → render/shader}/app/components/Pipeline/UVScrollY.client.vue +0 -0
- /package/layers/{shader → render/shader}/app/components/Pipeline/UVShear.client.vue +0 -0
- /package/layers/{shader → render/shader}/app/components/Pipeline/UVSineWarpXY.client.vue +0 -0
- /package/layers/{shader → render/shader}/app/components/Pipeline/UVSwapAxes.client.vue +0 -0
- /package/layers/{shader → render/shader}/app/components/Pipeline/UVTile.client.vue +0 -0
- /package/layers/{shader → render/shader}/app/components/Pipeline/UVTwirl.client.vue +0 -0
- /package/layers/{shader → render/shader}/app/components/Pipeline/UVWarp.client.vue +0 -0
- /package/layers/{shader → render/shader}/app/components/Pipeline/VHSBleed.client.vue +0 -0
- /package/layers/{shader → render/shader}/app/components/Pipeline/ValueNoise.client.vue +0 -0
- /package/layers/{shader → render/shader}/app/components/Pipeline/Vibrance.client.vue +0 -0
- /package/layers/{shader → render/shader}/app/components/Pipeline/Vignette.client.vue +0 -0
- /package/layers/{shader → render/shader}/app/components/Pipeline/VoronoiEdges.client.vue +0 -0
- /package/layers/{shader → render/shader}/app/components/Pipeline/Water.client.vue +0 -0
- /package/layers/{shader → render/shader}/app/components/Pipeline/WaveBendLayer.client.vue +0 -0
- /package/layers/{shader → render/shader}/app/components/Pipeline/WaveColourLayer.client.vue +0 -0
- /package/layers/{shader → render/shader}/app/components/Pipeline/WhiteBalance.client.vue +0 -0
- /package/layers/{shader → render/shader}/app/components/Pipeline/Wood.client.vue +0 -0
- /package/layers/{shader → render/shader}/app/components/Preset/Aurora.client.vue +0 -0
- /package/layers/{shader → render/shader}/app/components/Preset/Flow.client.vue +0 -0
- /package/layers/{shader → render/shader}/app/components/Preset/GradientMesh.client.vue +0 -0
- /package/layers/{shader → render/shader}/app/components/Preset/Nebula.client.vue +0 -0
- /package/layers/{shader → render/shader}/app/components/Preset/Ocean.client.vue +0 -0
- /package/layers/{shader → render/shader}/app/components/Preset/ThemeAurora.client.vue +0 -0
- /package/layers/{shader → render/shader}/app/components/Preset/ThemeBubble.client.vue +0 -0
- /package/layers/{shader → render/shader}/app/components/Preset/ThemeFlow.client.vue +0 -0
- /package/layers/{shader → render/shader}/app/components/Preset/ThemeGradient.client.vue +0 -0
- /package/layers/{shader → render/shader}/app/components/Preset/ThemeLavaLamp.client.vue +0 -0
- /package/layers/{shader → render/shader}/app/components/Preset/ThemePlasma.client.vue +0 -0
- /package/layers/{shader → render/shader}/app/components/Preset/ThemeWave.client.vue +0 -0
- /package/layers/{shader → render/shader}/app/components/Shader/Background.client.vue +0 -0
- /package/layers/{shader → render/shader}/app/components/Shader/Debug.vue +0 -0
- /package/layers/{shader → render/shader}/app/components/Shader/Host.client.vue +0 -0
- /package/layers/{shader → render/shader}/app/components/Shader/Material.client.vue +0 -0
- /package/layers/{shader → render/shader}/app/components/Shader/Pipeline.client.vue +0 -0
- /package/layers/{shader → render/shader}/app/components/Shader/PipelineContext.vue +0 -0
- /package/layers/{shader → render/shader}/app/components/Shader/Runtime.client.vue +0 -0
- /package/layers/{shader → render/shader}/app/composables/useAmbientMaterials.ts +0 -0
- /package/layers/{shader → render/shader}/app/composables/useCSSColourUniform.ts +0 -0
- /package/layers/{shader → render/shader}/app/composables/useCSSFloatUniform.ts +0 -0
- /package/layers/{shader → render/shader}/app/composables/useMousePosition.ts +0 -0
- /package/layers/{shader → render/shader}/app/composables/useShader.ts +0 -0
- /package/layers/{shader → render/shader}/app/composables/useShaderColor.ts +0 -0
- /package/layers/{shader → render/shader}/app/composables/useShaderFloat.ts +0 -0
- /package/layers/{shader → render/shader}/app/composables/useShaderGraph.ts +0 -0
- /package/layers/{shader → render/shader}/app/composables/useShaderMixBlend.ts +0 -0
- /package/layers/{shader → render/shader}/app/composables/useShaderPerf.ts +0 -0
- /package/layers/{shader → render/shader}/app/composables/useShaderPipeline.ts +0 -0
- /package/layers/{shader → render/shader}/app/composables/useShaderRuntime.ts +0 -0
- /package/layers/{shader → render/shader}/app/composables/useShaderVec2.ts +0 -0
- /package/layers/{shader → render/shader}/app/composables/useSunDirectionUniform.ts +0 -0
- /package/layers/{shader → render/shader}/app/composables/useTSLNodes.ts +0 -0
- /package/layers/{shader → render/shader}/app/composables/useThemeColors.ts +0 -0
- /package/layers/{shader → render/shader}/app/composables/useThemePreset.ts +0 -0
- /package/layers/{shader → render/shader}/app/composables/useUniformWatchers.ts +0 -0
- /package/layers/{shader → render/shader}/app/composables/useUniforms.ts +0 -0
- /package/layers/{shader → render/shader}/app/plugins/shader.client.ts +0 -0
- /package/layers/{shader → render/shader}/app/shaders/common/blend.ts +0 -0
- /package/layers/{shader → render/shader}/app/shaders/common/complex.ts +0 -0
- /package/layers/{shader → render/shader}/app/shaders/common/effects.ts +0 -0
- /package/layers/{shader → render/shader}/app/shaders/common/grain.ts +0 -0
- /package/layers/{shader → render/shader}/app/shaders/common/index.ts +0 -0
- /package/layers/{shader → render/shader}/app/shaders/common/lighting.ts +0 -0
- /package/layers/{shader → render/shader}/app/shaders/common/math.ts +0 -0
- /package/layers/{shader → render/shader}/app/shaders/common/nodes.ts +0 -0
- /package/layers/{shader → render/shader}/app/shaders/common/noise.ts +0 -0
- /package/layers/{shader → render/shader}/app/shaders/common/noiseHelpers.ts +0 -0
- /package/layers/{shader → render/shader}/app/shaders/common/palette.ts +0 -0
- /package/layers/{shader → render/shader}/app/shaders/common/patterns.ts +0 -0
- /package/layers/{shader → render/shader}/app/shaders/common/sdf.ts +0 -0
- /package/layers/{shader → render/shader}/app/shaders/common/shapes.ts +0 -0
- /package/layers/{shader → render/shader}/app/shaders/common/tonemapping.ts +0 -0
- /package/layers/{shader → render/shader}/app/shaders/common/uv.ts +0 -0
- /package/layers/{shader → render/shader}/app/shaders/createMaterial.ts +0 -0
- /package/layers/{shader → render/shader}/app/shaders/index.ts +0 -0
- /package/layers/{shader → render/shader}/app/shaders/layers/aurora.ts +0 -0
- /package/layers/{shader → render/shader}/app/shaders/layers/index.ts +0 -0
- /package/layers/{shader → render/shader}/app/shaders/layers/meshGradient.ts +0 -0
- /package/layers/{shader → render/shader}/app/shaders/layers/shaderGradient.ts +0 -0
- /package/layers/{shader → render/shader}/app/shaders/layers/stripe.ts +0 -0
- /package/layers/{shader → render/shader}/app/shaders/types.ts +0 -0
- /package/layers/{shader → render/shader}/app/types/index.ts +0 -0
- /package/layers/{shader → render/shader}/app/types/materials.ts +0 -0
- /package/layers/{shader → render/shader}/app/types/renderer.ts +0 -0
- /package/layers/{shader → render/shader}/app/types/tsl.ts +0 -0
- /package/layers/{shader → render/shader}/app/types/uniforms.ts +0 -0
- /package/layers/{shader → render/shader}/app/utils/tsl/animation.ts +0 -0
- /package/layers/{shader → render/shader}/app/utils/tsl/color.ts +0 -0
- /package/layers/{shader → render/shader}/app/utils/tsl/index.ts +0 -0
- /package/layers/{shader → render/shader}/app/utils/tsl/math.ts +0 -0
- /package/layers/{shader → render/shader}/app/utils/tsl/noise.ts +0 -0
- /package/layers/{shader → render/shader}/app/utils/tsl/oklch.ts +0 -0
- /package/layers/{shader → render/shader}/app/utils/tsl/patterns.ts +0 -0
- /package/layers/{shader → render/shader}/app/utils/tsl/tween.ts +0 -0
- /package/layers/{shader → render/shader}/app/utils/tsl/uv.ts +0 -0
- /package/layers/{shader → render/shader}/nuxt.config.ts +0 -0
- /package/layers/{layout → structure/layout}/app/components/Layout/Section/Gallery.vue +0 -0
- /package/layers/{layout → structure/layout}/app/components/Layout/Section/Hero.vue +0 -0
- /package/layers/{layout → structure/layout}/app/components/Layout/Section/Split.vue +0 -0
- /package/layers/{layout → structure/layout}/app/composables/useGridConfig.ts +0 -0
- /package/layers/{layout → structure/layout}/app/types/index.ts +0 -0
- /package/layers/{layout → structure/layout}/tailwind.config.js +0 -0
- /package/layers/{navigation → structure/navigation}/app/assets/css/navigation.css +0 -0
- /package/layers/{navigation → structure/navigation}/app/components/Links/Group.vue +0 -0
- /package/layers/{navigation → structure/navigation}/app/components/Links/Named.vue +0 -0
- /package/layers/{navigation → structure/navigation}/app/components/Mast/Footer.vue +0 -0
- /package/layers/{navigation → structure/navigation}/app/components/Mast/NavModal.vue +0 -0
- /package/layers/{navigation → structure/navigation}/app/components/Site/Subtitle.vue +0 -0
- /package/layers/{navigation → structure/navigation}/app/components/Site/Title.vue +0 -0
- /package/layers/{navigation → structure/navigation}/app/composables/toast.ts +0 -0
- /package/layers/{navigation → structure/navigation}/app/composables/useSite.ts +0 -0
- /package/layers/{navigation → structure/navigation}/app/types/index.ts +0 -0
- /package/layers/{navigation → structure/navigation}/app/types/nav.ts +0 -0
- /package/layers/{core → structure/navigation}/app/utils/regex.ts +0 -0
- /package/layers/{navigation → structure/navigation}/app/utils/site.test.ts +0 -0
- /package/layers/{navigation → structure/navigation}/app/utils/site.ts +0 -0
- /package/layers/{navigation → structure/navigation}/package.json +0 -0
- /package/layers/{routing → structure/routing}/app/composables/useFeatureFlags.ts +0 -0
- /package/layers/{routing → structure/routing}/app/composables/useMaintenance.ts +0 -0
- /package/layers/{routing → structure/routing}/app/composables/useRoutingConfig.ts +0 -0
- /package/layers/{routing → structure/routing}/app/middleware/01.maintenance.global.ts +0 -0
- /package/layers/{routing → structure/routing}/app/middleware/02.governance.global.ts +0 -0
- /package/layers/{routing → structure/routing}/app/plugins/feature-flags.client.ts +0 -0
- /package/layers/{routing → structure/routing}/app/plugins/scroll-routing.client.ts +0 -0
- /package/layers/{routing → structure/routing}/app/types/index.ts +0 -0
- /package/layers/{routing → structure/routing}/app/types/route-meta.d.ts +0 -0
- /package/layers/{routing → structure/routing}/app/types/routing.ts +0 -0
- /package/layers/{routing → structure/routing}/app/utils/resolveRoute.test.ts +0 -0
- /package/layers/{routing → structure/routing}/app/utils/resolveRoute.ts +0 -0
- /package/layers/{routing → structure/routing}/server/api/feature-flags.get.ts +0 -0
|
@@ -0,0 +1,342 @@
|
|
|
1
|
+
# Vue Element System — Design Spec
|
|
2
|
+
|
|
3
|
+
Source: `Vue Element System.md` (repo root) + working prototype at
|
|
4
|
+
`/Users/kieranmansfield/Developer/element-test`. This spec adapts both into
|
|
5
|
+
`layers/structure/layout`, on top of the declarative layout system already
|
|
6
|
+
shipped this session (`nuxt-declarative-layout-system-spec.md`).
|
|
7
|
+
|
|
8
|
+
## §0 Relationship to prior work
|
|
9
|
+
|
|
10
|
+
`nuxt-declarative-layout-system-spec.md` shipped `useLayoutAttrs` (core),
|
|
11
|
+
`HStack`/`VStack`/`ZStack`/`Spacer`/`AppContainer`, and explicitly **parked**
|
|
12
|
+
two things: a new Grid primitive (§20: "no new Grid primitive... untouched
|
|
13
|
+
this pass") and a semantic colour/surface system (§4.3, §21: Phase 2, gated
|
|
14
|
+
on Nuxt UI Unstyled work). This spec reopens both, scoped narrowly to
|
|
15
|
+
`Element` only — it does not touch `LayoutGridItem`'s placement logic, and it
|
|
16
|
+
does not introduce semantic colour tokens (bg/color stay raw CSS passthrough,
|
|
17
|
+
same as the prototype).
|
|
18
|
+
|
|
19
|
+
`2026-09-03-layout-layer-fluid-rebuild-design.md` (same day, separate
|
|
20
|
+
worktree) proposes removing `colStart`/`colSpan`/`rowStart`/`rowSpan`
|
|
21
|
+
entirely. Confirmed with the user as **shelved, not proceeding** — safe to
|
|
22
|
+
build Element's Grid group on the current engine.
|
|
23
|
+
|
|
24
|
+
## §1 Purpose
|
|
25
|
+
|
|
26
|
+
`Element` is a polymorphic primitive that gives Vue templates a small,
|
|
27
|
+
typed, composable vocabulary for layout/grid/spacing/sizing/surface/
|
|
28
|
+
interaction — replacing large utility-class strings with attributes that
|
|
29
|
+
read as a description of the composition. Not a Tailwind clone, not a
|
|
30
|
+
universal `Box` with every CSS property exposed, not a semantic colour
|
|
31
|
+
system.
|
|
32
|
+
|
|
33
|
+
```vue
|
|
34
|
+
<Element as="section" grid :cols="12" gap="lg" p="lg" bg="var(--ui-bg-elevated)">
|
|
35
|
+
<Element :colSpan="8">Main</Element>
|
|
36
|
+
<Element :colSpan="4">Sidebar</Element>
|
|
37
|
+
</Element>
|
|
38
|
+
```
|
|
39
|
+
|
|
40
|
+
Typography is explicitly out of scope (per source doc) — no `text`/`font`
|
|
41
|
+
props.
|
|
42
|
+
|
|
43
|
+
## §2 Layer placement
|
|
44
|
+
|
|
45
|
+
`layers/structure/layout` — same tier as `HStack`/`VStack`/`ZStack`/
|
|
46
|
+
`Spacer`. No new layer: the repo already dissolved a dedicated `ui` layer
|
|
47
|
+
specifically to avoid a second primitives home (CLAUDE.md). `Element`
|
|
48
|
+
becomes that layer's polymorphic sibling, reusing its existing grid engine
|
|
49
|
+
directly rather than duplicating it in `core` (which has zero layer deps by
|
|
50
|
+
convention).
|
|
51
|
+
|
|
52
|
+
## §3 Property groups
|
|
53
|
+
|
|
54
|
+
Six groups, each an internal composable in
|
|
55
|
+
`layers/structure/layout/app/composables/`. Markup stays flat — groups are
|
|
56
|
+
an architectural seam, not a markup namespace.
|
|
57
|
+
|
|
58
|
+
### 3.1 Layout — `useElementLayout.ts` (new)
|
|
59
|
+
|
|
60
|
+
```ts
|
|
61
|
+
interface ElementLayoutProps {
|
|
62
|
+
block?: boolean
|
|
63
|
+
flex?: boolean
|
|
64
|
+
grid?: boolean
|
|
65
|
+
hidden?: boolean
|
|
66
|
+
}
|
|
67
|
+
```
|
|
68
|
+
|
|
69
|
+
Resolves to `display`. Exactly one of the four booleans wins (first match:
|
|
70
|
+
hidden > grid > flex > block), matching the prototype's `displayFor` map.
|
|
71
|
+
|
|
72
|
+
### 3.2 Spacing — reuse `useLayoutAttrs` (core), extended
|
|
73
|
+
|
|
74
|
+
`useLayoutAttrs` (`layers/core/app/composables/useLayoutAttrs.ts`) already
|
|
75
|
+
resolves `gap`/`align`/`justify`/`p`/`px`/`py` off the fluid `Spacing`
|
|
76
|
+
token scale. Add `m`/`mx`/`my` (margin) — additive, optional fields, backward
|
|
77
|
+
compatible with `HStack`/`VStack`'s existing calls (they don't pass margin,
|
|
78
|
+
nothing changes for them). Element's Spacing group is this composable, not
|
|
79
|
+
a new one.
|
|
80
|
+
|
|
81
|
+
```ts
|
|
82
|
+
// added to LayoutAttrsInput
|
|
83
|
+
m?: ResponsiveValue<Spacing> | Spacing | undefined
|
|
84
|
+
mx?: ResponsiveValue<Spacing> | Spacing | undefined
|
|
85
|
+
my?: ResponsiveValue<Spacing> | Spacing | undefined
|
|
86
|
+
```
|
|
87
|
+
|
|
88
|
+
### 3.3 Grid — `useElementGrid.ts` (new), wraps existing engine
|
|
89
|
+
|
|
90
|
+
Two axes:
|
|
91
|
+
|
|
92
|
+
- **Container axis** (`grid` bool set): `cols`/`rows`/`gap` → `gridTemplateColumns`/`Rows`. `gap` already covered by 3.2. `cols`/`rows` accept a number (→ `repeat(n, 1fr)`) or a raw CSS track string, matching the prototype's `track()` helper. This axis has no existing engine to reuse — `LayoutGridItem` is item-only — so it's new, small code.
|
|
93
|
+
- **Item axis** (placement within a parent grid): `colStart`/`colSpan`/`rowStart`/`rowSpan`, delegated directly to `buildGridPlacementStyle` (`layers/structure/layout/app/utils/gridPlacementStyle.ts`) — same names, same responsive/bleed/align/layer support `LayoutGridItem` already has. **Decision:** these names, not the source doc's `span`/`start`/`end` — one grid vocabulary in this layer, not two competing spellings for the same concept.
|
|
94
|
+
|
|
95
|
+
```ts
|
|
96
|
+
interface ElementGridProps {
|
|
97
|
+
grid?: boolean
|
|
98
|
+
cols?: number | string
|
|
99
|
+
rows?: number | string
|
|
100
|
+
colStart?: number | ResponsiveValue<number>
|
|
101
|
+
colSpan?: number | 'full' | ResponsiveValue<number>
|
|
102
|
+
rowStart?: number | ResponsiveValue<number>
|
|
103
|
+
rowSpan?: number | ResponsiveValue<number>
|
|
104
|
+
}
|
|
105
|
+
```
|
|
106
|
+
|
|
107
|
+
`align`/`justify`/`bleed`/`density`/`layer` from `buildGridPlacementStyle`
|
|
108
|
+
are **not** exposed on `Element` in this pass — `LayoutGridItem` remains the
|
|
109
|
+
component for those; Element's item-axis support covers the common
|
|
110
|
+
span/start case only. Escape hatch: use `LayoutGridItem` directly, or
|
|
111
|
+
`:style` on `Element`, for the rest.
|
|
112
|
+
|
|
113
|
+
### 3.4 Sizing — `useElementSizing.ts` (new)
|
|
114
|
+
|
|
115
|
+
```ts
|
|
116
|
+
interface ElementSizingProps {
|
|
117
|
+
w?: CSSProperties['width']
|
|
118
|
+
h?: CSSProperties['height']
|
|
119
|
+
minW?: CSSProperties['minWidth']
|
|
120
|
+
maxW?: CSSProperties['maxWidth']
|
|
121
|
+
minH?: CSSProperties['minHeight']
|
|
122
|
+
maxH?: CSSProperties['maxHeight']
|
|
123
|
+
aspect?: CSSProperties['aspectRatio']
|
|
124
|
+
}
|
|
125
|
+
```
|
|
126
|
+
|
|
127
|
+
Raw CSS passthrough, same shape as the prototype. No token constraint — sizing is inherently arbitrary (pixel dimensions, percentages).
|
|
128
|
+
|
|
129
|
+
### 3.5 Surface — `useElementSurface.ts` (new)
|
|
130
|
+
|
|
131
|
+
```ts
|
|
132
|
+
interface ElementSurfaceProps {
|
|
133
|
+
bg?: CSSProperties['background']
|
|
134
|
+
color?: CSSProperties['color']
|
|
135
|
+
border?: CSSProperties['border']
|
|
136
|
+
radius?: CSSProperties['borderRadius']
|
|
137
|
+
shadow?: CSSProperties['boxShadow']
|
|
138
|
+
}
|
|
139
|
+
```
|
|
140
|
+
|
|
141
|
+
Raw CSS passthrough (per user decision) — `bg="var(--ui-color-primary-500)"`, not `bg="primary"`. No semantic colour resolution; that stays Phase 2 territory, untouched. No new `radius`/`shadow` token files exist in `core` yet — not created here.
|
|
142
|
+
|
|
143
|
+
### 3.6 Interaction — `useElementInteraction.ts` (new)
|
|
144
|
+
|
|
145
|
+
```ts
|
|
146
|
+
interface ElementInteractionProps {
|
|
147
|
+
cursor?: CSSProperties['cursor']
|
|
148
|
+
select?: CSSProperties['userSelect']
|
|
149
|
+
pointer?: CSSProperties['pointerEvents']
|
|
150
|
+
}
|
|
151
|
+
```
|
|
152
|
+
|
|
153
|
+
Direct port of the prototype's composable — already minimal and correct.
|
|
154
|
+
|
|
155
|
+
## §4 `Element.vue`
|
|
156
|
+
|
|
157
|
+
```vue
|
|
158
|
+
<script setup lang="ts">
|
|
159
|
+
import type { Component, CSSProperties } from 'vue'
|
|
160
|
+
import type { LayoutAttrsInput } from '#layers/core/app/composables/useLayoutAttrs'
|
|
161
|
+
import type { ElementGridProps } from '#layers/layout/app/composables/useElementGrid'
|
|
162
|
+
import type { ElementInteractionProps } from '#layers/layout/app/composables/useElementInteraction'
|
|
163
|
+
import type { ElementLayoutProps } from '#layers/layout/app/composables/useElementLayout'
|
|
164
|
+
import type { ElementSizingProps } from '#layers/layout/app/composables/useElementSizing'
|
|
165
|
+
import type { ElementSurfaceProps } from '#layers/layout/app/composables/useElementSurface'
|
|
166
|
+
|
|
167
|
+
const props = withDefaults(
|
|
168
|
+
defineProps<
|
|
169
|
+
ElementLayoutProps &
|
|
170
|
+
ElementGridProps &
|
|
171
|
+
LayoutAttrsInput &
|
|
172
|
+
ElementSizingProps &
|
|
173
|
+
ElementSurfaceProps &
|
|
174
|
+
ElementInteractionProps & { as?: string | Component }
|
|
175
|
+
>(),
|
|
176
|
+
{ as: 'div' }
|
|
177
|
+
)
|
|
178
|
+
|
|
179
|
+
const style = computed<CSSProperties>(() => ({
|
|
180
|
+
...useElementLayout(props).value,
|
|
181
|
+
...useLayoutAttrs(() => props).style.value,
|
|
182
|
+
...useElementGrid(props).value,
|
|
183
|
+
...useElementSizing(props).value,
|
|
184
|
+
...useElementSurface(props).value,
|
|
185
|
+
...useElementInteraction(props).value,
|
|
186
|
+
}))
|
|
187
|
+
</script>
|
|
188
|
+
|
|
189
|
+
<template>
|
|
190
|
+
<component :is="as" :style>
|
|
191
|
+
<slot />
|
|
192
|
+
</component>
|
|
193
|
+
</template>
|
|
194
|
+
```
|
|
195
|
+
|
|
196
|
+
Root-level, unprefixed component name (`<Element>`), matching `HStack`/
|
|
197
|
+
`VStack`'s convention.
|
|
198
|
+
|
|
199
|
+
## §5 Types file
|
|
200
|
+
|
|
201
|
+
`layers/structure/layout/app/types/element.ts` re-exports the union:
|
|
202
|
+
|
|
203
|
+
```ts
|
|
204
|
+
export type ElementProps = ElementLayoutProps &
|
|
205
|
+
ElementGridProps &
|
|
206
|
+
LayoutAttrsInput &
|
|
207
|
+
ElementSizingProps &
|
|
208
|
+
ElementSurfaceProps &
|
|
209
|
+
ElementInteractionProps & { as?: string | Component }
|
|
210
|
+
```
|
|
211
|
+
|
|
212
|
+
Consumed by future semantic components (`Card`, `Section` variants) that
|
|
213
|
+
want a documented subset — per source doc's "Component Capabilities"
|
|
214
|
+
section. No such consumer is built in this pass; the type just exists for
|
|
215
|
+
one to compose against later.
|
|
216
|
+
|
|
217
|
+
## §6 What's explicitly out of scope this pass
|
|
218
|
+
|
|
219
|
+
- Typography vocabulary (source doc defers it too).
|
|
220
|
+
- Semantic colour/surface tokens (`bg="surface"`) — Phase 2, per the
|
|
221
|
+
declarative-layout spec's §21, untouched.
|
|
222
|
+
- `align`/`justify`/`bleed`/`density`/`layer` on Element's Grid group — use
|
|
223
|
+
`LayoutGridItem` directly for those.
|
|
224
|
+
- Any change to `LayoutGridItem`, `gridPlacementStyle.ts` placement logic,
|
|
225
|
+
or the fluid-rebuild spec's territory — read-only reuse, zero edits.
|
|
226
|
+
- A new `Grid`/`Section` container component — `Element grid` covers the
|
|
227
|
+
"I am a grid" case inline; the source doc's own example doesn't need a
|
|
228
|
+
separate named component for it.
|
|
229
|
+
|
|
230
|
+
## §7 File layout
|
|
231
|
+
|
|
232
|
+
```
|
|
233
|
+
layers/structure/layout/app/
|
|
234
|
+
├── components/
|
|
235
|
+
│ └── Element.vue (new)
|
|
236
|
+
├── composables/
|
|
237
|
+
│ ├── useElementLayout.ts (new)
|
|
238
|
+
│ ├── useElementGrid.ts (new)
|
|
239
|
+
│ ├── useElementSizing.ts (new)
|
|
240
|
+
│ ├── useElementSurface.ts (new)
|
|
241
|
+
│ └── useElementInteraction.ts (new)
|
|
242
|
+
└── types/
|
|
243
|
+
└── element.ts (new)
|
|
244
|
+
|
|
245
|
+
layers/core/app/composables/
|
|
246
|
+
└── useLayoutAttrs.ts (edit: add m/mx/my)
|
|
247
|
+
```
|
|
248
|
+
|
|
249
|
+
## §8 Testing
|
|
250
|
+
|
|
251
|
+
- Vitest unit tests per composable: static value, boolean layout-mode
|
|
252
|
+
precedence, grid container-axis (`cols`/`rows` number vs. string),
|
|
253
|
+
grid item-axis delegates correctly to `buildGridPlacementStyle`.
|
|
254
|
+
- `Element.vue` mount test: renders as native tag, renders as a passed
|
|
255
|
+
component (`:as="SomeComponent"`), style merge order (later group wins
|
|
256
|
+
on key collision — none expected, groups write disjoint CSS properties).
|
|
257
|
+
- Regression: `useLayoutAttrs`'s existing `HStack`/`VStack` consumers
|
|
258
|
+
unaffected by the `m`/`mx`/`my` addition (existing tests still pass).
|
|
259
|
+
- Manual: playground page exercising the source doc's grid/flex/sizing
|
|
260
|
+
examples, ported from the prototype's `pages/index.vue`.
|
|
261
|
+
|
|
262
|
+
## §9 Success criteria
|
|
263
|
+
|
|
264
|
+
1. `<Element as="section" grid :cols="12" gap="lg">` renders identically
|
|
265
|
+
in spirit to the prototype, but spacing/gap comes from the fluid token
|
|
266
|
+
scale, not raw CSS strings.
|
|
267
|
+
2. Item placement (`colSpan`/`colStart`) on `Element` produces the same
|
|
268
|
+
CSS as the equivalent `LayoutGridItem` usage — one engine, two entry
|
|
269
|
+
points.
|
|
270
|
+
3. Zero changes to `LayoutGridItem`, `gridPlacementStyle.ts`, or any file
|
|
271
|
+
the fluid-rebuild spec's territory covers.
|
|
272
|
+
4. `HStack`/`VStack` unaffected by the `useLayoutAttrs` margin addition.
|
|
273
|
+
5. No new semantic colour/token system introduced.
|
|
274
|
+
|
|
275
|
+
## §10 Amendment (2026-09-03, post-ship): relocated to `core`, item placement dropped
|
|
276
|
+
|
|
277
|
+
Shipped as designed above, in `layers/structure/layout`, then relocated the
|
|
278
|
+
same day. The stated intent was for `Element` to be usable across
|
|
279
|
+
essentially every layer to replace class-attribute soup generally — not a
|
|
280
|
+
layout-tier-only primitive. That breaks criterion 2 above: `layout` is a
|
|
281
|
+
tier-2 layer, and forcing every other layer (typography, visual, data,
|
|
282
|
+
motion, render, delivery — everything) to `extends: ['../layout']` just to
|
|
283
|
+
use `Element` is a far heavier dependency footprint than a shared-vocabulary
|
|
284
|
+
component should ask for.
|
|
285
|
+
|
|
286
|
+
**Resolution:** moved `Element` and its five composables
|
|
287
|
+
(`useElementLayout`/`useElementGrid`/`useElementSizing`/`useElementSurface`/
|
|
288
|
+
`useElementInteraction`) into `layers/core` (zero layer deps, already
|
|
289
|
+
extended by everything). This forced dropping `useElementGrid`'s item-axis
|
|
290
|
+
(`colStart`/`colSpan`/`rowStart`/`rowSpan`) support outright — that axis
|
|
291
|
+
delegated to `buildGridPlacementStyle`, which lives in `layout` and can't be
|
|
292
|
+
imported from `core` without inverting the dependency graph. `useElementGrid`
|
|
293
|
+
is now container-axis only (`grid`/`cols`/`rows` → `display: grid` +
|
|
294
|
+
`gridTemplateColumns`/`gridTemplateRows`). Item placement inside an
|
|
295
|
+
`Element`-built grid still works — just via `LayoutGridItem` directly, in
|
|
296
|
+
the `layout` layer, unchanged.
|
|
297
|
+
|
|
298
|
+
Superseded from §9: criterion 2 (item placement, no longer part of
|
|
299
|
+
`Element`) and criterion 3's `LayoutGridItem`/`gridPlacementStyle.ts`
|
|
300
|
+
clause (moot — `Element` no longer imports either). Criteria 1, 4, 5 still
|
|
301
|
+
hold. `Element.vue`'s duplicated `.gi-placed` CSS block (added during the
|
|
302
|
+
final-review fix wave, §8's ledger) was removed along with the item axis —
|
|
303
|
+
no longer needed.
|
|
304
|
+
|
|
305
|
+
File moves (git history preserved via `git mv`):
|
|
306
|
+
|
|
307
|
+
- `layers/structure/layout/app/components/Element.vue` → `layers/core/app/components/Element.vue`
|
|
308
|
+
- `layers/structure/layout/app/composables/useElement*.ts(.test.ts)` → `layers/core/app/composables/`
|
|
309
|
+
- `layers/structure/layout/app/types/element.ts` → `layers/core/app/types/element.ts`
|
|
310
|
+
- `@vue/test-utils` devDependency moved from `layout`'s `package.json` to `core`'s.
|
|
311
|
+
- The `#layers/core` vitest alias added for the old cross-layer import was removed (dead — `Element`'s imports are relative now that it lives in `core`).
|
|
312
|
+
|
|
313
|
+
## §11 Second amendment (2026-09-03, same day): moved again, to its own layer
|
|
314
|
+
|
|
315
|
+
Reconsidered §10's placement almost immediately: putting `Element` inside
|
|
316
|
+
`core` means core stops being pure foundation and starts carrying an
|
|
317
|
+
opinionated design-vocabulary component. The user's framing — `Element`
|
|
318
|
+
"provides containment," a distinct concern from core's browser/device/PWA
|
|
319
|
+
utilities — matches the tier taxonomy better than folding it into `core`.
|
|
320
|
+
|
|
321
|
+
**Resolution:** new layer, `layers/design-system/element/`, alongside
|
|
322
|
+
`theming`/`typography`/`visual` (same tier, same shape: one dependency,
|
|
323
|
+
`core`). This is _not_ a reversion to §7's original mistake (`layout`,
|
|
324
|
+
tier 2) — `element` depends only on `core`, so it costs every consuming
|
|
325
|
+
layer/app exactly one `extends` entry, same as `typography` or `visual`
|
|
326
|
+
already do. §10's core objection (§7's placement inverting the tier-2
|
|
327
|
+
`layout` → tier-0 `core` boundary if item-placement stayed) is unaffected —
|
|
328
|
+
`useElementGrid` is still container-axis only; nothing about this second
|
|
329
|
+
move reopens the dropped item-placement question.
|
|
330
|
+
|
|
331
|
+
Mechanically: `Element.vue`'s `useLayoutAttrs` import goes back to the
|
|
332
|
+
`#layers/core/...` alias (cross-layer again), and `types/element.ts`'s
|
|
333
|
+
`LayoutAttrsInput` import goes back to the four-level relative path (same
|
|
334
|
+
SFC-macro-can't-see-aliases reason as §7). The `#layers/core` vitest alias
|
|
335
|
+
removed in §10 is restored. New layer scaffolding: `nuxt.config.ts`
|
|
336
|
+
(`extends: ['../../core']`, matching `typography`'s exact shape),
|
|
337
|
+
`package.json` (`kmcom-layer-element`, `@vue/test-utils` devDependency
|
|
338
|
+
moved here from `core`). Registered in
|
|
339
|
+
`apps/playground/nuxt.config.ts`'s `AVAILABLE_LAYERS`/`LAYER_PATHS`/
|
|
340
|
+
`LAYER_DEPENDENCIES` (depends on `core` only, same as `typography`/`visual`).
|
|
341
|
+
`CLAUDE.md` and `.claude/rules/nuxt-layers.md` updated to list the new
|
|
342
|
+
layer and its `element → core` dependency-graph line.
|
|
@@ -0,0 +1,236 @@
|
|
|
1
|
+
# Grid layer — design
|
|
2
|
+
|
|
3
|
+
## Context
|
|
4
|
+
|
|
5
|
+
`layout` (Tier 2 — Structure) has carried a fixed 6/12/18-column "Swiss Grid
|
|
6
|
+
System" since its dissolution of the old `ui` layer. A forensic spec,
|
|
7
|
+
`LAYOUT-SYSTEM.md` (repo root), documents a different, single-mode fluid grid
|
|
8
|
+
derived entirely from `--fs` (font-size) — no fixed column count, columns
|
|
9
|
+
resolve via `repeat(auto-fill, minmax(...))`, and vertical rhythm derives from
|
|
10
|
+
`--unit: 1rlh`. A worktree, `layout-fluid-rebuild`, was mid-migration from the
|
|
11
|
+
Swiss system to that fluid system: it had already stripped `columns`,
|
|
12
|
+
`rowsPerSection`, and `presets` out of `layout`'s `app.config.ts`/
|
|
13
|
+
`types/layouts.ts` in favor of `tunables` (`measureMin`, `edgeMin`, `lpf`), but
|
|
14
|
+
had not yet touched the components that still assume 18 numbered columns
|
|
15
|
+
(`Section/Hero.vue`, `Section/Split.vue`, `Section/Gallery.vue`,
|
|
16
|
+
`Grid/Item.vue`).
|
|
17
|
+
|
|
18
|
+
Mid-migration, direction changed: a single imposed grid (whether Swiss or
|
|
19
|
+
fluid) is too rigid. The system should support **multiple layout patterns**
|
|
20
|
+
plus a way to build **arbitrary, unequal-width column compositions** (e.g. 8
|
|
21
|
+
equal columns + 1 double + 1 triple), plus an interactive tool for
|
|
22
|
+
constructing those compositions at dev time.
|
|
23
|
+
|
|
24
|
+
This spec covers a **new layer**, not changes to `layout`. `layout`'s
|
|
25
|
+
existing grid components (`LayoutMain`, `LayoutGridItem`, `LayoutSection`,
|
|
26
|
+
`Hero`, `Split`, `Gallery`, `useGridConfig`) are explicitly **out of scope**
|
|
27
|
+
and stay as they are — reworking them to consume this new layer is deferred
|
|
28
|
+
to a future pass. The `layout-fluid-rebuild` worktree's uncommitted
|
|
29
|
+
`app.config.ts`/`types/layouts.ts` changes are superseded by this spec and
|
|
30
|
+
should not be carried forward as-is; its rhythm math is the basis for what
|
|
31
|
+
this layer reimplements fresh.
|
|
32
|
+
|
|
33
|
+
## Governing idea
|
|
34
|
+
|
|
35
|
+
Two independent concerns, both configurable, neither hardcoded:
|
|
36
|
+
|
|
37
|
+
1. **Vertical rhythm** — derived from `--fs`, unconditional, the same for
|
|
38
|
+
every layout pattern (per `LAYOUT-SYSTEM.md`'s derivation chain).
|
|
39
|
+
2. **Column composition** — a named preset (`swiss`, `editorial`) or a
|
|
40
|
+
custom array of track segments, each optionally carrying CSS named grid
|
|
41
|
+
lines. This is the "grid builder" surface.
|
|
42
|
+
|
|
43
|
+
A layout pattern is data: an array of track segments. A preset is just a
|
|
44
|
+
named, pre-built instance of that same data shape. The interactive builder
|
|
45
|
+
produces that same shape. One representation, three ways to get one.
|
|
46
|
+
|
|
47
|
+
## New layer: `grid`
|
|
48
|
+
|
|
49
|
+
Tier 2 — Structure, sibling to `layout`/`navigation`/`routing`. Depends only
|
|
50
|
+
on `core`, same as `layout`.
|
|
51
|
+
|
|
52
|
+
```
|
|
53
|
+
layers/structure/grid/
|
|
54
|
+
├── app/
|
|
55
|
+
│ ├── assets/css/
|
|
56
|
+
│ │ └── grid.css # rhythm custom properties, .grid-root class
|
|
57
|
+
│ ├── composables/
|
|
58
|
+
│ │ └── useGridTracks.ts # preset lookup + custom-track → CSS string
|
|
59
|
+
│ ├── types/
|
|
60
|
+
│ │ └── tracks.ts # TrackSegment, TrackConfig, GridPreset types
|
|
61
|
+
│ └── app.config.ts # gridLayer.presets registry (swiss, editorial)
|
|
62
|
+
├── nuxt.config.ts # $meta.name: 'grid', extends core, alias #layers/grid
|
|
63
|
+
├── package.json # kmcom-layer-grid
|
|
64
|
+
└── CLAUDE.md
|
|
65
|
+
```
|
|
66
|
+
|
|
67
|
+
### Rhythm (`app/assets/css/grid.css`)
|
|
68
|
+
|
|
69
|
+
Reimplements `LAYOUT-SYSTEM.md`'s derivation as custom properties on
|
|
70
|
+
`.grid-root`:
|
|
71
|
+
|
|
72
|
+
```
|
|
73
|
+
--fs → line-height (rounded) → --unit: 1rlh
|
|
74
|
+
→ --edge-min, --measure-min
|
|
75
|
+
→ --lines, --lpf, --fields
|
|
76
|
+
→ padding-block, row height (--unit * --lpf floor)
|
|
77
|
+
```
|
|
78
|
+
|
|
79
|
+
Same constraints as the source doc, carried forward unconditionally:
|
|
80
|
+
|
|
81
|
+
- Every `clamp()` keeps a `rem` term (WCAG 1.4.4 zoom safety).
|
|
82
|
+
- `svh`/`svi`, never `dvh`/`vw`/`vh`.
|
|
83
|
+
- `rlh` not `lh`, so nested elements with different line-heights don't skew
|
|
84
|
+
the unit.
|
|
85
|
+
- `container-type` never on `body`.
|
|
86
|
+
|
|
87
|
+
This part is **not preset-dependent** — `swiss`, `editorial`, and any custom
|
|
88
|
+
track config all sit on the same rhythm.
|
|
89
|
+
|
|
90
|
+
### Track config shape (`app/types/tracks.ts`)
|
|
91
|
+
|
|
92
|
+
```ts
|
|
93
|
+
export type TrackSegment = {
|
|
94
|
+
/** Relative size, same unit as CSS `fr`. 1 = one equal column. */
|
|
95
|
+
size: number
|
|
96
|
+
/** Optional named line(s) at the start of this segment, e.g. 'feature-start'. */
|
|
97
|
+
lineStart?: string | string[]
|
|
98
|
+
/** Optional named line(s) at the end of this segment. */
|
|
99
|
+
lineEnd?: string | string[]
|
|
100
|
+
}
|
|
101
|
+
|
|
102
|
+
export type TrackConfig = {
|
|
103
|
+
columns: TrackSegment[]
|
|
104
|
+
/** Track floor — reuses --measure-min unless overridden. */
|
|
105
|
+
minTrackWidth?: string
|
|
106
|
+
}
|
|
107
|
+
|
|
108
|
+
export type GridPreset = TrackConfig & {
|
|
109
|
+
name: string
|
|
110
|
+
}
|
|
111
|
+
```
|
|
112
|
+
|
|
113
|
+
`8 equal + double + triple` is:
|
|
114
|
+
|
|
115
|
+
```ts
|
|
116
|
+
columns: [
|
|
117
|
+
{ size: 1 },
|
|
118
|
+
{ size: 1 },
|
|
119
|
+
{ size: 1 },
|
|
120
|
+
{ size: 1 },
|
|
121
|
+
{ size: 1 },
|
|
122
|
+
{ size: 1 },
|
|
123
|
+
{ size: 1 },
|
|
124
|
+
{ size: 2 },
|
|
125
|
+
{ size: 3 },
|
|
126
|
+
]
|
|
127
|
+
```
|
|
128
|
+
|
|
129
|
+
An editorial preset with named lines:
|
|
130
|
+
|
|
131
|
+
```ts
|
|
132
|
+
columns: [
|
|
133
|
+
{ size: 2, lineStart: 'feature-start', lineEnd: 'feature-end' },
|
|
134
|
+
{ size: 1, lineStart: 'aside-start', lineEnd: 'aside-end' },
|
|
135
|
+
]
|
|
136
|
+
```
|
|
137
|
+
|
|
138
|
+
### Presets (`app/app.config.ts`)
|
|
139
|
+
|
|
140
|
+
```ts
|
|
141
|
+
gridLayer: {
|
|
142
|
+
presets: {
|
|
143
|
+
swiss: { columns: [ /* 18 equal segments */ ] },
|
|
144
|
+
editorial: { columns: [ /* feature/aside as above */ ] },
|
|
145
|
+
}
|
|
146
|
+
}
|
|
147
|
+
```
|
|
148
|
+
|
|
149
|
+
Registry is data in `app.config.ts` (consuming apps can override/extend, same
|
|
150
|
+
pattern `layout` already uses for its own config), not hardcoded in the
|
|
151
|
+
composable.
|
|
152
|
+
|
|
153
|
+
### `useGridTracks()` composable
|
|
154
|
+
|
|
155
|
+
```ts
|
|
156
|
+
const { toColumnsCss, resolve } = useGridTracks()
|
|
157
|
+
|
|
158
|
+
resolve('swiss') // → GridPreset from app.config
|
|
159
|
+
resolve(customTrackConfig) // → passes a TrackConfig straight through
|
|
160
|
+
|
|
161
|
+
toColumnsCss(trackConfig)
|
|
162
|
+
// → 'minmax(min-content, [feature-start] 2fr [feature-end aside-start] 1fr [aside-end])'
|
|
163
|
+
```
|
|
164
|
+
|
|
165
|
+
`toColumnsCss` builds the `grid-template-columns` string: each segment's
|
|
166
|
+
`lineStart`/`lineEnd` become bracketed line names positioned around its `fr`
|
|
167
|
+
value, per standard named-grid-line syntax. Track width floor uses
|
|
168
|
+
`minTrackWidth` (defaults to `var(--measure-min)` from the rhythm CSS) via
|
|
169
|
+
`minmax()`, so narrow viewports still degrade to fewer effective columns —
|
|
170
|
+
same floor behavior as today's `auto-fill` approach, just applied per-segment
|
|
171
|
+
rather than to one repeated track.
|
|
172
|
+
|
|
173
|
+
### Placement — named lines primary, numeric fallback
|
|
174
|
+
|
|
175
|
+
No `LayoutGridItem`-equivalent component ships in this layer (that's
|
|
176
|
+
`layout`'s territory, deferred). What ships is the addressing convention and
|
|
177
|
+
a pure util others can build on:
|
|
178
|
+
|
|
179
|
+
```ts
|
|
180
|
+
export function placementFromLines(startLine: string, endLine: string): string
|
|
181
|
+
// → 'feature-start / aside-start'
|
|
182
|
+
|
|
183
|
+
export function placementFromIndex(colStart: number, colSpan: number | 'full'): string
|
|
184
|
+
// → numeric fallback for auto-flowing content (e.g. a future Gallery) that
|
|
185
|
+
// has no named slot to target
|
|
186
|
+
```
|
|
187
|
+
|
|
188
|
+
Named lines are primary because they propagate through CSS `subgrid`
|
|
189
|
+
correctly — `grid-template-areas` do not survive a subgrid boundary the same
|
|
190
|
+
way, and this codebase's existing grid components lean heavily on subgrid
|
|
191
|
+
for Section → Item inheritance. Numeric index/span stays available as a
|
|
192
|
+
fallback, unchanged in shape from what `layout`'s current `GridItem` already
|
|
193
|
+
exposes, so a future migration of those components is additive rather than a
|
|
194
|
+
rewrite of every prop.
|
|
195
|
+
|
|
196
|
+
### Visual builder (`apps/playground`)
|
|
197
|
+
|
|
198
|
+
A dev-only page, e.g. `/grid-builder`, in `apps/playground` (not shipped as
|
|
199
|
+
part of the `grid` layer itself — playground is a demo app that loads
|
|
200
|
+
layers, this doesn't need to be loadable by consuming apps):
|
|
201
|
+
|
|
202
|
+
- Form/drag UI to add, resize, and reorder `TrackSegment`s (count, relative
|
|
203
|
+
size, optional line names).
|
|
204
|
+
- Live preview: renders a `.grid-root` with the resulting
|
|
205
|
+
`grid-template-columns`, filled with placeholder cells so proportions are
|
|
206
|
+
visible immediately.
|
|
207
|
+
- Output panel: the resulting `TrackConfig` as copyable TS, so the result can
|
|
208
|
+
be pasted into `app.config.ts` as a new named preset or used inline.
|
|
209
|
+
- No persistence, no save-to-registry automation — copy/paste is the
|
|
210
|
+
hand-off, matching the "dev-time tool in playground, emits config" scope
|
|
211
|
+
agreed earlier.
|
|
212
|
+
|
|
213
|
+
## Testing
|
|
214
|
+
|
|
215
|
+
- `useGridTracks.test.ts` — `toColumnsCss` produces correct line-name
|
|
216
|
+
bracket placement for: equal segments, mixed sizes, segments with only
|
|
217
|
+
`lineStart`, segments with both. `resolve()` returns registry presets and
|
|
218
|
+
passes through custom configs unchanged.
|
|
219
|
+
- `placement.test.ts` — `placementFromLines`/`placementFromIndex` produce
|
|
220
|
+
the expected `grid-column` value strings, including the `'full'` numeric
|
|
221
|
+
case.
|
|
222
|
+
- No component tests — no Vue component ships in this phase besides the
|
|
223
|
+
playground builder page, which is verified visually (render the three
|
|
224
|
+
known shapes — swiss, editorial, one ad hoc custom config from the builder
|
|
225
|
+
itself — and confirm proportions match what was configured).
|
|
226
|
+
|
|
227
|
+
## Out of scope
|
|
228
|
+
|
|
229
|
+
- Reworking `layout`'s `LayoutMain`/`LayoutGridItem`/`Section`/`Hero`/
|
|
230
|
+
`Split`/`Gallery` to consume this layer's tracks/rhythm. Noted as a known
|
|
231
|
+
follow-up; not part of this spec or its implementation plan.
|
|
232
|
+
- Row-track presets beyond the rhythm-derived floor (`--unit * --lpf`) —
|
|
233
|
+
only column composition is preset/builder-driven in this phase.
|
|
234
|
+
- Saving builder output directly into the preset registry from the UI.
|
|
235
|
+
- A Bento-grid preset (mixed row+column spans) — deferred; only `swiss` and
|
|
236
|
+
`editorial` ship initially, matching the two selected patterns.
|
|
@@ -1,9 +1,17 @@
|
|
|
1
|
-
|
|
1
|
+
import type { ContentLayerConfig } from './types/content'
|
|
2
|
+
|
|
3
|
+
export default defineAppConfig({
|
|
2
4
|
contentLayer: {
|
|
3
5
|
sections: {
|
|
4
6
|
blog: true,
|
|
5
7
|
portfolio: true,
|
|
6
8
|
gallery: true,
|
|
7
9
|
},
|
|
8
|
-
},
|
|
10
|
+
} satisfies ContentLayerConfig,
|
|
11
|
+
})
|
|
12
|
+
|
|
13
|
+
declare module '@nuxt/schema' {
|
|
14
|
+
interface AppConfigInput {
|
|
15
|
+
contentLayer?: ContentLayerConfig
|
|
16
|
+
}
|
|
9
17
|
}
|
|
@@ -0,0 +1,21 @@
|
|
|
1
|
+
<script setup lang="ts">
|
|
2
|
+
import type { ContentLayerConfig } from '#layers/content/app/types/content'
|
|
3
|
+
|
|
4
|
+
const { slug } = defineProps<{
|
|
5
|
+
slug: string
|
|
6
|
+
}>()
|
|
7
|
+
|
|
8
|
+
const appConfig = useAppConfig()
|
|
9
|
+
const contentLayer = appConfig.contentLayer as ContentLayerConfig | undefined
|
|
10
|
+
if (contentLayer?.sections?.blog === false) {
|
|
11
|
+
throw createError({ statusCode: 404, statusMessage: 'Not Found' })
|
|
12
|
+
}
|
|
13
|
+
</script>
|
|
14
|
+
|
|
15
|
+
<template>
|
|
16
|
+
<LayoutSection>
|
|
17
|
+
<LayoutGridItem>
|
|
18
|
+
<BlogArticle :slug />
|
|
19
|
+
</LayoutGridItem>
|
|
20
|
+
</LayoutSection>
|
|
21
|
+
</template>
|
|
@@ -0,0 +1,25 @@
|
|
|
1
|
+
<script setup lang="ts">
|
|
2
|
+
import type { ContentLayerConfig } from '#layers/content/app/types/content'
|
|
3
|
+
|
|
4
|
+
const appConfig = useAppConfig()
|
|
5
|
+
const contentLayer = appConfig.contentLayer as ContentLayerConfig | undefined
|
|
6
|
+
if (contentLayer?.sections?.blog === false) {
|
|
7
|
+
throw createError({ statusCode: 404, statusMessage: 'Not Found' })
|
|
8
|
+
}
|
|
9
|
+
|
|
10
|
+
useSeoMeta({
|
|
11
|
+
title: 'Blog',
|
|
12
|
+
description: 'Articles and posts',
|
|
13
|
+
})
|
|
14
|
+
</script>
|
|
15
|
+
|
|
16
|
+
<template>
|
|
17
|
+
<LayoutSection>
|
|
18
|
+
<LayoutGridItem>
|
|
19
|
+
<UPageHeader title="Blog" description="Articles and posts" />
|
|
20
|
+
<UPageBody>
|
|
21
|
+
<BlogList />
|
|
22
|
+
</UPageBody>
|
|
23
|
+
</LayoutGridItem>
|
|
24
|
+
</LayoutSection>
|
|
25
|
+
</template>
|
|
@@ -1,9 +1,13 @@
|
|
|
1
1
|
<script setup lang="ts">
|
|
2
|
+
import type { ContentLayerConfig } from '#layers/content/app/types/content'
|
|
3
|
+
|
|
2
4
|
const { slug, index } = defineProps<{
|
|
3
5
|
slug: string
|
|
4
6
|
index: number
|
|
5
7
|
}>()
|
|
6
|
-
|
|
8
|
+
|
|
9
|
+
const appConfig = useAppConfig()
|
|
10
|
+
const contentLayer = appConfig.contentLayer as ContentLayerConfig | undefined
|
|
7
11
|
if (contentLayer?.sections?.gallery === false) {
|
|
8
12
|
throw createError({ statusCode: 404, statusMessage: 'Not Found' })
|
|
9
13
|
}
|
|
@@ -1,5 +1,8 @@
|
|
|
1
1
|
<script setup lang="ts">
|
|
2
|
-
|
|
2
|
+
import type { ContentLayerConfig } from '#layers/content/app/types/content'
|
|
3
|
+
|
|
4
|
+
const appConfig = useAppConfig()
|
|
5
|
+
const contentLayer = appConfig.contentLayer as ContentLayerConfig | undefined
|
|
3
6
|
if (contentLayer?.sections?.gallery === false) {
|
|
4
7
|
throw createError({ statusCode: 404, statusMessage: 'Not Found' })
|
|
5
8
|
}
|