@janga/norna 0.7.16 → 0.7.18
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 +18 -9
- package/astro.config.mjs +35 -3
- package/bin/norna-cli.mjs +1 -1
- package/docs/README.md +16 -14
- package/docs/commands.md +2 -2
- package/docs/configuration.md +25 -2
- package/docs/content.md +92 -103
- package/docs/design/navigation-and-theme-plan.md +186 -0
- package/docs/design/norna-diagram-design.md +9 -9
- package/docs/design/site-examples-structure.md +15 -11
- package/docs/engine-development.md +19 -22
- package/docs/getting-started.md +21 -16
- package/docs/images-and-metadata.md +12 -9
- package/docs/pages.md +190 -0
- package/docs/public-files.md +49 -36
- package/docs/publishing.md +19 -3
- package/docs/site-files.md +46 -38
- package/docs/sitewide-content.md +20 -36
- package/docs/theme.md +109 -143
- package/docs/typography.md +19 -31
- package/examples/README.md +10 -4
- package/examples/complete-sites/dog-shelter-multi-page/.astro/collections/site.schema.json +17 -41
- package/examples/complete-sites/dog-shelter-multi-page/.astro/collections/sitewide.schema.json +26 -67
- package/examples/complete-sites/dog-shelter-multi-page/.astro/collections/theme.schema.json +185 -88
- package/examples/complete-sites/dog-shelter-multi-page/.astro/data-store.json +1 -1
- package/examples/complete-sites/dog-shelter-multi-page/.astro/dev-local.json +4 -4
- package/examples/complete-sites/dog-shelter-multi-page/.astro/dev.json +5 -5
- package/examples/complete-sites/dog-shelter-multi-page/.astro/dev.log +33 -23
- package/examples/complete-sites/dog-shelter-multi-page/README.md +1 -1
- package/examples/complete-sites/dog-shelter-multi-page/node_modules/.vite/deps/_metadata.json +8 -8
- package/examples/complete-sites/dog-shelter-multi-page/site/.norna/generated-images.json +20 -20
- package/examples/complete-sites/dog-shelter-multi-page/site/{content.md → pages/000-home/content.md} +3 -4
- package/examples/complete-sites/dog-shelter-multi-page/site/{routes → pages}/010-dogs/content.md +3 -4
- package/examples/complete-sites/dog-shelter-multi-page/site/{routes → pages}/020-adopt/content.md +3 -4
- package/examples/complete-sites/dog-shelter-multi-page/site/sitewide-content.yaml +2 -4
- package/examples/complete-sites/dog-shelter-single-page/.astro/collections/site.schema.json +17 -41
- package/examples/complete-sites/dog-shelter-single-page/.astro/collections/sitewide.schema.json +26 -67
- package/examples/complete-sites/dog-shelter-single-page/.astro/collections/theme.schema.json +185 -88
- package/examples/complete-sites/dog-shelter-single-page/.astro/data-store.json +1 -1
- package/examples/complete-sites/dog-shelter-single-page/.astro/dev-local.json +8 -0
- package/examples/complete-sites/dog-shelter-single-page/.astro/dev.json +5 -5
- package/examples/complete-sites/dog-shelter-single-page/.astro/dev.log +16 -12
- package/examples/complete-sites/dog-shelter-single-page/README.md +1 -1
- package/examples/complete-sites/dog-shelter-single-page/node_modules/.vite/deps/_metadata.json +8 -8
- package/examples/complete-sites/dog-shelter-single-page/site/.norna/generated-images.json +12 -12
- package/examples/complete-sites/dog-shelter-single-page/site/{content.md → pages/000-home/content.md} +5 -2
- package/examples/complete-sites/dog-shelter-single-page/site/sitewide-content.yaml +2 -4
- package/examples/feature-demos/media-and-surfaces/.astro/collections/site.schema.json +17 -41
- package/examples/feature-demos/media-and-surfaces/.astro/collections/sitewide.schema.json +26 -67
- package/examples/feature-demos/media-and-surfaces/.astro/collections/theme.schema.json +180 -91
- package/examples/feature-demos/media-and-surfaces/.astro/data-store.json +1 -1
- package/examples/feature-demos/media-and-surfaces/.astro/dev.log +4 -14
- package/examples/feature-demos/media-and-surfaces/README.md +2 -2
- package/examples/feature-demos/media-and-surfaces/node_modules/.vite/deps/_metadata.json +9 -9
- package/examples/feature-demos/media-and-surfaces/site/.norna/generated-images.json +16 -16
- package/examples/feature-demos/media-and-surfaces/site/{content.md → pages/000-home/content.md} +4 -7
- package/examples/feature-demos/media-and-surfaces/site/{routes → pages}/010-media/content.md +6 -5
- package/examples/feature-demos/media-and-surfaces/site/{routes → pages}/020-surfaces/content.md +9 -7
- package/examples/feature-demos/media-and-surfaces/site/pages/020-surfaces/theme.yaml +2 -0
- package/examples/feature-demos/media-and-surfaces/site/sitewide-content.yaml +0 -2
- package/examples/feature-demos/sitewide-content/README.md +3 -3
- package/examples/feature-demos/sitewide-content/site/pages/000-home/content.md +17 -0
- package/examples/feature-demos/sitewide-content/site/pages/010-logo-and-navigation/content.md +17 -0
- package/examples/feature-demos/sitewide-content/site/{routes → pages}/020-notices/content.md +7 -6
- package/examples/feature-demos/sitewide-content/site/{routes → pages}/030-footer/content.md +6 -5
- package/examples/feature-demos/sitewide-content/site/sitewide-content.yaml +4 -13
- package/examples/feature-demos/theme-preset-documentation/README.md +16 -0
- package/examples/feature-demos/theme-preset-documentation/site/.norna/generated-images.json +74 -0
- package/examples/feature-demos/{theme-presets/site/routes/020-documentation → theme-preset-documentation/site/pages/000-home}/content.md +4 -7
- package/examples/feature-demos/theme-preset-documentation/site/sitewide-content.yaml +3 -0
- package/examples/feature-demos/theme-preset-portfolio/README.md +16 -0
- package/examples/feature-demos/theme-preset-portfolio/site/.norna/generated-images.json +74 -0
- package/examples/feature-demos/theme-preset-portfolio/site/config.yaml +1 -0
- package/examples/feature-demos/{theme-presets/site/routes/010-portfolio → theme-preset-portfolio/site/pages/000-home}/content.md +4 -7
- package/examples/feature-demos/theme-preset-portfolio/site/public/robots.txt +2 -0
- package/examples/feature-demos/theme-preset-portfolio/site/sitewide-content.yaml +3 -0
- package/examples/feature-demos/theme-preset-project/README.md +16 -0
- package/examples/feature-demos/theme-preset-project/site/.norna/generated-images.json +74 -0
- package/examples/feature-demos/theme-preset-project/site/config.yaml +1 -0
- package/examples/feature-demos/{theme-presets/site/routes/030-project → theme-preset-project/site/pages/000-home}/content.md +4 -7
- package/examples/feature-demos/theme-preset-project/site/public/robots.txt +2 -0
- package/examples/feature-demos/theme-preset-project/site/sitewide-content.yaml +3 -0
- package/examples/feature-demos/theme-preset-statement/README.md +16 -0
- package/examples/feature-demos/theme-preset-statement/site/.norna/generated-images.json +74 -0
- package/examples/feature-demos/theme-preset-statement/site/config.yaml +1 -0
- package/examples/feature-demos/{theme-presets/site/routes/040-statement → theme-preset-statement/site/pages/000-home}/content.md +4 -7
- package/examples/feature-demos/theme-preset-statement/site/public/robots.txt +2 -0
- package/examples/feature-demos/theme-preset-statement/site/sitewide-content.yaml +3 -0
- package/fixtures/basic/site/{content.md → pages/000-home/content.md} +5 -6
- package/fixtures/basic/site/sitewide-content.yaml +1 -8
- package/fixtures/basic/site/theme.yaml +1 -8
- package/fixtures/content-model-v2/site/{content.md → pages/000-home/content.md} +11 -13
- package/fixtures/content-model-v2/site/pages/010-guide/content.md +18 -0
- package/fixtures/nested-pages/.astro/collections/site.schema.json +35 -0
- package/fixtures/nested-pages/.astro/collections/sitewide.schema.json +97 -0
- package/fixtures/nested-pages/.astro/collections/theme.schema.json +844 -0
- package/fixtures/nested-pages/.astro/content-assets.mjs +4 -0
- package/fixtures/nested-pages/.astro/content-modules.mjs +1 -0
- package/fixtures/nested-pages/.astro/content.d.ts +183 -0
- package/fixtures/nested-pages/.astro/data-store.json +1 -0
- package/fixtures/nested-pages/.astro/dev-local.json +8 -0
- package/fixtures/nested-pages/.astro/dev.log +1128 -0
- package/fixtures/nested-pages/.astro/settings.json +5 -0
- package/fixtures/nested-pages/.astro/types.d.ts +2 -0
- package/fixtures/nested-pages/node_modules/.vite/deps/_metadata.json +74 -0
- package/fixtures/nested-pages/node_modules/.vite/deps/astro-D_GIpJIE.js +434 -0
- package/fixtures/nested-pages/node_modules/.vite/deps/astro-D_GIpJIE.js.map +1 -0
- package/fixtures/nested-pages/node_modules/.vite/deps/astro_n_aria-query.js +6390 -0
- package/fixtures/nested-pages/node_modules/.vite/deps/astro_n_aria-query.js.map +1 -0
- package/fixtures/nested-pages/node_modules/.vite/deps/astro_n_axobject-query.js +2702 -0
- package/fixtures/nested-pages/node_modules/.vite/deps/astro_n_axobject-query.js.map +1 -0
- package/fixtures/nested-pages/node_modules/.vite/deps/astro_n_html-escaper.js +65 -0
- package/fixtures/nested-pages/node_modules/.vite/deps/astro_n_html-escaper.js.map +1 -0
- package/fixtures/nested-pages/node_modules/.vite/deps/astro_runtime_client_dev-toolbar_entrypoint__js.js +455 -0
- package/fixtures/nested-pages/node_modules/.vite/deps/astro_runtime_client_dev-toolbar_entrypoint__js.js.map +1 -0
- package/fixtures/nested-pages/node_modules/.vite/deps/audit-DM9Hkl5B.js +1534 -0
- package/fixtures/nested-pages/node_modules/.vite/deps/audit-DM9Hkl5B.js.map +1 -0
- package/fixtures/nested-pages/node_modules/.vite/deps/highlight-DnZ1ULOL.js +48 -0
- package/fixtures/nested-pages/node_modules/.vite/deps/highlight-DnZ1ULOL.js.map +1 -0
- package/fixtures/nested-pages/node_modules/.vite/deps/icons-RyebKi45.js +42 -0
- package/fixtures/nested-pages/node_modules/.vite/deps/icons-RyebKi45.js.map +1 -0
- package/fixtures/nested-pages/node_modules/.vite/deps/package.json +3 -0
- package/fixtures/nested-pages/node_modules/.vite/deps/rolldown-runtime-BvCyGRYZ.js +4 -0
- package/fixtures/nested-pages/node_modules/.vite/deps/settings-DaU-gNnK.js +190 -0
- package/fixtures/nested-pages/node_modules/.vite/deps/settings-DaU-gNnK.js.map +1 -0
- package/fixtures/nested-pages/node_modules/.vite/deps/toolbar-63PA619H.js +458 -0
- package/fixtures/nested-pages/node_modules/.vite/deps/toolbar-63PA619H.js.map +1 -0
- package/fixtures/nested-pages/node_modules/.vite/deps/ui-library--bkcNSYz.js +1016 -0
- package/fixtures/nested-pages/node_modules/.vite/deps/ui-library--bkcNSYz.js.map +1 -0
- package/fixtures/nested-pages/node_modules/.vite/deps/window-jPkpKVcy.js +32 -0
- package/fixtures/nested-pages/node_modules/.vite/deps/window-jPkpKVcy.js.map +1 -0
- package/fixtures/nested-pages/node_modules/.vite/deps/xray-BXCHpEJP.js +111 -0
- package/fixtures/nested-pages/node_modules/.vite/deps/xray-BXCHpEJP.js.map +1 -0
- package/fixtures/nested-pages/site/.norna/generated-images.json +10 -0
- package/fixtures/nested-pages/site/config.yaml +3 -0
- package/fixtures/nested-pages/site/pages/000-home/content.md +15 -0
- package/fixtures/nested-pages/site/pages/010-guides/content.md +15 -0
- package/fixtures/nested-pages/site/pages/010-guides/pages/010-installation/content.md +21 -0
- package/fixtures/nested-pages/site/pages/010-guides/pages/010-installation/images/diagram.svg +21 -0
- package/fixtures/nested-pages/site/pages/010-guides/pages/010-installation/pages/010-macos/content.md +18 -0
- package/fixtures/nested-pages/site/pages/010-guides/pages/010-installation/theme.yaml +2 -0
- package/fixtures/nested-pages/site/pages/010-guides/pages/020-workflows/content.md +11 -0
- package/fixtures/nested-pages/site/pages/010-guides/pages/030-release-notes/content.md +9 -0
- package/fixtures/nested-pages/site/pages/010-guides/pages/040-configuration/content.md +3 -0
- package/fixtures/nested-pages/site/pages/010-guides/pages/050-content/content.md +3 -0
- package/fixtures/nested-pages/site/pages/010-guides/pages/060-themes/content.md +3 -0
- package/fixtures/nested-pages/site/pages/010-guides/pages/070-images/content.md +3 -0
- package/fixtures/nested-pages/site/pages/010-guides/pages/080-cards/content.md +3 -0
- package/fixtures/nested-pages/site/pages/010-guides/pages/090-notes/content.md +3 -0
- package/fixtures/nested-pages/site/pages/010-guides/pages/100-validation/content.md +3 -0
- package/fixtures/nested-pages/site/pages/010-guides/pages/110-synchronization/content.md +3 -0
- package/fixtures/nested-pages/site/pages/010-guides/pages/120-building/content.md +3 -0
- package/fixtures/nested-pages/site/pages/010-guides/pages/130-publishing/content.md +3 -0
- package/fixtures/nested-pages/site/pages/010-guides/pages/140-troubleshooting/content.md +3 -0
- package/fixtures/nested-pages/site/pages/010-guides/pages/150-migration/content.md +3 -0
- package/fixtures/nested-pages/site/pages/010-guides/pages/160-accessibility/content.md +3 -0
- package/fixtures/nested-pages/site/pages/010-guides/pages/170-performance/content.md +3 -0
- package/fixtures/nested-pages/site/pages/010-guides/pages/180-security/content.md +3 -0
- package/fixtures/nested-pages/site/pages/010-guides/pages/190-localization/content.md +3 -0
- package/fixtures/nested-pages/site/pages/010-guides/pages/200-upgrading/content.md +3 -0
- package/fixtures/nested-pages/site/pages/010-guides/pages/210-faq/content.md +3 -0
- package/fixtures/nested-pages/site/pages/010-guides/theme.yaml +7 -0
- package/fixtures/nested-pages/site/pages/020-reference/content.md +10 -0
- package/fixtures/nested-pages/site/pages/020-reference/pages/010-installation/content.md +11 -0
- package/fixtures/nested-pages/site/theme.yaml +1 -0
- package/package.json +8 -4
- package/schemas/config.schema.json +46 -5
- package/schemas/content-frontmatter.schema.json +28 -63
- package/schemas/manifest.json +4 -2
- package/schemas/page-theme.schema.json +192 -0
- package/schemas/sitewide-content.schema.json +58 -132
- package/schemas/theme.schema.json +434 -152
- package/scripts/check-config.mjs +8 -6
- package/scripts/deploy-site.mjs +6 -8
- package/scripts/doctor.mjs +2 -2
- package/scripts/generate-images.mjs +15 -29
- package/scripts/generate-schemas.mjs +7 -218
- package/scripts/lib/base-path-redirect.mjs +9 -0
- package/scripts/lib/editor-language-service.mjs +125 -79
- package/scripts/lib/example-sites.mjs +15 -3
- package/scripts/lib/heading-ids.mjs +161 -0
- package/scripts/lib/navigation-model.mjs +51 -0
- package/scripts/lib/norna-markdown-blocks.mjs +3 -4
- package/scripts/lib/page-model.mjs +102 -0
- package/scripts/lib/presentation.mjs +25 -17
- package/scripts/lib/project-config.mjs +46 -8
- package/scripts/lib/schema-definitions.mjs +78 -55
- package/scripts/lib/schema-editor-metadata.mjs +519 -0
- package/scripts/lib/schema-value-definitions.mjs +20 -6
- package/scripts/lib/site-content.mjs +159 -97
- package/scripts/lib/site-conventions.mjs +1 -0
- package/scripts/lib/site-paths.mjs +11 -5
- package/scripts/lib/theme-config.mjs +12 -18
- package/scripts/lib/theme-presets.mjs +55 -14
- package/scripts/release.mjs +1 -1
- package/scripts/show-typography.mjs +4 -30
- package/scripts/sync-content-sections.mjs +107 -68
- package/scripts/{test-temporary-visibility.mjs → test-banner-visibility.mjs} +8 -25
- package/scripts/test-client-javascript.mjs +50 -46
- package/scripts/test-content-check.mjs +153 -69
- package/scripts/test-content-model-v2.mjs +566 -285
- package/scripts/test-documentation.mjs +10 -3
- package/scripts/test-editor-language-service.mjs +172 -25
- package/scripts/test-engine-commands.mjs +6 -5
- package/scripts/test-examples.mjs +30 -1
- package/scripts/test-heading-ids.mjs +68 -0
- package/scripts/test-navigation-model.mjs +63 -0
- package/scripts/test-navigation.mjs +11 -2
- package/scripts/test-nested-pages.mjs +125 -0
- package/scripts/test-package-check.mjs +55 -95
- package/scripts/test-page-model.mjs +108 -0
- package/scripts/test-project-config.mjs +22 -3
- package/scripts/test-schemas.mjs +82 -15
- package/scripts/test-theme-presets.mjs +57 -42
- package/src/components/NavigationPageTree.astro +157 -0
- package/src/components/PageContentsLinks.astro +40 -0
- package/src/components/SectionNavigationScript.astro +117 -5
- package/src/components/SiteBreadcrumbs.astro +32 -0
- package/src/components/SiteNavigation.astro +97 -68
- package/src/components/SitePage.astro +93 -55
- package/src/components/SiteSection.astro +29 -27
- package/src/components/SiteTreeNavigation.astro +35 -0
- package/src/components/TreeNavigationScript.astro +83 -0
- package/src/content.config.ts +8 -10
- package/src/layouts/BaseLayout.astro +21 -20
- package/src/lib/pageThemes.ts +44 -0
- package/src/lib/sectionContent.ts +106 -107
- package/src/lib/siteNavigation.ts +49 -0
- package/src/lib/sitePages.ts +96 -38
- package/src/pages/{[slug].astro → [...slug].astro} +2 -2
- package/src/pages/index.astro +2 -1
- package/src/styles/global.css +743 -57
- package/starters/basic/README.md +9 -11
- package/starters/basic/site/{content.md → pages/000-home/content.md} +7 -4
- package/starters/basic/site/sitewide-content.yaml +1 -10
- package/starters/basic/site/theme.yaml +1 -105
- package/starters/project/README.md +14 -14
- package/starters/project/site/{content.md → pages/000-home/content.md} +5 -4
- package/starters/project/site/{routes → pages}/010-guide/content.md +5 -4
- package/starters/project/site/sitewide-content.yaml +1 -10
- package/starters/project/site/theme.yaml +1 -31
- package/docs/routes.md +0 -121
- package/examples/feature-demos/media-and-surfaces/site/routes/020-surfaces/theme.yaml +0 -3
- package/examples/feature-demos/sitewide-content/site/content.md +0 -16
- package/examples/feature-demos/sitewide-content/site/routes/010-identity/content.md +0 -20
- package/examples/feature-demos/theme-presets/README.md +0 -18
- package/examples/feature-demos/theme-presets/site/.norna/generated-images.json +0 -290
- package/examples/feature-demos/theme-presets/site/content.md +0 -17
- package/examples/feature-demos/theme-presets/site/sitewide-content.yaml +0 -12
- package/examples/feature-demos/theme-presets/site/theme.yaml +0 -1
- package/fixtures/content-model-v2/site/routes/010-guide/content.md +0 -17
- package/scripts/lib/route-model.mjs +0 -17
- package/scripts/test-route-model.mjs +0 -32
- package/src/lib/routeThemes.ts +0 -41
- /package/examples/complete-sites/dog-shelter-multi-page/site/{images/intro → pages/000-home/images}/shelter-dog.jpg +0 -0
- /package/examples/complete-sites/dog-shelter-multi-page/site/{routes/010-dogs/images/dogs → pages/010-dogs/images}/rex.jpg +0 -0
- /package/examples/complete-sites/dog-shelter-multi-page/site/{routes/010-dogs/images/dogs → pages/010-dogs/images}/rover.jpg +0 -0
- /package/examples/complete-sites/dog-shelter-multi-page/site/{routes/020-adopt/images/adopt → pages/020-adopt/images}/adoption-dog.jpg +0 -0
- /package/examples/complete-sites/dog-shelter-single-page/site/{images/you-can-help → pages/000-home/images}/foster-dog.jpg +0 -0
- /package/examples/complete-sites/dog-shelter-single-page/site/{images/what-we-do → pages/000-home/images}/rescue-dog.jpg +0 -0
- /package/examples/feature-demos/media-and-surfaces/site/{routes/010-media/images/cards → pages/010-media/images}/card-carousel.svg +0 -0
- /package/examples/feature-demos/media-and-surfaces/site/{routes/010-media/images/cards → pages/010-media/images}/card-stack.svg +0 -0
- /package/examples/feature-demos/media-and-surfaces/site/{routes/010-media/images/cards → pages/010-media/images}/card-surfaces.svg +0 -0
- /package/examples/feature-demos/media-and-surfaces/site/{routes/010-media/images/carousel → pages/010-media/images}/carousel-one.svg +0 -0
- /package/examples/feature-demos/media-and-surfaces/site/{routes/010-media/images/carousel → pages/010-media/images}/carousel-three.svg +0 -0
- /package/examples/feature-demos/media-and-surfaces/site/{routes/010-media/images/carousel → pages/010-media/images}/carousel-two.svg +0 -0
- /package/examples/feature-demos/media-and-surfaces/site/{routes/010-media/images/stack → pages/010-media/images}/stack-one.svg +0 -0
- /package/examples/feature-demos/media-and-surfaces/site/{routes/010-media/images/stack → pages/010-media/images}/stack-two.svg +0 -0
- /package/examples/feature-demos/{theme-presets → theme-preset-documentation}/site/config.yaml +0 -0
- /package/examples/feature-demos/{theme-presets/site/routes/020-documentation/images/documentation → theme-preset-documentation/site/pages/000-home/images}/black-schnauzer.jpg +0 -0
- /package/examples/feature-demos/{theme-presets/site/routes/020-documentation/images/documentation → theme-preset-documentation/site/pages/000-home/images}/retriever-portrait.jpg +0 -0
- /package/examples/feature-demos/{theme-presets/site/routes/020-documentation/images/documentation → theme-preset-documentation/site/pages/000-home/images}/schnauzer-portrait.jpg +0 -0
- /package/examples/feature-demos/{theme-presets → theme-preset-documentation}/site/public/robots.txt +0 -0
- /package/examples/feature-demos/{theme-presets/site/routes/020-documentation → theme-preset-documentation/site}/theme.yaml +0 -0
- /package/examples/feature-demos/{theme-presets/site/routes/010-portfolio/images/portfolio → theme-preset-portfolio/site/pages/000-home/images}/puppy-portrait.jpg +0 -0
- /package/examples/feature-demos/{theme-presets/site/routes/010-portfolio/images/portfolio → theme-preset-portfolio/site/pages/000-home/images}/shepherd-portrait.jpg +0 -0
- /package/examples/feature-demos/{theme-presets/site/routes/010-portfolio/images/portfolio → theme-preset-portfolio/site/pages/000-home/images}/white-puppy.jpg +0 -0
- /package/examples/feature-demos/{theme-presets/site/routes/010-portfolio → theme-preset-portfolio/site}/theme.yaml +0 -0
- /package/examples/feature-demos/{theme-presets → theme-preset-project}/.astro/collections/routeTheme.schema.json +0 -0
- /package/examples/feature-demos/{theme-presets → theme-preset-project}/.astro/collections/site.schema.json +0 -0
- /package/examples/feature-demos/{theme-presets → theme-preset-project}/.astro/collections/sitewide.schema.json +0 -0
- /package/examples/feature-demos/{theme-presets → theme-preset-project}/.astro/collections/theme.schema.json +0 -0
- /package/examples/feature-demos/{theme-presets → theme-preset-project}/.astro/content-assets.mjs +0 -0
- /package/examples/feature-demos/{theme-presets → theme-preset-project}/.astro/content-modules.mjs +0 -0
- /package/examples/feature-demos/{theme-presets → theme-preset-project}/.astro/content.d.ts +0 -0
- /package/examples/feature-demos/{theme-presets → theme-preset-project}/.astro/data-store.json +0 -0
- /package/examples/feature-demos/{theme-presets → theme-preset-project}/.astro/dev-local.json +0 -0
- /package/examples/feature-demos/{theme-presets → theme-preset-project}/.astro/dev.json +0 -0
- /package/examples/feature-demos/{theme-presets → theme-preset-project}/.astro/dev.log +0 -0
- /package/examples/feature-demos/{theme-presets → theme-preset-project}/.astro/settings.json +0 -0
- /package/examples/feature-demos/{theme-presets → theme-preset-project}/.astro/types.d.ts +0 -0
- /package/examples/feature-demos/{theme-presets → theme-preset-project}/node_modules/.vite/deps/_metadata.json +0 -0
- /package/examples/feature-demos/{theme-presets → theme-preset-project}/node_modules/.vite/deps/astro-D_GIpJIE.js +0 -0
- /package/examples/feature-demos/{theme-presets → theme-preset-project}/node_modules/.vite/deps/astro-D_GIpJIE.js.map +0 -0
- /package/examples/feature-demos/{theme-presets → theme-preset-project}/node_modules/.vite/deps/astro_n_aria-query.js +0 -0
- /package/examples/feature-demos/{theme-presets → theme-preset-project}/node_modules/.vite/deps/astro_n_aria-query.js.map +0 -0
- /package/examples/feature-demos/{theme-presets → theme-preset-project}/node_modules/.vite/deps/astro_n_axobject-query.js +0 -0
- /package/examples/feature-demos/{theme-presets → theme-preset-project}/node_modules/.vite/deps/astro_n_axobject-query.js.map +0 -0
- /package/examples/feature-demos/{theme-presets → theme-preset-project}/node_modules/.vite/deps/astro_n_html-escaper.js +0 -0
- /package/examples/feature-demos/{theme-presets → theme-preset-project}/node_modules/.vite/deps/astro_n_html-escaper.js.map +0 -0
- /package/examples/feature-demos/{theme-presets → theme-preset-project}/node_modules/.vite/deps/astro_runtime_client_dev-toolbar_entrypoint__js.js +0 -0
- /package/examples/feature-demos/{theme-presets → theme-preset-project}/node_modules/.vite/deps/astro_runtime_client_dev-toolbar_entrypoint__js.js.map +0 -0
- /package/examples/feature-demos/{theme-presets → theme-preset-project}/node_modules/.vite/deps/audit-DM9Hkl5B.js +0 -0
- /package/examples/feature-demos/{theme-presets → theme-preset-project}/node_modules/.vite/deps/audit-DM9Hkl5B.js.map +0 -0
- /package/examples/feature-demos/{theme-presets → theme-preset-project}/node_modules/.vite/deps/embla-carousel.js +0 -0
- /package/examples/feature-demos/{theme-presets → theme-preset-project}/node_modules/.vite/deps/embla-carousel.js.map +0 -0
- /package/examples/feature-demos/{theme-presets → theme-preset-project}/node_modules/.vite/deps/highlight-DnZ1ULOL.js +0 -0
- /package/examples/feature-demos/{theme-presets → theme-preset-project}/node_modules/.vite/deps/highlight-DnZ1ULOL.js.map +0 -0
- /package/examples/feature-demos/{theme-presets → theme-preset-project}/node_modules/.vite/deps/icons-RyebKi45.js +0 -0
- /package/examples/feature-demos/{theme-presets → theme-preset-project}/node_modules/.vite/deps/icons-RyebKi45.js.map +0 -0
- /package/examples/feature-demos/{theme-presets → theme-preset-project}/node_modules/.vite/deps/package.json +0 -0
- /package/examples/feature-demos/{theme-presets → theme-preset-project}/node_modules/.vite/deps/rolldown-runtime-BvCyGRYZ.js +0 -0
- /package/examples/feature-demos/{theme-presets → theme-preset-project}/node_modules/.vite/deps/settings-DaU-gNnK.js +0 -0
- /package/examples/feature-demos/{theme-presets → theme-preset-project}/node_modules/.vite/deps/settings-DaU-gNnK.js.map +0 -0
- /package/examples/feature-demos/{theme-presets → theme-preset-project}/node_modules/.vite/deps/toolbar-63PA619H.js +0 -0
- /package/examples/feature-demos/{theme-presets → theme-preset-project}/node_modules/.vite/deps/toolbar-63PA619H.js.map +0 -0
- /package/examples/feature-demos/{theme-presets → theme-preset-project}/node_modules/.vite/deps/ui-library--bkcNSYz.js +0 -0
- /package/examples/feature-demos/{theme-presets → theme-preset-project}/node_modules/.vite/deps/ui-library--bkcNSYz.js.map +0 -0
- /package/examples/feature-demos/{theme-presets → theme-preset-project}/node_modules/.vite/deps/window-jPkpKVcy.js +0 -0
- /package/examples/feature-demos/{theme-presets → theme-preset-project}/node_modules/.vite/deps/window-jPkpKVcy.js.map +0 -0
- /package/examples/feature-demos/{theme-presets → theme-preset-project}/node_modules/.vite/deps/xray-BXCHpEJP.js +0 -0
- /package/examples/feature-demos/{theme-presets → theme-preset-project}/node_modules/.vite/deps/xray-BXCHpEJP.js.map +0 -0
- /package/examples/feature-demos/{theme-presets/site/routes/030-project/images/project → theme-preset-project/site/pages/000-home/images}/boxer-portrait.jpg +0 -0
- /package/examples/feature-demos/{theme-presets/site/routes/030-project/images/project → theme-preset-project/site/pages/000-home/images}/grass-puppy.jpg +0 -0
- /package/examples/feature-demos/{theme-presets/site/routes/030-project/images/project → theme-preset-project/site/pages/000-home/images}/grey-street-dog.jpg +0 -0
- /package/examples/feature-demos/{theme-presets/site/routes/030-project → theme-preset-project/site}/theme.yaml +0 -0
- /package/examples/feature-demos/{theme-presets/site/routes/040-statement/images/statement → theme-preset-statement/site/pages/000-home/images}/black-pedigree.jpg +0 -0
- /package/examples/feature-demos/{theme-presets/site/routes/040-statement/images/statement → theme-preset-statement/site/pages/000-home/images}/sheepdog-grass.jpg +0 -0
- /package/examples/feature-demos/{theme-presets/site/routes/040-statement/images/statement → theme-preset-statement/site/pages/000-home/images}/sheepdog-wide.jpg +0 -0
- /package/examples/feature-demos/{theme-presets/site/routes/040-statement → theme-preset-statement/site}/theme.yaml +0 -0
- /package/fixtures/basic/site/{images/work → pages/000-home/images}/.gitkeep +0 -0
- /package/fixtures/content-model-v2/site/{images/card-section → pages/000-home/images}/adopt.svg +0 -0
- /package/fixtures/content-model-v2/site/{images/intro → pages/000-home/images}/detail.jpg +0 -0
- /package/fixtures/content-model-v2/site/{images/intro → pages/000-home/images}/duplicate.jpg +0 -0
- /package/fixtures/content-model-v2/site/{images/card-section → pages/000-home/images}/foster.svg +0 -0
- /package/fixtures/content-model-v2/site/{images/intro → pages/000-home/images}/hero.jpg +0 -0
- /package/fixtures/content-model-v2/site/{images/plain → pages/000-home/images}/image.jpg +0 -0
- /package/fixtures/content-model-v2/site/{images/timed → pages/000-home/images}/slide-one.jpg +0 -0
- /package/fixtures/content-model-v2/site/{images/timed → pages/000-home/images}/slide-three.jpg +0 -0
- /package/fixtures/content-model-v2/site/{images/timed → pages/000-home/images}/slide-two.jpg +0 -0
- /package/fixtures/content-model-v2/site/{routes/010-guide/images/intro → pages/010-guide/images}/duplicate.jpg +0 -0
- /package/starters/basic/site/{images/work → pages/000-home/images}/.gitkeep +0 -0
package/README.md
CHANGED
|
@@ -17,7 +17,7 @@ implementing a new presentation layer for every project.
|
|
|
17
17
|
[Live examples](https://janga.github.io/norna/examples/) |
|
|
18
18
|
[npm package](https://www.npmjs.com/package/@janga/norna)
|
|
19
19
|
|
|
20
|
-
[](https://janga.github.io/norna/examples/complete-sites/dog-shelter-multi-page/)
|
|
21
21
|
|
|
22
22
|
The screenshot shows the built
|
|
23
23
|
[multi-page example source](examples/complete-sites/dog-shelter-multi-page/).
|
|
@@ -52,17 +52,23 @@ site/
|
|
|
52
52
|
|-- config.yaml
|
|
53
53
|
|-- theme.yaml
|
|
54
54
|
|-- sitewide-content.yaml
|
|
55
|
-
|--
|
|
56
|
-
|--
|
|
57
|
-
|--
|
|
55
|
+
|-- pages/
|
|
56
|
+
| |-- 000-home/
|
|
57
|
+
| | |-- content.md
|
|
58
|
+
| | `-- images/
|
|
59
|
+
| `-- 010-guide/
|
|
60
|
+
| |-- content.md
|
|
61
|
+
| `-- pages/
|
|
62
|
+
| `-- 010-installation/
|
|
58
63
|
`-- public/
|
|
59
64
|
```
|
|
60
65
|
|
|
61
|
-
- `content.md`
|
|
62
|
-
-
|
|
63
|
-
-
|
|
66
|
+
- `pages/000-home/content.md` is the required homepage at `/`.
|
|
67
|
+
- Other top-level directories under `pages/` are global navigation roots.
|
|
68
|
+
- A page may contain local images, limited presentation settings, and nested
|
|
69
|
+
child pages under its own `pages/` directory.
|
|
64
70
|
- `theme.yaml` normally selects one complete visual preset.
|
|
65
|
-
- `sitewide-content.yaml` holds shared
|
|
71
|
+
- `sitewide-content.yaml` holds shared logo display settings, banners, and footer content.
|
|
66
72
|
- `config.yaml` holds the public URL and optional language and scroll behavior.
|
|
67
73
|
- `public/` holds static files copied without processing.
|
|
68
74
|
|
|
@@ -89,7 +95,10 @@ documentation.
|
|
|
89
95
|
| --- | --- | --- |
|
|
90
96
|
| Dog shelter, single page | [Open demo](https://janga.github.io/norna/examples/complete-sites/dog-shelter-single-page/) | [View files](examples/complete-sites/dog-shelter-single-page/) |
|
|
91
97
|
| Dog shelter, multi-page | [Open demo](https://janga.github.io/norna/examples/complete-sites/dog-shelter-multi-page/) | [View files](examples/complete-sites/dog-shelter-multi-page/) |
|
|
92
|
-
|
|
|
98
|
+
| Portfolio preset | [Open demo](https://janga.github.io/norna/examples/feature-demos/theme-preset-portfolio/) | [View files](examples/feature-demos/theme-preset-portfolio/) |
|
|
99
|
+
| Documentation preset | [Open demo](https://janga.github.io/norna/examples/feature-demos/theme-preset-documentation/) | [View files](examples/feature-demos/theme-preset-documentation/) |
|
|
100
|
+
| Project preset | [Open demo](https://janga.github.io/norna/examples/feature-demos/theme-preset-project/) | [View files](examples/feature-demos/theme-preset-project/) |
|
|
101
|
+
| Statement preset | [Open demo](https://janga.github.io/norna/examples/feature-demos/theme-preset-statement/) | [View files](examples/feature-demos/theme-preset-statement/) |
|
|
93
102
|
| Media and surfaces | [Open demo](https://janga.github.io/norna/examples/feature-demos/media-and-surfaces/) | [View files](examples/feature-demos/media-and-surfaces/) |
|
|
94
103
|
| Sitewide content | [Open demo](https://janga.github.io/norna/examples/feature-demos/sitewide-content/) | [View files](examples/feature-demos/sitewide-content/) |
|
|
95
104
|
|
package/astro.config.mjs
CHANGED
|
@@ -3,6 +3,7 @@ import { execFile } from 'node:child_process';
|
|
|
3
3
|
import path from 'node:path';
|
|
4
4
|
import { promisify } from 'node:util';
|
|
5
5
|
import { defineConfig } from 'astro/config';
|
|
6
|
+
import { getBasePathRedirectLocation } from './scripts/lib/base-path-redirect.mjs';
|
|
6
7
|
import {
|
|
7
8
|
astroCacheDir,
|
|
8
9
|
astroDistDir,
|
|
@@ -12,7 +13,7 @@ import {
|
|
|
12
13
|
siteContentPath,
|
|
13
14
|
siteImagesDir,
|
|
14
15
|
siteProjectRoot,
|
|
15
|
-
|
|
16
|
+
sitePagesDir,
|
|
16
17
|
} from './scripts/lib/site-paths.mjs';
|
|
17
18
|
import projectConfig from './scripts/lib/project-config.mjs';
|
|
18
19
|
|
|
@@ -28,6 +29,37 @@ const runGenerateImages = () => execFileAsync(process.execPath, [path.join(engin
|
|
|
28
29
|
maxBuffer: 1024 * 1024 * 10,
|
|
29
30
|
});
|
|
30
31
|
|
|
32
|
+
const nornaBasePathRedirect = () => {
|
|
33
|
+
const middleware = (request, response, next) => {
|
|
34
|
+
if (!request.url) {
|
|
35
|
+
next();
|
|
36
|
+
return;
|
|
37
|
+
}
|
|
38
|
+
|
|
39
|
+
const redirectLocation = getBasePathRedirectLocation(projectConfig.site.basePath, request.url);
|
|
40
|
+
if (!redirectLocation) {
|
|
41
|
+
next();
|
|
42
|
+
return;
|
|
43
|
+
}
|
|
44
|
+
|
|
45
|
+
response.statusCode = 308;
|
|
46
|
+
response.setHeader('Location', redirectLocation);
|
|
47
|
+
response.end();
|
|
48
|
+
};
|
|
49
|
+
|
|
50
|
+
return {
|
|
51
|
+
name: 'norna-base-path-redirect',
|
|
52
|
+
configureServer(server) {
|
|
53
|
+
return () => {
|
|
54
|
+
server.middlewares.stack.unshift({ route: '', handle: middleware });
|
|
55
|
+
};
|
|
56
|
+
},
|
|
57
|
+
configurePreviewServer(server) {
|
|
58
|
+
server.middlewares.use(middleware);
|
|
59
|
+
},
|
|
60
|
+
};
|
|
61
|
+
};
|
|
62
|
+
|
|
31
63
|
const nornaGeneratedImagesWatcher = () => ({
|
|
32
64
|
name: 'norna-generated-images-watcher',
|
|
33
65
|
configureServer(server) {
|
|
@@ -35,7 +67,7 @@ const nornaGeneratedImagesWatcher = () => ({
|
|
|
35
67
|
const watchedSourcePaths = [
|
|
36
68
|
siteContentPath,
|
|
37
69
|
siteImagesDir,
|
|
38
|
-
|
|
70
|
+
sitePagesDir,
|
|
39
71
|
].map((watchedPath) => path.resolve(watchedPath));
|
|
40
72
|
let refreshTimer;
|
|
41
73
|
let refreshPromise = Promise.resolve();
|
|
@@ -90,6 +122,6 @@ export default defineConfig({
|
|
|
90
122
|
publicDir: astroPublicDir,
|
|
91
123
|
srcDir: path.join(engineRoot, 'src'),
|
|
92
124
|
vite: {
|
|
93
|
-
plugins: [nornaGeneratedImagesWatcher()],
|
|
125
|
+
plugins: [nornaBasePathRedirect(), nornaGeneratedImagesWatcher()],
|
|
94
126
|
},
|
|
95
127
|
});
|
package/bin/norna-cli.mjs
CHANGED
|
@@ -16,7 +16,7 @@ Commands:
|
|
|
16
16
|
dev:stop Stop local dev server
|
|
17
17
|
check Validate configuration and content
|
|
18
18
|
config:check Validate site/config.yaml
|
|
19
|
-
content:check Validate
|
|
19
|
+
content:check Validate page content and managed image references
|
|
20
20
|
content:sync Move misplaced Norna-managed images and refresh generated images
|
|
21
21
|
theme:presets List available theme presets and their intended uses
|
|
22
22
|
theme:export Export a commented theme preset reference
|
package/docs/README.md
CHANGED
|
@@ -27,9 +27,12 @@ site/
|
|
|
27
27
|
|-- config.yaml
|
|
28
28
|
|-- theme.yaml
|
|
29
29
|
|-- sitewide-content.yaml
|
|
30
|
-
|--
|
|
31
|
-
|--
|
|
32
|
-
|--
|
|
30
|
+
|-- pages/
|
|
31
|
+
| |-- 000-home/
|
|
32
|
+
| | |-- content.md
|
|
33
|
+
| | `-- images/
|
|
34
|
+
| `-- 010-guide/
|
|
35
|
+
| `-- content.md
|
|
33
36
|
`-- public/
|
|
34
37
|
```
|
|
35
38
|
|
|
@@ -37,14 +40,13 @@ site/
|
|
|
37
40
|
scroll behavior.
|
|
38
41
|
- [`theme.yaml`](theme.md): complete visual presets and focused presentation
|
|
39
42
|
overrides.
|
|
40
|
-
- [`sitewide-content.yaml`](sitewide-content.md): shared
|
|
43
|
+
- [`sitewide-content.yaml`](sitewide-content.md): shared logo display settings,
|
|
41
44
|
banners, and footer.
|
|
42
|
-
- [`
|
|
43
|
-
|
|
44
|
-
|
|
45
|
-
|
|
46
|
-
|
|
47
|
-
route-local images.
|
|
45
|
+
- [`pages/`](pages.md): Home, top-level areas, nested pages, ordering, and URLs.
|
|
46
|
+
- [`content.md`](content.md): the content file inside every page directory,
|
|
47
|
+
containing its title, optional metadata, sections, prose, notes, and blocks.
|
|
48
|
+
- [`images/`](images-and-metadata.md): managed images kept inside the page that
|
|
49
|
+
references them, plus variants, sync, and generated image state.
|
|
48
50
|
- [`public/`](public-files.md): navigation logos, favicons, and other static
|
|
49
51
|
files copied without managed-image processing.
|
|
50
52
|
- [Generated files](site-files.md#generated-files): `site/.norna/public/`,
|
|
@@ -67,7 +69,7 @@ required, optional, convention-discovered, versioned, or generated.
|
|
|
67
69
|
- [Write page sections](content.md#sections)
|
|
68
70
|
- [Use image stacks, carousels, and cards](content.md#norna-blocks)
|
|
69
71
|
- [Add notes to prose](content.md#markdown-text)
|
|
70
|
-
- [Add another page](
|
|
72
|
+
- [Add another page](pages.md)
|
|
71
73
|
- [Add shared banners or footer content](sitewide-content.md)
|
|
72
74
|
|
|
73
75
|
### Work With Images And Public Assets
|
|
@@ -75,14 +77,14 @@ required, optional, convention-discovered, versioned, or generated.
|
|
|
75
77
|
- [Add managed source images](images-and-metadata.md#managed-source-images)
|
|
76
78
|
- [Check and sync moved image references](content.md#validation-and-sync)
|
|
77
79
|
- [Add a navigation logo](public-files.md#navigation-logo)
|
|
78
|
-
- [Add
|
|
80
|
+
- [Add browser icons](public-files.md#browser-icons)
|
|
79
81
|
- [Add other static files](public-files.md#other-static-files)
|
|
80
82
|
|
|
81
83
|
### Change Presentation
|
|
82
84
|
|
|
83
85
|
- [Choose a complete theme preset](theme.md#theme-presets)
|
|
84
86
|
- [Inspect and override a preset](theme.md#overrides)
|
|
85
|
-
- [
|
|
87
|
+
- [Adjust limited presentation for a page subtree](theme.md#page-themes)
|
|
86
88
|
- [Adjust typography](typography.md)
|
|
87
89
|
|
|
88
90
|
### Check, Build, And Publish
|
|
@@ -95,7 +97,7 @@ required, optional, convention-discovered, versioned, or generated.
|
|
|
95
97
|
## Concepts And Explanation
|
|
96
98
|
|
|
97
99
|
- [Norna's site model](https://janga.github.io/norna/concepts/) explains how
|
|
98
|
-
files, sections, images, and
|
|
100
|
+
files, sections, images, and pages become a website.
|
|
99
101
|
- [Images and Metadata](images-and-metadata.md) explains managed variants and
|
|
100
102
|
published URLs.
|
|
101
103
|
- [Command Organization](design/command-organization.md) explains standalone,
|
package/docs/commands.md
CHANGED
|
@@ -119,7 +119,7 @@ should normally mean the repository's complete publishable artifact, while
|
|
|
119
119
|
inline styles, and common content mistakes.
|
|
120
120
|
- `content:sync` / `norna:sync`: moves misplaced referenced image files after
|
|
121
121
|
confirmation when the intended move is unambiguous. Moving files between the
|
|
122
|
-
homepage and
|
|
122
|
+
homepage and an additional page, or between additional pages, requires a clean Git working tree.
|
|
123
123
|
- `theme:presets`: lists the available complete theme presets and explains the
|
|
124
124
|
intended use of each one.
|
|
125
125
|
- `theme:export <preset>`: writes a protected, commented
|
|
@@ -129,7 +129,7 @@ should normally mean the repository's complete publishable artifact, while
|
|
|
129
129
|
- `typography profiles`: prints the exact built-in values for typography
|
|
130
130
|
profiles and rhythms.
|
|
131
131
|
- `typography show`: prints the selected site's resolved typography for the
|
|
132
|
-
theme, every page
|
|
132
|
+
theme, every page, and every section. Each value includes its source,
|
|
133
133
|
and inherited page or section values are marked with `inherited: true`.
|
|
134
134
|
- `site:public`: copies `site/public/` into `site/.norna/public/` and
|
|
135
135
|
removes stale copied static files.
|
package/docs/configuration.md
CHANGED
|
@@ -13,7 +13,7 @@ url: https://example.com/
|
|
|
13
13
|
Norna deliberately keeps this file small. Visual choices belong in
|
|
14
14
|
[`theme.yaml`](theme.md), shared editorial content belongs in
|
|
15
15
|
[`sitewide-content.yaml`](sitewide-content.md), and page content belongs in
|
|
16
|
-
[`content.md`](content.md).
|
|
16
|
+
[`pages/*/content.md`](content.md).
|
|
17
17
|
|
|
18
18
|
## `url`
|
|
19
19
|
|
|
@@ -58,6 +58,26 @@ would be misleading.
|
|
|
58
58
|
Interface labels are part of the engine and are not configured individually.
|
|
59
59
|
Editorial text remains in page content and `sitewide-content.yaml`.
|
|
60
60
|
|
|
61
|
+
## `navigation`
|
|
62
|
+
|
|
63
|
+
`navigation.mode` selects the site-wide navigation model:
|
|
64
|
+
|
|
65
|
+
- `automatic`: choose from the discovered page and heading structure. This is
|
|
66
|
+
the default.
|
|
67
|
+
- `sections`: navigate headings on a single page.
|
|
68
|
+
- `top`: use the sticky top navigation for a shallow multi-page site.
|
|
69
|
+
- `tree`: combine global top-level navigation with a local page hierarchy.
|
|
70
|
+
|
|
71
|
+
```yaml
|
|
72
|
+
url: https://example.com/
|
|
73
|
+
navigation:
|
|
74
|
+
mode: automatic
|
|
75
|
+
```
|
|
76
|
+
|
|
77
|
+
Navigation behavior is technical and site-wide. It cannot be configured in
|
|
78
|
+
`theme.yaml` or in an individual page. See [Pages](pages.md#navigation) for the
|
|
79
|
+
relationship between Home, top-level pages, child pages, and headings.
|
|
80
|
+
|
|
61
81
|
## `scrollBehavior`
|
|
62
82
|
|
|
63
83
|
- Purpose: select native same-page anchor movement.
|
|
@@ -80,6 +100,8 @@ requests reduced motion always get immediate anchor movement.
|
|
|
80
100
|
```yaml
|
|
81
101
|
url: https://example.com/
|
|
82
102
|
language: en-GB
|
|
103
|
+
navigation:
|
|
104
|
+
mode: automatic
|
|
83
105
|
scrollBehavior: instant
|
|
84
106
|
```
|
|
85
107
|
|
|
@@ -110,7 +132,8 @@ norna --site-dir presentation build
|
|
|
110
132
|
|
|
111
133
|
If `NORNA_SITE_DIR` is set to an empty value, commands fail. Relative site
|
|
112
134
|
directories are resolved by walking upward from the invocation directory until
|
|
113
|
-
the selected directory contains `config.yaml` and
|
|
135
|
+
the selected directory contains `config.yaml` and
|
|
136
|
+
`pages/000-home/content.md`.
|
|
114
137
|
|
|
115
138
|
Without an explicit selection, the current directory itself can be the site
|
|
116
139
|
directory when it contains those two files. Otherwise Norna walks upward for a
|
package/docs/content.md
CHANGED
|
@@ -1,36 +1,63 @@
|
|
|
1
1
|
# Content
|
|
2
2
|
|
|
3
|
-
`site/content.md` is the homepage
|
|
4
|
-
|
|
3
|
+
`site/pages/000-home/content.md` is the homepage file for a Norna site. Its Markdown H1 is
|
|
4
|
+
the page title. Optional page metadata can be added in YAML frontmatter.
|
|
5
5
|
|
|
6
|
-
|
|
7
|
-
`site/
|
|
8
|
-
route-specific rules.
|
|
6
|
+
Additional and nested pages use the same page model in a page directory under
|
|
7
|
+
`site/pages/`. See [Pages](pages.md) for the directory and nesting rules.
|
|
9
8
|
|
|
10
9
|
Site-wide visual defaults belong in [Theme](theme.md). Typography profiles and
|
|
11
10
|
overrides are described in [Typography](typography.md). Technical site settings
|
|
12
11
|
belong in [Configuration](configuration.md).
|
|
13
12
|
|
|
14
|
-
## Page Frontmatter
|
|
13
|
+
## Page Title And Frontmatter
|
|
15
14
|
|
|
16
|
-
|
|
15
|
+
Every page must contain exactly one Markdown H1. It must be the first heading,
|
|
16
|
+
must not have a section id, and supplies the visible page title, HTML document
|
|
17
|
+
title, and page label in site navigation:
|
|
17
18
|
|
|
18
|
-
|
|
19
|
-
|
|
20
|
-
|
|
21
|
-
|
|
19
|
+
```md
|
|
20
|
+
# My Site
|
|
21
|
+
```
|
|
22
|
+
|
|
23
|
+
Content between the H1 and the first H2 is the page introduction. It may
|
|
24
|
+
contain prose and Norna blocks.
|
|
25
|
+
|
|
26
|
+
Frontmatter is optional. When present, the content schema validates these
|
|
27
|
+
top-level fields:
|
|
28
|
+
|
|
29
|
+
- `page`: optional page metadata.
|
|
30
|
+
- `navigation`: optional page-listing metadata. See [Pages](pages.md).
|
|
31
|
+
|
|
32
|
+
`page` contains:
|
|
33
|
+
|
|
34
|
+
- `description`: optional string. Used only as the page's HTML meta description
|
|
35
|
+
for search engines, link previews, and other metadata consumers. It is not
|
|
36
|
+
rendered as visible page content.
|
|
37
|
+
|
|
38
|
+
Minimal homepage without metadata:
|
|
39
|
+
|
|
40
|
+
```md
|
|
41
|
+
# My Site
|
|
42
|
+
|
|
43
|
+
Introductory text.
|
|
44
|
+
|
|
45
|
+
## Work {#work}
|
|
46
|
+
|
|
47
|
+
Text...
|
|
48
|
+
```
|
|
22
49
|
|
|
23
|
-
|
|
50
|
+
Homepage with a meta description:
|
|
24
51
|
|
|
25
52
|
```md
|
|
26
53
|
---
|
|
27
|
-
|
|
28
|
-
description: A small Norna site.
|
|
54
|
+
page:
|
|
55
|
+
description: A small Norna site.
|
|
29
56
|
---
|
|
30
57
|
|
|
31
|
-
|
|
58
|
+
# My Site
|
|
32
59
|
|
|
33
|
-
|
|
60
|
+
Introductory text.
|
|
34
61
|
```
|
|
35
62
|
|
|
36
63
|
## Sections
|
|
@@ -51,44 +78,29 @@ Markdown level 2 headings define the page sections and their order:
|
|
|
51
78
|
...
|
|
52
79
|
```
|
|
53
80
|
|
|
54
|
-
|
|
81
|
+
Norna derives a stable lowercase id from the heading text when no explicit id
|
|
82
|
+
is present:
|
|
55
83
|
|
|
56
84
|
```md
|
|
57
|
-
## Work
|
|
58
|
-
```
|
|
59
|
-
|
|
60
|
-
The id must match `^[a-z0-9-]+$`. It is used for anchors, navigation, image
|
|
61
|
-
directories, and optional section metadata. The visible section navigation
|
|
62
|
-
label comes from the Markdown heading text.
|
|
63
|
-
|
|
64
|
-
Markdown section content starts at the level 2 heading and continues until the
|
|
65
|
-
next level 2 heading. `###` and `####` headings are body subheadings within the
|
|
66
|
-
current section, not new sections.
|
|
67
|
-
|
|
68
|
-
## Section Metadata
|
|
69
|
-
|
|
70
|
-
Use `sections` only when a section needs structured metadata that is not
|
|
71
|
-
naturally expressed by Markdown. Currently this is date-based visibility.
|
|
72
|
-
|
|
73
|
-
```yaml
|
|
74
|
-
sections:
|
|
75
|
-
work:
|
|
76
|
-
visible:
|
|
77
|
-
from: "2026-08-01"
|
|
78
|
-
until: "2026-09-16"
|
|
85
|
+
## Work
|
|
79
86
|
```
|
|
80
87
|
|
|
81
|
-
|
|
82
|
-
|
|
83
|
-
Each `sections.<section-id>` key must match a Markdown heading id in the same
|
|
84
|
-
page file:
|
|
88
|
+
Add an explicit id when a public anchor must remain stable even if the heading
|
|
89
|
+
text changes:
|
|
85
90
|
|
|
86
91
|
```md
|
|
87
92
|
## Work {#work}
|
|
88
93
|
```
|
|
89
94
|
|
|
90
|
-
|
|
91
|
-
from the
|
|
95
|
+
Explicit ids must match `^[a-z0-9-]+$`. Derived and explicit ids are used for
|
|
96
|
+
anchors and section navigation; the visible label still comes from the heading
|
|
97
|
+
text. H3 headings use the same derivation for deeper local navigation. If two
|
|
98
|
+
headings on one page resolve to the same id, `content:check` reports the page
|
|
99
|
+
and both headings instead of guessing.
|
|
100
|
+
|
|
101
|
+
Markdown section content starts at the level 2 heading and continues until the
|
|
102
|
+
next level 2 heading. `###` and `####` headings are body subheadings within the
|
|
103
|
+
current section, not new sections.
|
|
92
104
|
|
|
93
105
|
## Norna Blocks
|
|
94
106
|
|
|
@@ -97,6 +109,8 @@ the point where they should appear in the section. Markdown determines
|
|
|
97
109
|
placement: move the fenced block in the page file to move the rendered image,
|
|
98
110
|
carousel, or card list.
|
|
99
111
|
|
|
112
|
+
### Image Stack
|
|
113
|
+
|
|
100
114
|
Use `norna-image-stack` for one or more stacked images:
|
|
101
115
|
|
|
102
116
|
````md
|
|
@@ -107,6 +121,8 @@ Use `norna-image-stack` for one or more stacked images:
|
|
|
107
121
|
```
|
|
108
122
|
````
|
|
109
123
|
|
|
124
|
+
### Image Carousel
|
|
125
|
+
|
|
110
126
|
Use `norna-image-carousel` for a carousel:
|
|
111
127
|
|
|
112
128
|
````md
|
|
@@ -120,6 +136,8 @@ Use `norna-image-carousel` for a carousel:
|
|
|
120
136
|
```
|
|
121
137
|
````
|
|
122
138
|
|
|
139
|
+
### Card List
|
|
140
|
+
|
|
123
141
|
Use `norna-card-list` for a list of compact cards. Cards can include text,
|
|
124
142
|
managed images, links, and optional badge text:
|
|
125
143
|
|
|
@@ -198,13 +216,13 @@ sizing is less predictable.
|
|
|
198
216
|
Homepage images live under:
|
|
199
217
|
|
|
200
218
|
```text
|
|
201
|
-
site/images
|
|
219
|
+
site/pages/000-home/images/
|
|
202
220
|
```
|
|
203
221
|
|
|
204
|
-
|
|
222
|
+
Images for any page live directly under that page directory. For example:
|
|
205
223
|
|
|
206
224
|
```text
|
|
207
|
-
site/
|
|
225
|
+
site/pages/010-guide/pages/020-installation/images/
|
|
208
226
|
```
|
|
209
227
|
|
|
210
228
|
Image references in Norna managed image blocks use only the filename:
|
|
@@ -215,13 +233,15 @@ Image references in Norna managed image blocks use only the filename:
|
|
|
215
233
|
```
|
|
216
234
|
````
|
|
217
235
|
|
|
218
|
-
If `portrait.jpg` is referenced
|
|
219
|
-
location is `site/images/
|
|
236
|
+
If `portrait.jpg` is referenced anywhere on the homepage, its expected
|
|
237
|
+
location is `site/pages/000-home/images/portrait.jpg`. The same file may be referenced from
|
|
238
|
+
more than one section on that page.
|
|
220
239
|
|
|
221
|
-
Filenames
|
|
222
|
-
|
|
223
|
-
|
|
224
|
-
exists, Norna reports the
|
|
240
|
+
Filenames must be unique within one page's image directory, but do not have to
|
|
241
|
+
be globally unique across the site. Automatic sync only moves files between
|
|
242
|
+
page image roots when the filename identifies exactly one source candidate
|
|
243
|
+
across the site. If more than one candidate exists, Norna reports the
|
|
244
|
+
ambiguity instead of guessing.
|
|
225
245
|
|
|
226
246
|
## Markdown Images
|
|
227
247
|
|
|
@@ -237,36 +257,6 @@ managed by Norna. Use `norna-image-stack`, `norna-image-carousel`, or
|
|
|
237
257
|
`norna-card-list` for local site images that should be validated, processed and
|
|
238
258
|
synced.
|
|
239
259
|
|
|
240
|
-
## Temporary Sections
|
|
241
|
-
|
|
242
|
-
Use `sections.<section-id>.visible` for sections that should be rendered only
|
|
243
|
-
during a date window:
|
|
244
|
-
|
|
245
|
-
```yaml
|
|
246
|
-
sections:
|
|
247
|
-
exhibition:
|
|
248
|
-
visible:
|
|
249
|
-
from: "2026-08-01"
|
|
250
|
-
until: "2026-09-16"
|
|
251
|
-
```
|
|
252
|
-
|
|
253
|
-
`from` is inclusive. `until` is exclusive. With the example above, the section
|
|
254
|
-
is visible from 2026-08-01 through 2026-09-15 and hidden again on 2026-09-16.
|
|
255
|
-
|
|
256
|
-
Both `from` and `until` use `YYYY-MM-DD`. Either value may be omitted, but a
|
|
257
|
-
`visible` object must contain at least one of them.
|
|
258
|
-
|
|
259
|
-
Hidden sections are omitted from the rendered HTML and sticky navigation. They
|
|
260
|
-
remain in the page file, and `content:check` still validates their matching
|
|
261
|
-
Markdown headings and image references.
|
|
262
|
-
|
|
263
|
-
The current date is evaluated at dev/build time. Set `NORNA_TODAY` to preview
|
|
264
|
-
or test a specific date:
|
|
265
|
-
|
|
266
|
-
```sh
|
|
267
|
-
NORNA_TODAY=2026-08-15 npm run norna:build
|
|
268
|
-
```
|
|
269
|
-
|
|
270
260
|
## Markdown Text
|
|
271
261
|
|
|
272
262
|
Use ordinary Markdown for emphasis and structure:
|
|
@@ -277,7 +267,7 @@ This sentence contains **important text** and *emphasised text*.
|
|
|
277
267
|
|
|
278
268
|
Norna intentionally does not support arbitrary inline color or style classes.
|
|
279
269
|
Deprecated syntax such as `[highlighted text]{.yellow}` is rejected by
|
|
280
|
-
`content:check`. Keep the
|
|
270
|
+
`content:check`. Keep the page visually coherent through its `theme.yaml`
|
|
281
271
|
instead of styling individual phrases.
|
|
282
272
|
|
|
283
273
|
### Side Notes
|
|
@@ -315,7 +305,7 @@ Run:
|
|
|
315
305
|
npm run norna:content:check
|
|
316
306
|
```
|
|
317
307
|
|
|
318
|
-
This checks section heading ids,
|
|
308
|
+
This checks section heading ids, duplicate image names,
|
|
319
309
|
missing image files, misplaced referenced images, duplicate image references,
|
|
320
310
|
invalid Norna blocks, unreferenced images, removed inline style syntax,
|
|
321
311
|
Markdown image references to unmanaged local files, and common frontmatter
|
|
@@ -327,15 +317,12 @@ invalid, when a key is indented under a line that already has a value, or when a
|
|
|
327
317
|
known nested key appears at the top level:
|
|
328
318
|
|
|
329
319
|
```yaml
|
|
330
|
-
|
|
331
|
-
|
|
332
|
-
visible:
|
|
333
|
-
from: "2026-08-01"
|
|
320
|
+
navigation:
|
|
321
|
+
listed: false
|
|
334
322
|
```
|
|
335
323
|
|
|
336
|
-
Top-level page frontmatter may contain only `
|
|
337
|
-
|
|
338
|
-
`theme.yaml`.
|
|
324
|
+
Top-level page frontmatter may contain only `page` and `navigation`. Visual
|
|
325
|
+
settings belong in the root or page-local `theme.yaml`.
|
|
339
326
|
|
|
340
327
|
Run:
|
|
341
328
|
|
|
@@ -343,20 +330,22 @@ Run:
|
|
|
343
330
|
npm run norna:sync
|
|
344
331
|
```
|
|
345
332
|
|
|
346
|
-
This moves referenced image files into the
|
|
347
|
-
|
|
333
|
+
This moves referenced image files into the image directory for the page that
|
|
334
|
+
references them. Moving a block between sections on the same page does not
|
|
335
|
+
move the file because all sections share the page image directory. The command
|
|
336
|
+
prompts before writing unless `--yes` is passed.
|
|
348
337
|
|
|
349
338
|
`content:sync` is intentionally conservative. It only moves a file when the
|
|
350
|
-
filename identifies exactly one matching source candidate across
|
|
351
|
-
|
|
339
|
+
filename identifies exactly one matching source candidate across all page
|
|
340
|
+
image roots, and when the move will not break another reference.
|
|
352
341
|
If the intended move is ambiguous, rename or move the file manually and run
|
|
353
342
|
`content:check` again.
|
|
354
343
|
|
|
355
|
-
|
|
356
|
-
|
|
357
|
-
|
|
344
|
+
The same filename may exist in different page image directories. Automatic
|
|
345
|
+
relocation only requires site-wide filename uniqueness for the file being
|
|
346
|
+
moved.
|
|
358
347
|
|
|
359
|
-
When `content:sync` needs to move an image between the homepage and a
|
|
360
|
-
between two
|
|
361
|
-
keeps cross-
|
|
348
|
+
When `content:sync` needs to move an image between the homepage and a page, or
|
|
349
|
+
between two pages, the Git working tree must be clean before the write. This
|
|
350
|
+
keeps cross-page sync easy to roll back. `content:check` only reports issues
|
|
362
351
|
and does not require a clean working tree.
|