@janga/norna 0.7.9 → 0.7.11
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/README.md +4 -2
- package/bin/norna-cli.mjs +3 -0
- package/docs/README.md +16 -12
- package/docs/commands.md +6 -0
- package/docs/configuration.md +10 -54
- package/docs/content.md +20 -21
- package/docs/design/norna-diagram-design.md +2 -0
- package/docs/design/site-examples-structure.md +35 -24
- package/docs/engine-development.md +13 -7
- package/docs/getting-started.md +56 -19
- package/docs/routes.md +8 -6
- package/docs/site-structure.md +11 -6
- package/docs/sitewide-content.md +74 -0
- package/docs/theme.md +125 -140
- package/docs/typography.md +72 -45
- package/examples/README.md +41 -0
- package/examples/complete-sites/dog-shelter-multi-page/.astro/collections/site.schema.json +59 -0
- package/examples/complete-sites/dog-shelter-multi-page/.astro/collections/sitewide.schema.json +138 -0
- package/examples/complete-sites/dog-shelter-multi-page/.astro/collections/theme.schema.json +755 -0
- package/examples/complete-sites/dog-shelter-multi-page/.astro/content-modules.mjs +1 -0
- package/examples/{typography-presets → complete-sites/dog-shelter-multi-page}/.astro/content.d.ts +8 -0
- package/examples/complete-sites/dog-shelter-multi-page/.astro/data-store.json +1 -0
- package/examples/{typography-presets → complete-sites/dog-shelter-multi-page}/.astro/dev-local.json +2 -2
- package/examples/{typography-presets → complete-sites/dog-shelter-multi-page}/.astro/dev.json +2 -2
- package/examples/complete-sites/dog-shelter-multi-page/.astro/dev.log +53 -0
- package/examples/complete-sites/dog-shelter-multi-page/.astro/settings.json +5 -0
- package/examples/complete-sites/dog-shelter-multi-page/README.md +9 -0
- package/examples/{dog-gallery → complete-sites/dog-shelter-multi-page}/node_modules/.vite/deps/_metadata.json +13 -7
- package/examples/complete-sites/dog-shelter-multi-page/site/.norna/generated-images.json +18 -0
- package/examples/complete-sites/dog-shelter-multi-page/site/config.mjs +30 -0
- package/examples/complete-sites/dog-shelter-multi-page/site/content.md +12 -0
- package/examples/complete-sites/dog-shelter-multi-page/site/public/favicon.svg +10 -0
- package/examples/complete-sites/dog-shelter-multi-page/site/routes/010-dogs/images/dogs/rex.svg +19 -0
- package/examples/complete-sites/dog-shelter-multi-page/site/routes/010-dogs/images/dogs/rover.svg +19 -0
- package/examples/complete-sites/dog-shelter-multi-page/site/routes/010-dogs/route-content.md +30 -0
- package/examples/complete-sites/dog-shelter-multi-page/site/routes/020-adopt/route-content.md +12 -0
- package/examples/complete-sites/dog-shelter-multi-page/site/sitewide-content.md +6 -0
- package/examples/complete-sites/dog-shelter-multi-page/site/theme.md +25 -0
- package/examples/complete-sites/dog-shelter-single-page/README.md +9 -0
- package/examples/complete-sites/dog-shelter-single-page/site/.norna/generated-images.json +18 -0
- package/examples/complete-sites/dog-shelter-single-page/site/config.mjs +30 -0
- package/examples/complete-sites/dog-shelter-single-page/site/content.md +38 -0
- package/examples/complete-sites/dog-shelter-single-page/site/images/what-we-do/dog-house.svg +25 -0
- package/examples/complete-sites/dog-shelter-single-page/site/images/you-can-help/heart.svg +13 -0
- package/examples/complete-sites/dog-shelter-single-page/site/public/favicon.svg +10 -0
- package/examples/complete-sites/dog-shelter-single-page/site/public/robots.txt +2 -0
- package/examples/complete-sites/dog-shelter-single-page/site/sitewide-content.md +6 -0
- package/examples/complete-sites/dog-shelter-single-page/site/theme.md +25 -0
- package/examples/feature-demos/media-and-surfaces/.astro/collections/site.schema.json +59 -0
- package/examples/feature-demos/media-and-surfaces/.astro/collections/sitewide.schema.json +138 -0
- package/examples/feature-demos/media-and-surfaces/.astro/collections/theme.schema.json +755 -0
- package/examples/feature-demos/media-and-surfaces/.astro/content-modules.mjs +1 -0
- package/examples/feature-demos/media-and-surfaces/.astro/content.d.ts +183 -0
- package/examples/feature-demos/media-and-surfaces/.astro/data-store.json +1 -0
- package/examples/feature-demos/media-and-surfaces/.astro/dev.log +11 -0
- package/examples/feature-demos/media-and-surfaces/.astro/settings.json +5 -0
- package/examples/feature-demos/media-and-surfaces/.astro/types.d.ts +2 -0
- package/examples/feature-demos/media-and-surfaces/README.md +15 -0
- package/examples/feature-demos/media-and-surfaces/node_modules/.vite/deps/_metadata.json +74 -0
- package/examples/feature-demos/media-and-surfaces/node_modules/.vite/deps/astro-B3JHJyiv.js +434 -0
- package/examples/feature-demos/media-and-surfaces/node_modules/.vite/deps/astro-B3JHJyiv.js.map +1 -0
- package/examples/feature-demos/media-and-surfaces/node_modules/.vite/deps/astro_n_aria-query.js +6390 -0
- package/examples/feature-demos/media-and-surfaces/node_modules/.vite/deps/astro_n_aria-query.js.map +1 -0
- package/examples/feature-demos/media-and-surfaces/node_modules/.vite/deps/astro_n_axobject-query.js +2702 -0
- package/examples/feature-demos/media-and-surfaces/node_modules/.vite/deps/astro_n_axobject-query.js.map +1 -0
- package/examples/feature-demos/media-and-surfaces/node_modules/.vite/deps/astro_n_html-escaper.js +65 -0
- package/examples/feature-demos/media-and-surfaces/node_modules/.vite/deps/astro_n_html-escaper.js.map +1 -0
- package/examples/feature-demos/media-and-surfaces/node_modules/.vite/deps/astro_runtime_client_dev-toolbar_entrypoint__js.js +455 -0
- package/examples/feature-demos/media-and-surfaces/node_modules/.vite/deps/astro_runtime_client_dev-toolbar_entrypoint__js.js.map +1 -0
- package/examples/feature-demos/media-and-surfaces/node_modules/.vite/deps/audit-C3SVr7dT.js +1534 -0
- package/examples/feature-demos/media-and-surfaces/node_modules/.vite/deps/audit-C3SVr7dT.js.map +1 -0
- package/examples/feature-demos/media-and-surfaces/node_modules/.vite/deps/highlight-BLtvqtzO.js +48 -0
- package/examples/feature-demos/media-and-surfaces/node_modules/.vite/deps/highlight-BLtvqtzO.js.map +1 -0
- package/examples/feature-demos/media-and-surfaces/node_modules/.vite/deps/icons-C92i61-2.js +42 -0
- package/examples/feature-demos/media-and-surfaces/node_modules/.vite/deps/icons-C92i61-2.js.map +1 -0
- package/examples/feature-demos/media-and-surfaces/node_modules/.vite/deps/settings-v5GgKks_.js +190 -0
- package/examples/feature-demos/media-and-surfaces/node_modules/.vite/deps/settings-v5GgKks_.js.map +1 -0
- package/examples/feature-demos/media-and-surfaces/node_modules/.vite/deps/toolbar-BFvJVp26.js +458 -0
- package/examples/feature-demos/media-and-surfaces/node_modules/.vite/deps/toolbar-BFvJVp26.js.map +1 -0
- package/examples/feature-demos/media-and-surfaces/node_modules/.vite/deps/ui-library-Cd35oAvo.js +1016 -0
- package/examples/feature-demos/media-and-surfaces/node_modules/.vite/deps/ui-library-Cd35oAvo.js.map +1 -0
- package/examples/feature-demos/media-and-surfaces/node_modules/.vite/deps/window-vo3A6TMn.js +32 -0
- package/examples/feature-demos/media-and-surfaces/node_modules/.vite/deps/window-vo3A6TMn.js.map +1 -0
- package/examples/feature-demos/media-and-surfaces/node_modules/.vite/deps/xray-DwhzGckb.js +111 -0
- package/examples/feature-demos/media-and-surfaces/node_modules/.vite/deps/xray-DwhzGckb.js.map +1 -0
- package/examples/feature-demos/media-and-surfaces/site/.norna/generated-images.json +66 -0
- package/examples/feature-demos/media-and-surfaces/site/config.mjs +30 -0
- package/examples/feature-demos/media-and-surfaces/site/content.md +64 -0
- package/examples/feature-demos/media-and-surfaces/site/public/robots.txt +2 -0
- package/examples/feature-demos/media-and-surfaces/site/routes/010-media/images/cards/card-carousel.svg +11 -0
- package/examples/feature-demos/media-and-surfaces/site/routes/010-media/images/cards/card-stack.svg +9 -0
- package/examples/feature-demos/media-and-surfaces/site/routes/010-media/images/cards/card-surfaces.svg +8 -0
- package/examples/feature-demos/media-and-surfaces/site/routes/010-media/images/carousel/carousel-one.svg +8 -0
- package/examples/feature-demos/media-and-surfaces/site/routes/010-media/images/carousel/carousel-three.svg +13 -0
- package/examples/feature-demos/media-and-surfaces/site/routes/010-media/images/carousel/carousel-two.svg +8 -0
- package/examples/feature-demos/media-and-surfaces/site/routes/010-media/images/stack/stack-one.svg +8 -0
- package/examples/feature-demos/media-and-surfaces/site/routes/010-media/images/stack/stack-two.svg +9 -0
- package/examples/feature-demos/media-and-surfaces/site/routes/010-media/route-content.md +85 -0
- package/examples/feature-demos/media-and-surfaces/site/routes/010-media/theme.md +3 -0
- package/examples/feature-demos/media-and-surfaces/site/routes/020-surfaces/route-content.md +44 -0
- package/examples/feature-demos/media-and-surfaces/site/routes/020-surfaces/theme.md +8 -0
- package/examples/feature-demos/media-and-surfaces/site/sitewide-content.md +6 -0
- package/examples/feature-demos/media-and-surfaces/site/theme.md +3 -0
- package/examples/{typography-presets/.astro/collections/theme.schema.json → feature-demos/theme-presets/.astro/collections/routeTheme.schema.json} +143 -65
- package/examples/feature-demos/theme-presets/.astro/collections/site.schema.json +59 -0
- package/examples/feature-demos/theme-presets/.astro/collections/sitewide.schema.json +138 -0
- package/examples/feature-demos/theme-presets/.astro/collections/theme.schema.json +755 -0
- package/examples/feature-demos/theme-presets/.astro/content-assets.mjs +4 -0
- package/examples/feature-demos/theme-presets/.astro/content-modules.mjs +1 -0
- package/examples/feature-demos/theme-presets/.astro/content.d.ts +183 -0
- package/examples/feature-demos/theme-presets/.astro/data-store.json +1 -0
- package/examples/feature-demos/theme-presets/.astro/dev-local.json +8 -0
- package/examples/feature-demos/theme-presets/.astro/dev.json +15 -0
- package/examples/feature-demos/theme-presets/.astro/dev.log +127 -0
- package/examples/feature-demos/theme-presets/.astro/types.d.ts +2 -0
- package/examples/feature-demos/theme-presets/README.md +14 -0
- package/examples/feature-demos/theme-presets/node_modules/.vite/deps/embla-carousel.js +1389 -0
- package/examples/feature-demos/theme-presets/node_modules/.vite/deps/embla-carousel.js.map +1 -0
- package/examples/feature-demos/theme-presets/node_modules/.vite/deps/package.json +3 -0
- package/examples/feature-demos/theme-presets/node_modules/.vite/deps/rolldown-runtime-BvCyGRYZ.js +4 -0
- package/examples/feature-demos/theme-presets/site/.norna/generated-images.json +290 -0
- package/examples/{typography-presets → feature-demos/theme-presets}/site/config.mjs +4 -16
- package/examples/feature-demos/theme-presets/site/content.md +17 -0
- package/examples/feature-demos/theme-presets/site/routes/010-portfolio/route-content.md +34 -0
- package/examples/feature-demos/theme-presets/site/routes/010-portfolio/theme.md +3 -0
- package/examples/feature-demos/theme-presets/site/routes/020-documentation/route-content.md +33 -0
- package/examples/feature-demos/theme-presets/site/routes/020-documentation/theme.md +3 -0
- package/examples/feature-demos/theme-presets/site/routes/030-project/route-content.md +34 -0
- package/examples/feature-demos/theme-presets/site/routes/030-project/theme.md +3 -0
- package/examples/feature-demos/theme-presets/site/routes/040-statement/route-content.md +34 -0
- package/examples/feature-demos/theme-presets/site/routes/040-statement/theme.md +3 -0
- package/examples/feature-demos/theme-presets/site/sitewide-content.md +14 -0
- package/examples/feature-demos/theme-presets/site/theme.md +3 -0
- package/fixtures/basic/site/config.mjs +0 -13
- package/fixtures/basic/site/sitewide-content.md +12 -0
- package/fixtures/basic/site/theme.md +2 -2
- package/fixtures/content-model-v2/site/content.md +2 -5
- package/fixtures/content-model-v2/site/theme.md +1 -3
- package/package.json +9 -4
- package/scripts/build-pages.mjs +71 -0
- package/scripts/check-config.mjs +23 -1
- package/scripts/export-theme-preset.mjs +31 -0
- package/scripts/init-site.mjs +1 -0
- package/scripts/lib/example-sites.mjs +34 -0
- package/scripts/lib/frontmatter-yaml.mjs +28 -0
- package/scripts/lib/logo-assets.mjs +35 -0
- package/scripts/lib/norna-markdown-blocks.mjs +166 -0
- package/scripts/lib/presentation.mjs +106 -47
- package/scripts/lib/project-config.mjs +68 -105
- package/scripts/lib/site-content.mjs +26 -118
- package/scripts/lib/site-paths.mjs +2 -0
- package/scripts/lib/sitewide-config.mjs +34 -0
- package/scripts/lib/theme-config.mjs +75 -8
- package/scripts/lib/theme-presets.mjs +209 -0
- package/scripts/lib/typography.mjs +20 -26
- package/scripts/show-typography.mjs +43 -149
- package/scripts/sync-content-sections.mjs +19 -17
- package/scripts/test-content-check.mjs +59 -27
- package/scripts/test-content-model-v2.mjs +154 -0
- package/scripts/test-engine-commands.mjs +4 -1
- package/scripts/test-examples.mjs +15 -0
- package/scripts/test-navigation.mjs +73 -45
- package/scripts/test-package-check.mjs +66 -24
- package/scripts/test-temporary-visibility.mjs +19 -2
- package/scripts/test-theme-presets.mjs +151 -0
- package/src/components/CardList.astro +5 -2
- package/src/components/GalleryGrid.astro +37 -16
- package/src/components/SiteBanners.astro +100 -0
- package/src/components/SiteNavigation.astro +48 -31
- package/src/components/SitePage.astro +55 -13
- package/src/components/SiteSection.astro +193 -35
- package/src/content.config.ts +80 -48
- package/src/layouts/BaseLayout.astro +64 -14
- package/src/lib/routeThemes.ts +61 -0
- package/src/lib/sectionContent.ts +235 -51
- package/src/lib/sitePublicAssets.ts +1 -0
- package/src/styles/global.css +284 -93
- package/starters/basic/.github/workflows/deploy.yml +1 -1
- package/starters/basic/README.md +7 -6
- package/starters/basic/package.json +1 -0
- package/starters/basic/site/config.mjs +0 -13
- package/starters/basic/site/content.md +1 -1
- package/starters/basic/site/sitewide-content.md +14 -0
- package/starters/basic/site/theme.md +13 -24
- package/starters/project/.github/workflows/deploy.yml +1 -1
- package/starters/project/README.md +10 -8
- package/starters/project/package.json +1 -0
- package/starters/project/site/config.mjs +0 -13
- package/starters/project/site/sitewide-content.md +14 -0
- package/starters/project/site/theme.md +3 -11
- package/examples/dog-gallery/site/.norna/generated-images.json +0 -226
- package/examples/dog-gallery/site/config.mjs +0 -67
- package/examples/dog-gallery/site/content.md +0 -128
- package/examples/dog-gallery/site/images/black-dogs/black-puppy-meadow.png +0 -0
- package/examples/dog-gallery/site/images/black-dogs/photo-of-a-black-dog.jpg +0 -0
- package/examples/dog-gallery/site/images/brown-dogs/brown-dog.jpg +0 -0
- package/examples/dog-gallery/site/images/brown-dogs/dog-accompanies-master.jpg +0 -0
- package/examples/dog-gallery/site/images/golden-dogs/golden-retriever.jpg +0 -0
- package/examples/dog-gallery/site/images/golden-dogs/toller-puppy.jpg +0 -0
- package/examples/dog-gallery/site/images/white-dogs/white-cute-dog.jpg +0 -0
- package/examples/dog-gallery/site/images/white-dogs/white-puppy-garden.png +0 -0
- package/examples/dog-gallery/site/public/favicon.svg +0 -7
- package/examples/dog-gallery/site/routes/010-dog-care/route-content.md +0 -38
- package/examples/dog-gallery/site/theme.md +0 -112
- package/examples/typography-presets/.astro/collections/site.schema.json +0 -776
- package/examples/typography-presets/.astro/data-store.json +0 -1
- package/examples/typography-presets/.astro/dev.log +0 -24
- package/examples/typography-presets/site/.norna/generated-images.json +0 -290
- package/examples/typography-presets/site/content.md +0 -134
- package/examples/typography-presets/site/theme.md +0 -43
- /package/examples/{typography-presets/.astro/content-modules.mjs → complete-sites/dog-shelter-multi-page/.astro/content-assets.mjs} +0 -0
- /package/examples/{typography-presets → complete-sites/dog-shelter-multi-page}/.astro/types.d.ts +0 -0
- /package/examples/{dog-gallery → complete-sites/dog-shelter-multi-page}/node_modules/.vite/deps/astro-D_GIpJIE.js +0 -0
- /package/examples/{dog-gallery → complete-sites/dog-shelter-multi-page}/node_modules/.vite/deps/astro-D_GIpJIE.js.map +0 -0
- /package/examples/{dog-gallery → complete-sites/dog-shelter-multi-page}/node_modules/.vite/deps/astro_n_aria-query.js +0 -0
- /package/examples/{dog-gallery → complete-sites/dog-shelter-multi-page}/node_modules/.vite/deps/astro_n_aria-query.js.map +0 -0
- /package/examples/{dog-gallery → complete-sites/dog-shelter-multi-page}/node_modules/.vite/deps/astro_n_axobject-query.js +0 -0
- /package/examples/{dog-gallery → complete-sites/dog-shelter-multi-page}/node_modules/.vite/deps/astro_n_axobject-query.js.map +0 -0
- /package/examples/{dog-gallery → complete-sites/dog-shelter-multi-page}/node_modules/.vite/deps/astro_n_html-escaper.js +0 -0
- /package/examples/{dog-gallery → complete-sites/dog-shelter-multi-page}/node_modules/.vite/deps/astro_n_html-escaper.js.map +0 -0
- /package/examples/{dog-gallery → complete-sites/dog-shelter-multi-page}/node_modules/.vite/deps/astro_runtime_client_dev-toolbar_entrypoint__js.js +0 -0
- /package/examples/{dog-gallery → complete-sites/dog-shelter-multi-page}/node_modules/.vite/deps/astro_runtime_client_dev-toolbar_entrypoint__js.js.map +0 -0
- /package/examples/{dog-gallery → complete-sites/dog-shelter-multi-page}/node_modules/.vite/deps/audit-DM9Hkl5B.js +0 -0
- /package/examples/{dog-gallery → complete-sites/dog-shelter-multi-page}/node_modules/.vite/deps/audit-DM9Hkl5B.js.map +0 -0
- /package/examples/{typography-presets → complete-sites/dog-shelter-multi-page}/node_modules/.vite/deps/embla-carousel.js +0 -0
- /package/examples/{typography-presets → complete-sites/dog-shelter-multi-page}/node_modules/.vite/deps/embla-carousel.js.map +0 -0
- /package/examples/{dog-gallery → complete-sites/dog-shelter-multi-page}/node_modules/.vite/deps/highlight-DnZ1ULOL.js +0 -0
- /package/examples/{dog-gallery → complete-sites/dog-shelter-multi-page}/node_modules/.vite/deps/highlight-DnZ1ULOL.js.map +0 -0
- /package/examples/{dog-gallery → complete-sites/dog-shelter-multi-page}/node_modules/.vite/deps/icons-RyebKi45.js +0 -0
- /package/examples/{dog-gallery → complete-sites/dog-shelter-multi-page}/node_modules/.vite/deps/icons-RyebKi45.js.map +0 -0
- /package/examples/{dog-gallery → complete-sites/dog-shelter-multi-page}/node_modules/.vite/deps/package.json +0 -0
- /package/examples/{dog-gallery → complete-sites/dog-shelter-multi-page}/node_modules/.vite/deps/rolldown-runtime-BvCyGRYZ.js +0 -0
- /package/examples/{dog-gallery → complete-sites/dog-shelter-multi-page}/node_modules/.vite/deps/settings-DaU-gNnK.js +0 -0
- /package/examples/{dog-gallery → complete-sites/dog-shelter-multi-page}/node_modules/.vite/deps/settings-DaU-gNnK.js.map +0 -0
- /package/examples/{dog-gallery → complete-sites/dog-shelter-multi-page}/node_modules/.vite/deps/toolbar-63PA619H.js +0 -0
- /package/examples/{dog-gallery → complete-sites/dog-shelter-multi-page}/node_modules/.vite/deps/toolbar-63PA619H.js.map +0 -0
- /package/examples/{dog-gallery → complete-sites/dog-shelter-multi-page}/node_modules/.vite/deps/ui-library--bkcNSYz.js +0 -0
- /package/examples/{dog-gallery → complete-sites/dog-shelter-multi-page}/node_modules/.vite/deps/ui-library--bkcNSYz.js.map +0 -0
- /package/examples/{dog-gallery → complete-sites/dog-shelter-multi-page}/node_modules/.vite/deps/window-jPkpKVcy.js +0 -0
- /package/examples/{dog-gallery → complete-sites/dog-shelter-multi-page}/node_modules/.vite/deps/window-jPkpKVcy.js.map +0 -0
- /package/examples/{dog-gallery → complete-sites/dog-shelter-multi-page}/node_modules/.vite/deps/xray-BXCHpEJP.js +0 -0
- /package/examples/{dog-gallery → complete-sites/dog-shelter-multi-page}/node_modules/.vite/deps/xray-BXCHpEJP.js.map +0 -0
- /package/examples/{dog-gallery → complete-sites/dog-shelter-multi-page}/site/public/robots.txt +0 -0
- /package/examples/{typography-presets → feature-demos/media-and-surfaces}/.astro/content-assets.mjs +0 -0
- /package/examples/{typography-presets → feature-demos/media-and-surfaces}/node_modules/.vite/deps/package.json +0 -0
- /package/examples/{typography-presets → feature-demos/media-and-surfaces}/node_modules/.vite/deps/rolldown-runtime-BvCyGRYZ.js +0 -0
- /package/examples/{typography-presets → feature-demos/theme-presets}/.astro/settings.json +0 -0
- /package/examples/{typography-presets → feature-demos/theme-presets}/node_modules/.vite/deps/_metadata.json +0 -0
- /package/examples/{typography-presets → feature-demos/theme-presets}/node_modules/.vite/deps/astro-D_GIpJIE.js +0 -0
- /package/examples/{typography-presets → feature-demos/theme-presets}/node_modules/.vite/deps/astro-D_GIpJIE.js.map +0 -0
- /package/examples/{typography-presets → feature-demos/theme-presets}/node_modules/.vite/deps/astro_n_aria-query.js +0 -0
- /package/examples/{typography-presets → feature-demos/theme-presets}/node_modules/.vite/deps/astro_n_aria-query.js.map +0 -0
- /package/examples/{typography-presets → feature-demos/theme-presets}/node_modules/.vite/deps/astro_n_axobject-query.js +0 -0
- /package/examples/{typography-presets → feature-demos/theme-presets}/node_modules/.vite/deps/astro_n_axobject-query.js.map +0 -0
- /package/examples/{typography-presets → feature-demos/theme-presets}/node_modules/.vite/deps/astro_n_html-escaper.js +0 -0
- /package/examples/{typography-presets → feature-demos/theme-presets}/node_modules/.vite/deps/astro_n_html-escaper.js.map +0 -0
- /package/examples/{typography-presets → feature-demos/theme-presets}/node_modules/.vite/deps/astro_runtime_client_dev-toolbar_entrypoint__js.js +0 -0
- /package/examples/{typography-presets → feature-demos/theme-presets}/node_modules/.vite/deps/astro_runtime_client_dev-toolbar_entrypoint__js.js.map +0 -0
- /package/examples/{typography-presets → feature-demos/theme-presets}/node_modules/.vite/deps/audit-DM9Hkl5B.js +0 -0
- /package/examples/{typography-presets → feature-demos/theme-presets}/node_modules/.vite/deps/audit-DM9Hkl5B.js.map +0 -0
- /package/examples/{typography-presets → feature-demos/theme-presets}/node_modules/.vite/deps/highlight-DnZ1ULOL.js +0 -0
- /package/examples/{typography-presets → feature-demos/theme-presets}/node_modules/.vite/deps/highlight-DnZ1ULOL.js.map +0 -0
- /package/examples/{typography-presets → feature-demos/theme-presets}/node_modules/.vite/deps/icons-RyebKi45.js +0 -0
- /package/examples/{typography-presets → feature-demos/theme-presets}/node_modules/.vite/deps/icons-RyebKi45.js.map +0 -0
- /package/examples/{typography-presets → feature-demos/theme-presets}/node_modules/.vite/deps/settings-DaU-gNnK.js +0 -0
- /package/examples/{typography-presets → feature-demos/theme-presets}/node_modules/.vite/deps/settings-DaU-gNnK.js.map +0 -0
- /package/examples/{typography-presets → feature-demos/theme-presets}/node_modules/.vite/deps/toolbar-63PA619H.js +0 -0
- /package/examples/{typography-presets → feature-demos/theme-presets}/node_modules/.vite/deps/toolbar-63PA619H.js.map +0 -0
- /package/examples/{typography-presets → feature-demos/theme-presets}/node_modules/.vite/deps/ui-library--bkcNSYz.js +0 -0
- /package/examples/{typography-presets → feature-demos/theme-presets}/node_modules/.vite/deps/ui-library--bkcNSYz.js.map +0 -0
- /package/examples/{typography-presets → feature-demos/theme-presets}/node_modules/.vite/deps/window-jPkpKVcy.js +0 -0
- /package/examples/{typography-presets → feature-demos/theme-presets}/node_modules/.vite/deps/window-jPkpKVcy.js.map +0 -0
- /package/examples/{typography-presets → feature-demos/theme-presets}/node_modules/.vite/deps/xray-BXCHpEJP.js +0 -0
- /package/examples/{typography-presets → feature-demos/theme-presets}/node_modules/.vite/deps/xray-BXCHpEJP.js.map +0 -0
- /package/examples/{typography-presets → feature-demos/theme-presets}/site/public/robots.txt +0 -0
- /package/examples/{typography-presets/site/images/quiet-gallery → feature-demos/theme-presets/site/routes/010-portfolio/images/portfolio}/puppy-portrait.jpg +0 -0
- /package/examples/{typography-presets/site/images/quiet-gallery → feature-demos/theme-presets/site/routes/010-portfolio/images/portfolio}/shepherd-portrait.jpg +0 -0
- /package/examples/{typography-presets/site/images/quiet-gallery → feature-demos/theme-presets/site/routes/010-portfolio/images/portfolio}/white-puppy.jpg +0 -0
- /package/examples/{typography-presets/site/images/compact-gallery → feature-demos/theme-presets/site/routes/020-documentation/images/documentation}/black-schnauzer.jpg +0 -0
- /package/examples/{typography-presets/site/images/compact-gallery → feature-demos/theme-presets/site/routes/020-documentation/images/documentation}/retriever-portrait.jpg +0 -0
- /package/examples/{typography-presets/site/images/compact-gallery → feature-demos/theme-presets/site/routes/020-documentation/images/documentation}/schnauzer-portrait.jpg +0 -0
- /package/examples/{typography-presets/site/images/text-forward → feature-demos/theme-presets/site/routes/030-project/images/project}/boxer-portrait.jpg +0 -0
- /package/examples/{typography-presets/site/images/text-forward → feature-demos/theme-presets/site/routes/030-project/images/project}/grass-puppy.jpg +0 -0
- /package/examples/{typography-presets/site/images/text-forward → feature-demos/theme-presets/site/routes/030-project/images/project}/grey-street-dog.jpg +0 -0
- /package/examples/{typography-presets/site → feature-demos/theme-presets/site/routes/040-statement}/images/statement/black-pedigree.jpg +0 -0
- /package/examples/{typography-presets/site → feature-demos/theme-presets/site/routes/040-statement}/images/statement/sheepdog-grass.jpg +0 -0
- /package/examples/{typography-presets/site → feature-demos/theme-presets/site/routes/040-statement}/images/statement/sheepdog-wide.jpg +0 -0
|
@@ -1,71 +1,130 @@
|
|
|
1
1
|
import {
|
|
2
2
|
defaultTypography,
|
|
3
3
|
resolveTypographyConfig,
|
|
4
|
-
resolveTypographyOverride,
|
|
5
4
|
} from './typography.mjs';
|
|
5
|
+
import { resolveThemeConfig } from './theme-presets.mjs';
|
|
6
6
|
|
|
7
|
-
export const
|
|
8
|
-
|
|
9
|
-
|
|
7
|
+
export const presentationPaletteNames = ['dark', 'light', 'paper'];
|
|
8
|
+
|
|
9
|
+
const presentationPalettes = Object.freeze({
|
|
10
|
+
dark: {
|
|
11
|
+
colorScheme: 'dark',
|
|
12
|
+
page: { backgroundColor: '#000000', textColor: '#f2eee6' },
|
|
13
|
+
surfaces: {
|
|
14
|
+
base: { backgroundColor: '#000000', textColor: '#f2eee6' },
|
|
15
|
+
soft: { backgroundColor: '#171717', textColor: '#f2eee6' },
|
|
16
|
+
emphasis: { backgroundColor: '#252525', textColor: '#f2eee6' },
|
|
17
|
+
},
|
|
18
|
+
frame: { backgroundColor: '#000000', textColor: '#f2eee6' },
|
|
19
|
+
css: {
|
|
20
|
+
surface: '#101010',
|
|
21
|
+
muted: '#aaa49a',
|
|
22
|
+
soft: '#302f2c',
|
|
23
|
+
accent: '#d8d2c8',
|
|
24
|
+
border: 'rgb(255 255 255 / 14%)',
|
|
25
|
+
navBackground: 'rgb(0 0 0 / 90%)',
|
|
26
|
+
navSeparator: 'rgb(255 255 255 / 28%)',
|
|
27
|
+
},
|
|
28
|
+
},
|
|
29
|
+
light: {
|
|
30
|
+
colorScheme: 'light',
|
|
31
|
+
page: { backgroundColor: '#ffffff', textColor: '#17201d' },
|
|
32
|
+
surfaces: {
|
|
33
|
+
base: { backgroundColor: '#ffffff', textColor: '#17201d' },
|
|
34
|
+
soft: { backgroundColor: '#f1f4f2', textColor: '#17201d' },
|
|
35
|
+
emphasis: { backgroundColor: '#dde7e1', textColor: '#17201d' },
|
|
36
|
+
},
|
|
37
|
+
frame: { backgroundColor: '#ffffff', textColor: '#17201d' },
|
|
38
|
+
css: {
|
|
39
|
+
surface: '#f7f8f7',
|
|
40
|
+
muted: '#5e655f',
|
|
41
|
+
soft: '#d9dfda',
|
|
42
|
+
accent: '#38645a',
|
|
43
|
+
border: 'rgb(0 0 0 / 14%)',
|
|
44
|
+
navBackground: 'rgb(255 255 255 / 92%)',
|
|
45
|
+
navSeparator: 'rgb(0 0 0 / 20%)',
|
|
46
|
+
},
|
|
47
|
+
},
|
|
48
|
+
paper: {
|
|
49
|
+
colorScheme: 'light',
|
|
50
|
+
page: { backgroundColor: '#f8f5ee', textColor: '#272522' },
|
|
51
|
+
surfaces: {
|
|
52
|
+
base: { backgroundColor: '#f8f5ee', textColor: '#272522' },
|
|
53
|
+
soft: { backgroundColor: '#ebe5d9', textColor: '#272522' },
|
|
54
|
+
emphasis: { backgroundColor: '#ded4c5', textColor: '#272522' },
|
|
55
|
+
},
|
|
56
|
+
frame: { backgroundColor: '#f8f5ee', textColor: '#272522' },
|
|
57
|
+
css: {
|
|
58
|
+
surface: '#f0ebe1',
|
|
59
|
+
muted: '#746e63',
|
|
60
|
+
soft: '#d8d0c4',
|
|
61
|
+
accent: '#685a43',
|
|
62
|
+
border: 'rgb(39 37 34 / 18%)',
|
|
63
|
+
navBackground: 'rgb(248 245 238 / 92%)',
|
|
64
|
+
navSeparator: 'rgb(39 37 34 / 24%)',
|
|
65
|
+
},
|
|
66
|
+
},
|
|
10
67
|
});
|
|
11
68
|
|
|
12
69
|
const normalizePresentation = (presentation) => presentation ?? {};
|
|
13
70
|
|
|
14
|
-
export const
|
|
15
|
-
const
|
|
16
|
-
|
|
71
|
+
export const getPresentationPalette = (paletteName = 'dark') => {
|
|
72
|
+
const palette = presentationPalettes[paletteName];
|
|
73
|
+
if (!palette) {
|
|
74
|
+
throw new Error(`Unknown presentation palette: ${paletteName}. Use one of: ${presentationPaletteNames.join(', ')}`);
|
|
75
|
+
}
|
|
76
|
+
|
|
77
|
+
return palette;
|
|
78
|
+
};
|
|
17
79
|
|
|
80
|
+
export const getPresentationCssVariables = (presentation) => {
|
|
81
|
+
const { palette } = presentation;
|
|
18
82
|
return {
|
|
19
|
-
|
|
20
|
-
|
|
21
|
-
|
|
22
|
-
|
|
83
|
+
'--color-page': palette.page.backgroundColor,
|
|
84
|
+
'--color-text': palette.page.textColor,
|
|
85
|
+
'--color-surface': palette.css.surface,
|
|
86
|
+
'--color-muted': palette.css.muted,
|
|
87
|
+
'--color-soft': palette.css.soft,
|
|
88
|
+
'--color-accent': palette.css.accent,
|
|
89
|
+
'--color-border': palette.css.border,
|
|
90
|
+
'--color-nav-background': palette.css.navBackground,
|
|
91
|
+
'--color-nav-separator': palette.css.navSeparator,
|
|
92
|
+
'--color-scheme': palette.colorScheme,
|
|
23
93
|
};
|
|
24
94
|
};
|
|
25
95
|
|
|
26
|
-
export const
|
|
27
|
-
const
|
|
28
|
-
const
|
|
96
|
+
export const resolveThemePresentation = (theme, sourceLabel = 'theme.md') => {
|
|
97
|
+
const normalizedTheme = resolveThemeConfig(theme, sourceLabel);
|
|
98
|
+
const normalizedThemePresentation = normalizePresentation(normalizedTheme.presentation);
|
|
99
|
+
const paletteName = normalizedThemePresentation.palette ?? 'dark';
|
|
100
|
+
const palette = getPresentationPalette(paletteName);
|
|
29
101
|
|
|
30
102
|
return {
|
|
31
|
-
|
|
32
|
-
|
|
33
|
-
|
|
34
|
-
|
|
35
|
-
|
|
36
|
-
|
|
37
|
-
),
|
|
103
|
+
paletteName,
|
|
104
|
+
palette,
|
|
105
|
+
sectionSurfaces: {
|
|
106
|
+
mode: normalizedThemePresentation.sectionSurfaces?.mode ?? 'none',
|
|
107
|
+
sequence: normalizedThemePresentation.sectionSurfaces?.sequence ?? ['base', 'soft', 'emphasis'],
|
|
108
|
+
},
|
|
109
|
+
typography: resolveTypographyConfig(normalizedTheme.typography ?? defaultTypography),
|
|
38
110
|
};
|
|
39
111
|
};
|
|
40
112
|
|
|
41
|
-
const
|
|
42
|
-
|
|
43
|
-
textColor: presentation.textColor,
|
|
44
|
-
});
|
|
45
|
-
|
|
46
|
-
const resolveColorSource = ({ colors, themeFrameColors, pagePresentation }) => {
|
|
47
|
-
if (!colors || colors === 'theme') {
|
|
48
|
-
return themeFrameColors;
|
|
49
|
-
}
|
|
50
|
-
|
|
51
|
-
if (colors === 'presentation') {
|
|
52
|
-
return getColorsFromPresentation(pagePresentation);
|
|
53
|
-
}
|
|
113
|
+
export const resolvePagePresentation = (theme, sourceLabel) => {
|
|
114
|
+
const resolvedThemePresentation = resolveThemePresentation(theme, sourceLabel);
|
|
54
115
|
|
|
55
|
-
return
|
|
116
|
+
return resolvedThemePresentation;
|
|
56
117
|
};
|
|
57
118
|
|
|
58
|
-
export const
|
|
59
|
-
const
|
|
60
|
-
|
|
61
|
-
|
|
62
|
-
themeFrameColors: getColorsFromPresentation(resolvedThemePresentation),
|
|
63
|
-
pagePresentation: resolvedThemePresentation,
|
|
64
|
-
});
|
|
119
|
+
export const resolveSectionSurface = (pagePresentation, sectionIndex) => {
|
|
120
|
+
const surfaceName = pagePresentation.sectionSurfaces.mode === 'cycle'
|
|
121
|
+
? pagePresentation.sectionSurfaces.sequence[sectionIndex % pagePresentation.sectionSurfaces.sequence.length]
|
|
122
|
+
: 'base';
|
|
65
123
|
|
|
66
|
-
return
|
|
67
|
-
|
|
68
|
-
|
|
69
|
-
|
|
70
|
-
});
|
|
124
|
+
return {
|
|
125
|
+
name: surfaceName,
|
|
126
|
+
...pagePresentation.palette.surfaces[surfaceName],
|
|
127
|
+
};
|
|
71
128
|
};
|
|
129
|
+
|
|
130
|
+
export const resolveFrameColors = ({ theme, sourceLabel }) => resolveThemePresentation(theme, sourceLabel).palette.frame;
|
|
@@ -1,6 +1,7 @@
|
|
|
1
1
|
import { pathToFileURL } from 'node:url';
|
|
2
2
|
import { siteConfigLabel, siteConfigPath, siteThemeLabel } from './site-paths.mjs';
|
|
3
3
|
import { readThemeConfig } from './theme-config.mjs';
|
|
4
|
+
import { resolveThemeConfig } from './theme-presets.mjs';
|
|
4
5
|
|
|
5
6
|
const { default: siteConfig } = await import(/* @vite-ignore */ pathToFileURL(siteConfigPath).href);
|
|
6
7
|
const themeConfig = await readThemeConfig();
|
|
@@ -37,20 +38,6 @@ const readString = (object, key, path, sourceLabel = siteConfigLabel) => {
|
|
|
37
38
|
return value.trim();
|
|
38
39
|
};
|
|
39
40
|
|
|
40
|
-
const readOptionalString = (object, key, path, sourceLabel = siteConfigLabel) => {
|
|
41
|
-
const value = object[key];
|
|
42
|
-
|
|
43
|
-
if (value === undefined || value === null || value === '') {
|
|
44
|
-
return null;
|
|
45
|
-
}
|
|
46
|
-
|
|
47
|
-
if (typeof value !== 'string' || value.trim() === '') {
|
|
48
|
-
throw new Error(`${path}.${key} must be a non-empty string when set in ${sourceLabel}.`);
|
|
49
|
-
}
|
|
50
|
-
|
|
51
|
-
return value.trim();
|
|
52
|
-
};
|
|
53
|
-
|
|
54
41
|
const readFontFamily = (object, key, path, fallback, sourceLabel = siteConfigLabel) => {
|
|
55
42
|
const value = object[key] ?? fallback;
|
|
56
43
|
|
|
@@ -242,58 +229,19 @@ const readLocale = (rawLocale) => {
|
|
|
242
229
|
lang: lang.trim(),
|
|
243
230
|
labels: Object.freeze({
|
|
244
231
|
closeMenu: readString({ closeMenu: labels.closeMenu ?? 'Close menu' }, 'closeMenu', 'locale.labels'),
|
|
232
|
+
dismissBanner: readString({ dismissBanner: labels.dismissBanner ?? 'Dismiss notice' }, 'dismissBanner', 'locale.labels'),
|
|
245
233
|
skipToContent: readString({ skipToContent: labels.skipToContent ?? 'Skip to content' }, 'skipToContent', 'locale.labels'),
|
|
246
234
|
sectionNavigation: readString({ sectionNavigation: labels.sectionNavigation ?? 'Sections' }, 'sectionNavigation', 'locale.labels'),
|
|
247
235
|
gallery: readString({ gallery: labels.gallery ?? 'Images' }, 'gallery', 'locale.labels'),
|
|
236
|
+
note: readString({ note: labels.note ?? 'Note' }, 'note', 'locale.labels'),
|
|
248
237
|
menu: readString({ menu: labels.menu ?? 'Menu' }, 'menu', 'locale.labels'),
|
|
249
238
|
pageNavigation: readString({ pageNavigation: labels.pageNavigation ?? 'On this page' }, 'pageNavigation', 'locale.labels'),
|
|
250
239
|
siteNavigation: readString({ siteNavigation: labels.siteNavigation ?? 'Pages' }, 'siteNavigation', 'locale.labels'),
|
|
240
|
+
siteBanners: readString({ siteBanners: labels.siteBanners ?? 'Site notices' }, 'siteBanners', 'locale.labels'),
|
|
251
241
|
}),
|
|
252
242
|
});
|
|
253
243
|
};
|
|
254
244
|
|
|
255
|
-
const readDateTimeFormat = (object, path) => {
|
|
256
|
-
const dateTimeFormat = assertObject(object, path);
|
|
257
|
-
const locale = readString(dateTimeFormat, 'locale', path);
|
|
258
|
-
const timeZone = readString(dateTimeFormat, 'timeZone', path);
|
|
259
|
-
const dateStyle = readString(dateTimeFormat, 'dateStyle', path);
|
|
260
|
-
const timeStyle = readString(dateTimeFormat, 'timeStyle', path);
|
|
261
|
-
|
|
262
|
-
try {
|
|
263
|
-
new Intl.DateTimeFormat(locale, {
|
|
264
|
-
dateStyle,
|
|
265
|
-
timeStyle,
|
|
266
|
-
timeZone,
|
|
267
|
-
});
|
|
268
|
-
} catch (error) {
|
|
269
|
-
const message = error instanceof Error ? error.message : String(error);
|
|
270
|
-
throw new Error(`${path} must be a valid Intl.DateTimeFormat configuration in ${siteConfigLabel}: ${message}`);
|
|
271
|
-
}
|
|
272
|
-
|
|
273
|
-
return Object.freeze({
|
|
274
|
-
dateStyle,
|
|
275
|
-
locale,
|
|
276
|
-
timeStyle,
|
|
277
|
-
timeZone,
|
|
278
|
-
});
|
|
279
|
-
};
|
|
280
|
-
|
|
281
|
-
const readBuildInfo = (footer) => {
|
|
282
|
-
const value = footer.buildInfo;
|
|
283
|
-
|
|
284
|
-
if (value === undefined || value === null || value === false) {
|
|
285
|
-
return null;
|
|
286
|
-
}
|
|
287
|
-
|
|
288
|
-
const buildInfo = assertObject(value, 'footer.buildInfo');
|
|
289
|
-
|
|
290
|
-
return Object.freeze({
|
|
291
|
-
enabled: readBoolean(buildInfo, 'enabled', 'footer.buildInfo', true),
|
|
292
|
-
text: readString(buildInfo, 'text', 'footer.buildInfo'),
|
|
293
|
-
dateTimeFormat: readDateTimeFormat(buildInfo.dateTimeFormat, 'footer.buildInfo.dateTimeFormat'),
|
|
294
|
-
});
|
|
295
|
-
};
|
|
296
|
-
|
|
297
245
|
const rawConfig = assertObject(siteConfig, 'default export');
|
|
298
246
|
const misplacedThemeKeys = ['layout', 'gallery', 'typography'].filter((key) => key in rawConfig);
|
|
299
247
|
if (misplacedThemeKeys.length > 0) {
|
|
@@ -302,13 +250,8 @@ if (misplacedThemeKeys.length > 0) {
|
|
|
302
250
|
|
|
303
251
|
const rawTheme = assertObject(themeConfig, 'theme frontmatter', siteThemeLabel);
|
|
304
252
|
const rawSite = assertObject(rawConfig.site, 'site');
|
|
305
|
-
const rawLayout = assertObject(rawTheme.layout ?? {}, 'layout', siteThemeLabel);
|
|
306
|
-
const rawLayoutSpacing = assertObject(rawLayout.spacing ?? {}, 'layout.spacing', siteThemeLabel);
|
|
307
|
-
const rawGallery = assertObject(rawTheme.gallery ?? {}, 'gallery', siteThemeLabel);
|
|
308
|
-
const rawTypography = assertObject(rawTheme.typography ?? {}, 'typography', siteThemeLabel);
|
|
309
253
|
const rawNavigation = assertObject(rawConfig.navigation ?? {}, 'navigation');
|
|
310
254
|
const rawLocale = rawConfig.locale ?? {};
|
|
311
|
-
const rawFooter = assertObject(rawConfig.footer ?? {}, 'footer');
|
|
312
255
|
const rawGithub = assertObject(rawConfig.github, 'github');
|
|
313
256
|
const rawDeploy = assertObject(rawConfig.deploy ?? {}, 'deploy');
|
|
314
257
|
const rawDeployWatch = assertObject(rawDeploy.watch ?? {}, 'deploy.watch');
|
|
@@ -317,9 +260,9 @@ const defaultFontFamily = "Arial, 'Helvetica Neue', Helvetica, sans-serif";
|
|
|
317
260
|
const layoutDensityNames = ['compact', 'normal', 'airy'];
|
|
318
261
|
const layoutDensityProfiles = Object.freeze({
|
|
319
262
|
compact: Object.freeze({
|
|
320
|
-
|
|
321
|
-
desktop: '
|
|
322
|
-
mobile: '
|
|
263
|
+
blockGap: Object.freeze({
|
|
264
|
+
desktop: '1.25em',
|
|
265
|
+
mobile: '1.1em',
|
|
323
266
|
}),
|
|
324
267
|
finalSectionBottom: Object.freeze({
|
|
325
268
|
desktop: 'clamp(1.2rem, 2.4vw, 2.25rem)',
|
|
@@ -329,6 +272,10 @@ const layoutDensityProfiles = Object.freeze({
|
|
|
329
272
|
desktop: 'clamp(1rem, 2vw, 1.75rem)',
|
|
330
273
|
mobile: '1rem',
|
|
331
274
|
}),
|
|
275
|
+
headingToBlock: Object.freeze({
|
|
276
|
+
desktop: '0.65em',
|
|
277
|
+
mobile: '0.6em',
|
|
278
|
+
}),
|
|
332
279
|
imageGap: Object.freeze({
|
|
333
280
|
desktop: 'clamp(1rem, 2vw, 1.5rem)',
|
|
334
281
|
mobile: '1.25rem',
|
|
@@ -339,9 +286,9 @@ const layoutDensityProfiles = Object.freeze({
|
|
|
339
286
|
}),
|
|
340
287
|
}),
|
|
341
288
|
normal: Object.freeze({
|
|
342
|
-
|
|
343
|
-
desktop: '1.
|
|
344
|
-
mobile: '
|
|
289
|
+
blockGap: Object.freeze({
|
|
290
|
+
desktop: '1.5em',
|
|
291
|
+
mobile: '1.25em',
|
|
345
292
|
}),
|
|
346
293
|
finalSectionBottom: Object.freeze({
|
|
347
294
|
desktop: 'clamp(1.4rem, 3vw, 2.75rem)',
|
|
@@ -351,6 +298,10 @@ const layoutDensityProfiles = Object.freeze({
|
|
|
351
298
|
desktop: 'clamp(1.25rem, 3vw, 2.5rem)',
|
|
352
299
|
mobile: '1.25rem',
|
|
353
300
|
}),
|
|
301
|
+
headingToBlock: Object.freeze({
|
|
302
|
+
desktop: '0.75em',
|
|
303
|
+
mobile: '0.7em',
|
|
304
|
+
}),
|
|
354
305
|
imageGap: Object.freeze({
|
|
355
306
|
desktop: 'clamp(1.25rem, 2.8vw, 2rem)',
|
|
356
307
|
mobile: '1.5rem',
|
|
@@ -361,9 +312,9 @@ const layoutDensityProfiles = Object.freeze({
|
|
|
361
312
|
}),
|
|
362
313
|
}),
|
|
363
314
|
airy: Object.freeze({
|
|
364
|
-
|
|
365
|
-
desktop: '1.
|
|
366
|
-
mobile: '1.
|
|
315
|
+
blockGap: Object.freeze({
|
|
316
|
+
desktop: '1.75em',
|
|
317
|
+
mobile: '1.5em',
|
|
367
318
|
}),
|
|
368
319
|
finalSectionBottom: Object.freeze({
|
|
369
320
|
desktop: 'clamp(2.25rem, 5vw, 4.5rem)',
|
|
@@ -373,6 +324,10 @@ const layoutDensityProfiles = Object.freeze({
|
|
|
373
324
|
desktop: 'clamp(2rem, 5vw, 4rem)',
|
|
374
325
|
mobile: '1.5rem',
|
|
375
326
|
}),
|
|
327
|
+
headingToBlock: Object.freeze({
|
|
328
|
+
desktop: '0.9em',
|
|
329
|
+
mobile: '0.8em',
|
|
330
|
+
}),
|
|
376
331
|
imageGap: Object.freeze({
|
|
377
332
|
desktop: 'clamp(1.5rem, 3.5vw, 2.75rem)',
|
|
378
333
|
mobile: '2rem',
|
|
@@ -383,51 +338,59 @@ const layoutDensityProfiles = Object.freeze({
|
|
|
383
338
|
}),
|
|
384
339
|
}),
|
|
385
340
|
});
|
|
386
|
-
const
|
|
387
|
-
const
|
|
341
|
+
export const resolveThemeVisualConfig = (theme, sourceLabel = siteThemeLabel) => {
|
|
342
|
+
const rawThemeConfig = assertObject(resolveThemeConfig(theme, sourceLabel), 'theme frontmatter', sourceLabel);
|
|
343
|
+
const rawLayoutConfig = assertObject(rawThemeConfig.layout ?? {}, 'layout', sourceLabel);
|
|
344
|
+
const rawLayoutSpacingConfig = assertObject(rawLayoutConfig.spacing ?? {}, 'layout.spacing', sourceLabel);
|
|
345
|
+
const rawGalleryConfig = assertObject(rawThemeConfig.gallery ?? {}, 'gallery', sourceLabel);
|
|
346
|
+
const rawTypographyConfig = assertObject(rawThemeConfig.typography ?? {}, 'typography', sourceLabel);
|
|
347
|
+
const resolvedLayoutDensity = readEnum(rawLayoutConfig, 'density', 'layout', layoutDensityNames, 'normal', sourceLabel);
|
|
348
|
+
const resolvedLayoutSpacingDefaults = layoutDensityProfiles[resolvedLayoutDensity];
|
|
349
|
+
|
|
350
|
+
return Object.freeze({
|
|
351
|
+
layout: Object.freeze({
|
|
352
|
+
density: resolvedLayoutDensity,
|
|
353
|
+
gutter: readResponsiveCssLength(rawLayoutConfig, 'gutter', 'layout', Object.freeze({
|
|
354
|
+
desktop: 'clamp(1.25rem, 4vw, 3rem)',
|
|
355
|
+
mobile: '1rem',
|
|
356
|
+
}), sourceLabel),
|
|
357
|
+
pageWidth: readCssLength(rawLayoutConfig, 'pageWidth', 'layout', '1180px', sourceLabel),
|
|
358
|
+
spacing: Object.freeze({
|
|
359
|
+
blockGap: readResponsiveCssLength(rawLayoutSpacingConfig, 'blockGap', 'layout.spacing', resolvedLayoutSpacingDefaults.blockGap, sourceLabel),
|
|
360
|
+
finalSectionBottom: readResponsiveCssLength(rawLayoutSpacingConfig, 'finalSectionBottom', 'layout.spacing', resolvedLayoutSpacingDefaults.finalSectionBottom, sourceLabel),
|
|
361
|
+
firstSectionTop: readResponsiveCssLength(rawLayoutSpacingConfig, 'firstSectionTop', 'layout.spacing', resolvedLayoutSpacingDefaults.firstSectionTop, sourceLabel),
|
|
362
|
+
headingToBlock: readResponsiveCssLength(rawLayoutSpacingConfig, 'headingToBlock', 'layout.spacing', resolvedLayoutSpacingDefaults.headingToBlock, sourceLabel),
|
|
363
|
+
imageGap: readResponsiveCssLength(rawLayoutSpacingConfig, 'imageGap', 'layout.spacing', resolvedLayoutSpacingDefaults.imageGap, sourceLabel),
|
|
364
|
+
sectionGap: readResponsiveCssLength(rawLayoutSpacingConfig, 'sectionGap', 'layout.spacing', resolvedLayoutSpacingDefaults.sectionGap, sourceLabel),
|
|
365
|
+
}),
|
|
366
|
+
}),
|
|
367
|
+
gallery: Object.freeze({
|
|
368
|
+
maxAvailableHeightPercent: readResponsivePercent(rawGalleryConfig, 'maxAvailableHeightPercent', 'gallery', Object.freeze({
|
|
369
|
+
desktop: 74,
|
|
370
|
+
mobile: 68,
|
|
371
|
+
}), sourceLabel),
|
|
372
|
+
maxAvailableWidthPercent: readResponsivePercent(rawGalleryConfig, 'maxAvailableWidthPercent', 'gallery', Object.freeze({
|
|
373
|
+
desktop: 100,
|
|
374
|
+
mobile: 100,
|
|
375
|
+
}), sourceLabel),
|
|
376
|
+
width: readCssLength(rawGalleryConfig, 'width', 'gallery', '900px', sourceLabel),
|
|
377
|
+
}),
|
|
378
|
+
typography: Object.freeze({
|
|
379
|
+
fontFamily: readFontFamily(rawTypographyConfig, 'fontFamily', 'typography', defaultFontFamily, sourceLabel),
|
|
380
|
+
}),
|
|
381
|
+
});
|
|
382
|
+
};
|
|
388
383
|
|
|
389
384
|
export const projectConfig = Object.freeze({
|
|
390
385
|
site: Object.freeze({
|
|
391
386
|
basePath: readBasePath(rawSite, 'basePath', 'site'),
|
|
392
387
|
url: readUrl(rawSite, 'url', 'site'),
|
|
393
388
|
}),
|
|
394
|
-
|
|
395
|
-
density: layoutDensity,
|
|
396
|
-
gutter: readResponsiveCssLength(rawLayout, 'gutter', 'layout', Object.freeze({
|
|
397
|
-
desktop: 'clamp(1.25rem, 4vw, 3rem)',
|
|
398
|
-
mobile: '1rem',
|
|
399
|
-
}), siteThemeLabel),
|
|
400
|
-
pageWidth: readCssLength(rawLayout, 'pageWidth', 'layout', '1180px', siteThemeLabel),
|
|
401
|
-
spacing: Object.freeze({
|
|
402
|
-
bodyToImages: readResponsiveCssLength(rawLayoutSpacing, 'bodyToImages', 'layout.spacing', layoutSpacingDefaults.bodyToImages, siteThemeLabel),
|
|
403
|
-
finalSectionBottom: readResponsiveCssLength(rawLayoutSpacing, 'finalSectionBottom', 'layout.spacing', layoutSpacingDefaults.finalSectionBottom, siteThemeLabel),
|
|
404
|
-
firstSectionTop: readResponsiveCssLength(rawLayoutSpacing, 'firstSectionTop', 'layout.spacing', layoutSpacingDefaults.firstSectionTop, siteThemeLabel),
|
|
405
|
-
imageGap: readResponsiveCssLength(rawLayoutSpacing, 'imageGap', 'layout.spacing', layoutSpacingDefaults.imageGap, siteThemeLabel),
|
|
406
|
-
sectionGap: readResponsiveCssLength(rawLayoutSpacing, 'sectionGap', 'layout.spacing', layoutSpacingDefaults.sectionGap, siteThemeLabel),
|
|
407
|
-
}),
|
|
408
|
-
}),
|
|
409
|
-
gallery: Object.freeze({
|
|
410
|
-
maxAvailableHeightPercent: readResponsivePercent(rawGallery, 'maxAvailableHeightPercent', 'gallery', Object.freeze({
|
|
411
|
-
desktop: 74,
|
|
412
|
-
mobile: 68,
|
|
413
|
-
}), siteThemeLabel),
|
|
414
|
-
maxAvailableWidthPercent: readResponsivePercent(rawGallery, 'maxAvailableWidthPercent', 'gallery', Object.freeze({
|
|
415
|
-
desktop: 100,
|
|
416
|
-
mobile: 100,
|
|
417
|
-
}), siteThemeLabel),
|
|
418
|
-
width: readCssLength(rawGallery, 'width', 'gallery', '900px', siteThemeLabel),
|
|
419
|
-
}),
|
|
420
|
-
typography: Object.freeze({
|
|
421
|
-
fontFamily: readFontFamily(rawTypography, 'fontFamily', 'typography', defaultFontFamily, siteThemeLabel),
|
|
422
|
-
}),
|
|
389
|
+
...resolveThemeVisualConfig(rawTheme, siteThemeLabel),
|
|
423
390
|
navigation: Object.freeze({
|
|
424
391
|
smoothScroll: readSmoothScroll(rawNavigation),
|
|
425
392
|
}),
|
|
426
393
|
locale: readLocale(rawLocale),
|
|
427
|
-
footer: Object.freeze({
|
|
428
|
-
buildInfo: readBuildInfo(rawFooter),
|
|
429
|
-
copyrightMessage: readOptionalString(rawFooter, 'copyrightMessage', 'footer'),
|
|
430
|
-
}),
|
|
431
394
|
github: Object.freeze({
|
|
432
395
|
repo: readString(rawGithub, 'repo', 'github'),
|
|
433
396
|
branch: readString(rawGithub, 'branch', 'github'),
|
|
@@ -18,24 +18,20 @@ export const supportedImageExtensions = new Set([...rasterImageExtensions, ...st
|
|
|
18
18
|
|
|
19
19
|
const h2Regex = /^##\s+.*$/gm;
|
|
20
20
|
const explicitHeadingIdRegex = /\s*\{#([a-z0-9-]+)\}\s*$/;
|
|
21
|
-
const
|
|
21
|
+
const deprecatedInlineStyleReferenceRegex = /\[[^\]\n]+\]\{\.([a-z][a-z0-9-]*)\}/g;
|
|
22
22
|
const frontmatterDelimiterRegex = /^---\s*$/;
|
|
23
|
-
const knownContentTopLevelFrontmatterKeys = new Set(['title', 'description', 'navigation', '
|
|
24
|
-
const knownThemeTopLevelFrontmatterKeys = new Set(['navigation', 'layout', 'gallery', 'typography', 'presentation'
|
|
25
|
-
const
|
|
26
|
-
const
|
|
27
|
-
const unquotedHexColorRegex = /^#(?:[0-9a-fA-F]{3}|[0-9a-fA-F]{6}|[0-9a-fA-F]{8})$/;
|
|
23
|
+
const knownContentTopLevelFrontmatterKeys = new Set(['title', 'description', 'navigation', 'sections']);
|
|
24
|
+
const knownThemeTopLevelFrontmatterKeys = new Set(['navigation', 'preset', 'layout', 'gallery', 'typography', 'presentation']);
|
|
25
|
+
const knownRouteThemeTopLevelFrontmatterKeys = new Set(['navigation', 'preset', 'layout', 'gallery', 'typography', 'presentation']);
|
|
26
|
+
const knownSitewideTopLevelFrontmatterKeys = new Set(['navigation', 'banners', 'footer']);
|
|
28
27
|
const knownNestedFrontmatterKeys = new Set([
|
|
29
28
|
'align',
|
|
30
29
|
'alt',
|
|
31
|
-
'backgroundColor',
|
|
32
30
|
'body',
|
|
33
|
-
'
|
|
31
|
+
'blockGap',
|
|
34
32
|
'brand',
|
|
35
33
|
'caption',
|
|
36
34
|
'carousel',
|
|
37
|
-
'color',
|
|
38
|
-
'colors',
|
|
39
35
|
'density',
|
|
40
36
|
'desktop',
|
|
41
37
|
'fontFamily',
|
|
@@ -43,6 +39,7 @@ const knownNestedFrontmatterKeys = new Set([
|
|
|
43
39
|
'finalSectionBottom',
|
|
44
40
|
'gallery',
|
|
45
41
|
'gutter',
|
|
42
|
+
'headingToBlock',
|
|
46
43
|
'h1',
|
|
47
44
|
'h2',
|
|
48
45
|
'h3',
|
|
@@ -53,8 +50,8 @@ const knownNestedFrontmatterKeys = new Set([
|
|
|
53
50
|
'include',
|
|
54
51
|
'image',
|
|
55
52
|
'imageGap',
|
|
56
|
-
'inlineStyles',
|
|
57
53
|
'label',
|
|
54
|
+
'logo',
|
|
58
55
|
'lineHeight',
|
|
59
56
|
'maxAvailableHeightPercent',
|
|
60
57
|
'maxAvailableWidthPercent',
|
|
@@ -63,15 +60,18 @@ const knownNestedFrontmatterKeys = new Set([
|
|
|
63
60
|
'overrides',
|
|
64
61
|
'paragraphSpacing',
|
|
65
62
|
'pageWidth',
|
|
63
|
+
'palette',
|
|
66
64
|
'preset',
|
|
67
65
|
'presentation',
|
|
68
66
|
'rhythm',
|
|
67
|
+
'sequence',
|
|
69
68
|
'sections',
|
|
70
69
|
'sectionGap',
|
|
70
|
+
'sectionSurfaces',
|
|
71
71
|
'size',
|
|
72
72
|
'spacingAfter',
|
|
73
73
|
'spacingBefore',
|
|
74
|
-
'
|
|
74
|
+
'surface',
|
|
75
75
|
'theme',
|
|
76
76
|
'typography',
|
|
77
77
|
'until',
|
|
@@ -264,79 +264,6 @@ export const validateFrontmatterStructure = (frontmatter, addIssue, {
|
|
|
264
264
|
}
|
|
265
265
|
};
|
|
266
266
|
|
|
267
|
-
const stripInlineYamlComment = (value) => {
|
|
268
|
-
let quote = null;
|
|
269
|
-
|
|
270
|
-
for (let index = 0; index < value.length; index += 1) {
|
|
271
|
-
const character = value[index];
|
|
272
|
-
const previous = value[index - 1];
|
|
273
|
-
|
|
274
|
-
if ((character === '"' || character === "'") && previous !== '\\') {
|
|
275
|
-
quote = quote === character ? null : quote ?? character;
|
|
276
|
-
continue;
|
|
277
|
-
}
|
|
278
|
-
|
|
279
|
-
if (character === '#' && quote === null && /\s/.test(previous ?? '')) {
|
|
280
|
-
return value.slice(0, index).trimEnd();
|
|
281
|
-
}
|
|
282
|
-
}
|
|
283
|
-
|
|
284
|
-
return value.trim();
|
|
285
|
-
};
|
|
286
|
-
|
|
287
|
-
export const validateFrontmatterColorValues = (frontmatter, addIssue, label = 'Frontmatter') => {
|
|
288
|
-
const lines = frontmatter.split(/\r?\n/);
|
|
289
|
-
const pathStack = [];
|
|
290
|
-
|
|
291
|
-
for (const [index, line] of lines.entries()) {
|
|
292
|
-
const lineNumber = index + 1;
|
|
293
|
-
const trimmed = line.trim();
|
|
294
|
-
|
|
295
|
-
if (!trimmed || trimmed.startsWith('#') || frontmatterDelimiterRegex.test(line)) {
|
|
296
|
-
continue;
|
|
297
|
-
}
|
|
298
|
-
|
|
299
|
-
const match = line.match(/^(\s*)([A-Za-z][A-Za-z0-9-]*):\s*(.*?)\s*$/);
|
|
300
|
-
if (!match) continue;
|
|
301
|
-
|
|
302
|
-
const indent = match[1].length;
|
|
303
|
-
const key = match[2];
|
|
304
|
-
const rawValue = match[3].trim();
|
|
305
|
-
|
|
306
|
-
while (pathStack.length > 0 && pathStack[pathStack.length - 1].indent >= indent) {
|
|
307
|
-
pathStack.pop();
|
|
308
|
-
}
|
|
309
|
-
|
|
310
|
-
const pathLabel = [...pathStack.map((entry) => entry.key), key].join('.');
|
|
311
|
-
|
|
312
|
-
if (!frontmatterColorKeys.has(key)) {
|
|
313
|
-
if (!rawValue) {
|
|
314
|
-
pathStack.push({ indent, key });
|
|
315
|
-
}
|
|
316
|
-
continue;
|
|
317
|
-
}
|
|
318
|
-
|
|
319
|
-
const value = stripInlineYamlComment(rawValue);
|
|
320
|
-
|
|
321
|
-
if (quotedHexColorRegex.test(value)) continue;
|
|
322
|
-
|
|
323
|
-
if (unquotedHexColorRegex.test(rawValue)) {
|
|
324
|
-
addIssue({
|
|
325
|
-
severity: 'error',
|
|
326
|
-
message: `${label} line ${lineNumber} defines ${pathLabel} as an unquoted hex color. YAML treats "#" as the start of a comment unless the value is quoted.`,
|
|
327
|
-
fix: `Write it as ${key}: "#ffd84d" or another quoted hex color.`,
|
|
328
|
-
});
|
|
329
|
-
continue;
|
|
330
|
-
}
|
|
331
|
-
|
|
332
|
-
addIssue({
|
|
333
|
-
severity: 'error',
|
|
334
|
-
message: `${label} line ${lineNumber} defines ${pathLabel} with invalid color value ${rawValue || '(empty)'}.`,
|
|
335
|
-
fix: `Use a quoted hex color in #rgb, #rrggbb, or #rrggbbaa form, for example ${key}: "#ffd84d".`,
|
|
336
|
-
});
|
|
337
|
-
}
|
|
338
|
-
};
|
|
339
|
-
|
|
340
267
|
export const validateContentFrontmatterStructure = (frontmatter, addIssue) =>
|
|
341
268
|
validateFrontmatterStructure(frontmatter, addIssue, {
|
|
342
269
|
knownTopLevelFrontmatterKeys: knownContentTopLevelFrontmatterKeys,
|
|
@@ -349,6 +276,18 @@ export const validateThemeFrontmatterStructure = (frontmatter, addIssue) =>
|
|
|
349
276
|
fileKind: 'theme',
|
|
350
277
|
});
|
|
351
278
|
|
|
279
|
+
export const validateRouteThemeFrontmatterStructure = (frontmatter, addIssue) =>
|
|
280
|
+
validateFrontmatterStructure(frontmatter, addIssue, {
|
|
281
|
+
knownTopLevelFrontmatterKeys: knownRouteThemeTopLevelFrontmatterKeys,
|
|
282
|
+
fileKind: 'route theme',
|
|
283
|
+
});
|
|
284
|
+
|
|
285
|
+
export const validateSitewideFrontmatterStructure = (frontmatter, addIssue) =>
|
|
286
|
+
validateFrontmatterStructure(frontmatter, addIssue, {
|
|
287
|
+
knownTopLevelFrontmatterKeys: knownSitewideTopLevelFrontmatterKeys,
|
|
288
|
+
fileKind: 'sitewide content',
|
|
289
|
+
});
|
|
290
|
+
|
|
352
291
|
export const readThemeFile = async (sitePath) => readSiteFile(sitePath, siteThemeLabel);
|
|
353
292
|
|
|
354
293
|
export const getFrontmatterSections = (frontmatter) => {
|
|
@@ -374,42 +313,11 @@ export const getFrontmatterSections = (frontmatter) => {
|
|
|
374
313
|
return sections;
|
|
375
314
|
};
|
|
376
315
|
|
|
377
|
-
export const
|
|
378
|
-
const names = new Set();
|
|
379
|
-
const lines = frontmatter.split(/\r?\n/);
|
|
380
|
-
let inlineStylesIndent = null;
|
|
381
|
-
|
|
382
|
-
for (const line of lines) {
|
|
383
|
-
const inlineStylesMatch = line.match(/^(\s*)inlineStyles:\s*$/);
|
|
384
|
-
|
|
385
|
-
if (inlineStylesMatch) {
|
|
386
|
-
inlineStylesIndent = inlineStylesMatch[1].length;
|
|
387
|
-
continue;
|
|
388
|
-
}
|
|
389
|
-
|
|
390
|
-
if (inlineStylesIndent === null) continue;
|
|
391
|
-
if (!line.trim() || line.trim().startsWith('#')) continue;
|
|
392
|
-
|
|
393
|
-
const indent = line.match(/^\s*/)?.[0].length ?? 0;
|
|
394
|
-
if (indent <= inlineStylesIndent) {
|
|
395
|
-
inlineStylesIndent = null;
|
|
396
|
-
continue;
|
|
397
|
-
}
|
|
398
|
-
|
|
399
|
-
const nameMatch = line.match(new RegExp(`^\\s{${inlineStylesIndent + 2}}([a-z][a-z0-9-]*):\\s*$`));
|
|
400
|
-
if (nameMatch) {
|
|
401
|
-
names.add(nameMatch[1]);
|
|
402
|
-
}
|
|
403
|
-
}
|
|
404
|
-
|
|
405
|
-
return names;
|
|
406
|
-
};
|
|
316
|
+
export const getHeadingId = (heading) => heading.match(explicitHeadingIdRegex)?.[1];
|
|
407
317
|
|
|
408
|
-
export const
|
|
318
|
+
export const getDeprecatedInlineStyleReferences = (body) => Array.from(body.matchAll(deprecatedInlineStyleReferenceRegex))
|
|
409
319
|
.map((match) => match[1]);
|
|
410
320
|
|
|
411
|
-
export const getHeadingId = (heading) => heading.match(explicitHeadingIdRegex)?.[1];
|
|
412
|
-
|
|
413
321
|
export const getBodySections = (body) => {
|
|
414
322
|
const matches = Array.from(body.matchAll(h2Regex));
|
|
415
323
|
const prelude = matches.length > 0 ? body.slice(0, matches[0].index) : body;
|
|
@@ -117,6 +117,7 @@ export const siteDir = resolvedSitePaths.siteDir;
|
|
|
117
117
|
export const siteConfigPath = path.join(siteDir, 'config.mjs');
|
|
118
118
|
export const siteThemePath = path.join(siteDir, 'theme.md');
|
|
119
119
|
export const siteContentPath = path.join(siteDir, 'content.md');
|
|
120
|
+
export const sitewideContentPath = path.join(siteDir, 'sitewide-content.md');
|
|
120
121
|
export const siteImagesDir = path.join(siteDir, 'images');
|
|
121
122
|
export const siteRoutesDir = path.join(siteDir, 'routes');
|
|
122
123
|
export const sitePublicDir = path.join(siteDir, 'public');
|
|
@@ -135,6 +136,7 @@ export const siteDirLabel = getPathLabel(siteDir);
|
|
|
135
136
|
export const siteConfigLabel = getPathLabel(siteConfigPath);
|
|
136
137
|
export const siteThemeLabel = getPathLabel(siteThemePath);
|
|
137
138
|
export const siteContentLabel = getPathLabel(siteContentPath);
|
|
139
|
+
export const sitewideContentLabel = getPathLabel(sitewideContentPath);
|
|
138
140
|
export const siteImagesLabel = getPathLabel(siteImagesDir);
|
|
139
141
|
export const siteRoutesLabel = getPathLabel(siteRoutesDir);
|
|
140
142
|
export const sitePublicLabel = getPathLabel(sitePublicDir);
|