@janga/norna 0.7.18 → 0.7.23

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
Files changed (615) hide show
  1. package/README.md +22 -12
  2. package/astro.config.mjs +25 -0
  3. package/bin/norna-cli.mjs +8 -2
  4. package/package.json +60 -13
  5. package/schemas/category.schema.json +20 -0
  6. package/schemas/config.schema.json +22 -14
  7. package/schemas/content-frontmatter.schema.json +25 -5
  8. package/schemas/manifest.json +2 -1
  9. package/schemas/page-theme.schema.json +58 -30
  10. package/schemas/sitewide-content.schema.json +20 -19
  11. package/schemas/theme.schema.json +542 -243
  12. package/scripts/add-site-node.mjs +251 -0
  13. package/scripts/check-config.mjs +32 -4
  14. package/scripts/deploy-site.mjs +5 -9
  15. package/scripts/dev-local.mjs +175 -112
  16. package/scripts/generate-images.mjs +11 -15
  17. package/scripts/generate-schemas.mjs +4 -1
  18. package/scripts/init-site.mjs +35 -0
  19. package/scripts/lib/astro-command.mjs +14 -9
  20. package/scripts/lib/content-sync-apply.mjs +34 -0
  21. package/scripts/lib/content-sync-plan.mjs +179 -0
  22. package/scripts/lib/editor-language-service.mjs +156 -177
  23. package/scripts/lib/heading-ids.mjs +4 -2
  24. package/scripts/lib/image-presentation.mjs +2 -0
  25. package/scripts/lib/markdown-links.mjs +182 -0
  26. package/scripts/lib/navigation-model.mjs +36 -19
  27. package/scripts/lib/norna-markdown-blocks.mjs +65 -145
  28. package/scripts/lib/norna-markdown-render-plugin.mjs +37 -0
  29. package/scripts/lib/object.mjs +28 -0
  30. package/scripts/lib/page-aliases.mjs +164 -0
  31. package/scripts/lib/page-markdown.mjs +332 -0
  32. package/scripts/lib/presentation-contract.mjs +266 -0
  33. package/scripts/lib/presentation-palette-metadata.mjs +51 -0
  34. package/scripts/lib/presentation.mjs +508 -79
  35. package/scripts/lib/project-config.mjs +78 -10
  36. package/scripts/lib/schema-definitions.mjs +67 -16
  37. package/scripts/lib/schema-editor-metadata.mjs +126 -24
  38. package/scripts/lib/schema-value-definitions.mjs +30 -12
  39. package/scripts/lib/site-content.mjs +46 -239
  40. package/scripts/lib/site-link-graph.mjs +326 -0
  41. package/scripts/lib/site-page-urls.mjs +10 -0
  42. package/scripts/lib/site-paths.mjs +2 -3
  43. package/scripts/lib/site-structure.mjs +189 -0
  44. package/scripts/lib/sitemap.mjs +34 -0
  45. package/scripts/lib/theme-presets.mjs +118 -119
  46. package/scripts/lib/theme-profiles.mjs +223 -0
  47. package/scripts/lib/typography.mjs +220 -35
  48. package/scripts/lib/yaml-config.mjs +50 -6
  49. package/scripts/lib/yaml-indentation.mjs +86 -0
  50. package/scripts/show-typography.mjs +2 -3
  51. package/scripts/sync-content-sections.mjs +158 -244
  52. package/scripts/sync-site-public.mjs +23 -2
  53. package/src/components/CodeBlockCopyScript.astro +92 -0
  54. package/src/components/DisplaySettings.astro +107 -0
  55. package/src/components/ImageCarousel.astro +38 -13
  56. package/src/components/NavigationPageTree.astro +103 -88
  57. package/src/components/PageAliasRedirect.astro +49 -0
  58. package/src/components/PageContentsNavigation.astro +21 -0
  59. package/src/components/SectionNavigationScript.astro +112 -2
  60. package/src/components/SiteBreadcrumbs.astro +15 -12
  61. package/src/components/SiteNavigation.astro +104 -41
  62. package/src/components/SitePage.astro +76 -40
  63. package/src/components/SiteSection.astro +40 -191
  64. package/src/components/SiteTreeNavigation.astro +10 -10
  65. package/src/content.config.ts +5 -2
  66. package/src/layouts/BaseLayout.astro +55 -9
  67. package/src/lib/generatedImages.ts +0 -7
  68. package/src/lib/readerPreferencesScript.mjs +141 -0
  69. package/src/lib/sectionContent.ts +119 -201
  70. package/src/lib/siteNavigation.ts +36 -18
  71. package/src/lib/sitePages.ts +92 -20
  72. package/src/pages/[...slug].astro +35 -8
  73. package/src/styles/content.css +494 -0
  74. package/src/styles/foundations.css +284 -0
  75. package/src/styles/global.css +6 -2047
  76. package/src/styles/media.css +523 -0
  77. package/src/styles/navigation.css +495 -0
  78. package/src/styles/page-layout.css +437 -0
  79. package/src/styles/responsive.css +525 -0
  80. package/starters/basic/README.md +3 -3
  81. package/docs/README.md +0 -137
  82. package/docs/assets/norna-dog-shelter.jpg +0 -0
  83. package/docs/commands.md +0 -189
  84. package/docs/configuration.md +0 -142
  85. package/docs/content.md +0 -351
  86. package/docs/design/command-organization.md +0 -414
  87. package/docs/design/navigation-and-theme-plan.md +0 -186
  88. package/docs/design/norna-diagram-design.md +0 -159
  89. package/docs/design/site-examples-structure.md +0 -119
  90. package/docs/engine-development.md +0 -215
  91. package/docs/getting-started.md +0 -206
  92. package/docs/how-to/embedded-site.md +0 -35
  93. package/docs/images-and-metadata.md +0 -188
  94. package/docs/local-development.md +0 -82
  95. package/docs/pages.md +0 -190
  96. package/docs/public-files.md +0 -118
  97. package/docs/publishing.md +0 -117
  98. package/docs/requirements.md +0 -54
  99. package/docs/site-files.md +0 -152
  100. package/docs/sitewide-content.md +0 -73
  101. package/docs/theme.md +0 -237
  102. package/docs/typography.md +0 -168
  103. package/examples/README.md +0 -49
  104. package/examples/complete-sites/dog-shelter-multi-page/.astro/collections/site.schema.json +0 -35
  105. package/examples/complete-sites/dog-shelter-multi-page/.astro/collections/sitewide.schema.json +0 -97
  106. package/examples/complete-sites/dog-shelter-multi-page/.astro/collections/theme.schema.json +0 -852
  107. package/examples/complete-sites/dog-shelter-multi-page/.astro/content-assets.mjs +0 -4
  108. package/examples/complete-sites/dog-shelter-multi-page/.astro/content-modules.mjs +0 -1
  109. package/examples/complete-sites/dog-shelter-multi-page/.astro/content.d.ts +0 -183
  110. package/examples/complete-sites/dog-shelter-multi-page/.astro/data-store.json +0 -1
  111. package/examples/complete-sites/dog-shelter-multi-page/.astro/dev-local.json +0 -8
  112. package/examples/complete-sites/dog-shelter-multi-page/.astro/dev.json +0 -13
  113. package/examples/complete-sites/dog-shelter-multi-page/.astro/dev.log +0 -36
  114. package/examples/complete-sites/dog-shelter-multi-page/.astro/settings.json +0 -5
  115. package/examples/complete-sites/dog-shelter-multi-page/.astro/types.d.ts +0 -2
  116. package/examples/complete-sites/dog-shelter-multi-page/README.md +0 -24
  117. package/examples/complete-sites/dog-shelter-multi-page/node_modules/.vite/deps/_metadata.json +0 -74
  118. package/examples/complete-sites/dog-shelter-multi-page/node_modules/.vite/deps/astro-B3JHJyiv.js +0 -434
  119. package/examples/complete-sites/dog-shelter-multi-page/node_modules/.vite/deps/astro-B3JHJyiv.js.map +0 -1
  120. package/examples/complete-sites/dog-shelter-multi-page/node_modules/.vite/deps/astro_n_aria-query.js +0 -6390
  121. package/examples/complete-sites/dog-shelter-multi-page/node_modules/.vite/deps/astro_n_aria-query.js.map +0 -1
  122. package/examples/complete-sites/dog-shelter-multi-page/node_modules/.vite/deps/astro_n_axobject-query.js +0 -2702
  123. package/examples/complete-sites/dog-shelter-multi-page/node_modules/.vite/deps/astro_n_axobject-query.js.map +0 -1
  124. package/examples/complete-sites/dog-shelter-multi-page/node_modules/.vite/deps/astro_n_html-escaper.js +0 -65
  125. package/examples/complete-sites/dog-shelter-multi-page/node_modules/.vite/deps/astro_n_html-escaper.js.map +0 -1
  126. package/examples/complete-sites/dog-shelter-multi-page/node_modules/.vite/deps/astro_runtime_client_dev-toolbar_entrypoint__js.js +0 -455
  127. package/examples/complete-sites/dog-shelter-multi-page/node_modules/.vite/deps/astro_runtime_client_dev-toolbar_entrypoint__js.js.map +0 -1
  128. package/examples/complete-sites/dog-shelter-multi-page/node_modules/.vite/deps/audit-C3SVr7dT.js +0 -1534
  129. package/examples/complete-sites/dog-shelter-multi-page/node_modules/.vite/deps/audit-C3SVr7dT.js.map +0 -1
  130. package/examples/complete-sites/dog-shelter-multi-page/node_modules/.vite/deps/highlight-BLtvqtzO.js +0 -48
  131. package/examples/complete-sites/dog-shelter-multi-page/node_modules/.vite/deps/highlight-BLtvqtzO.js.map +0 -1
  132. package/examples/complete-sites/dog-shelter-multi-page/node_modules/.vite/deps/icons-C92i61-2.js +0 -42
  133. package/examples/complete-sites/dog-shelter-multi-page/node_modules/.vite/deps/icons-C92i61-2.js.map +0 -1
  134. package/examples/complete-sites/dog-shelter-multi-page/node_modules/.vite/deps/package.json +0 -3
  135. package/examples/complete-sites/dog-shelter-multi-page/node_modules/.vite/deps/rolldown-runtime-BvCyGRYZ.js +0 -4
  136. package/examples/complete-sites/dog-shelter-multi-page/node_modules/.vite/deps/settings-v5GgKks_.js +0 -190
  137. package/examples/complete-sites/dog-shelter-multi-page/node_modules/.vite/deps/settings-v5GgKks_.js.map +0 -1
  138. package/examples/complete-sites/dog-shelter-multi-page/node_modules/.vite/deps/toolbar-BFvJVp26.js +0 -458
  139. package/examples/complete-sites/dog-shelter-multi-page/node_modules/.vite/deps/toolbar-BFvJVp26.js.map +0 -1
  140. package/examples/complete-sites/dog-shelter-multi-page/node_modules/.vite/deps/ui-library-Cd35oAvo.js +0 -1016
  141. package/examples/complete-sites/dog-shelter-multi-page/node_modules/.vite/deps/ui-library-Cd35oAvo.js.map +0 -1
  142. package/examples/complete-sites/dog-shelter-multi-page/node_modules/.vite/deps/window-vo3A6TMn.js +0 -32
  143. package/examples/complete-sites/dog-shelter-multi-page/node_modules/.vite/deps/window-vo3A6TMn.js.map +0 -1
  144. package/examples/complete-sites/dog-shelter-multi-page/node_modules/.vite/deps/xray-DwhzGckb.js +0 -111
  145. package/examples/complete-sites/dog-shelter-multi-page/node_modules/.vite/deps/xray-DwhzGckb.js.map +0 -1
  146. package/examples/complete-sites/dog-shelter-multi-page/site/.norna/generated-images.json +0 -98
  147. package/examples/complete-sites/dog-shelter-multi-page/site/config.yaml +0 -1
  148. package/examples/complete-sites/dog-shelter-multi-page/site/pages/000-home/content.md +0 -23
  149. package/examples/complete-sites/dog-shelter-multi-page/site/pages/000-home/images/shelter-dog.jpg +0 -0
  150. package/examples/complete-sites/dog-shelter-multi-page/site/pages/010-dogs/content.md +0 -21
  151. package/examples/complete-sites/dog-shelter-multi-page/site/pages/010-dogs/images/rex.jpg +0 -0
  152. package/examples/complete-sites/dog-shelter-multi-page/site/pages/010-dogs/images/rover.jpg +0 -0
  153. package/examples/complete-sites/dog-shelter-multi-page/site/pages/020-adopt/content.md +0 -22
  154. package/examples/complete-sites/dog-shelter-multi-page/site/pages/020-adopt/images/adoption-dog.jpg +0 -0
  155. package/examples/complete-sites/dog-shelter-multi-page/site/public/favicon.svg +0 -10
  156. package/examples/complete-sites/dog-shelter-multi-page/site/public/logo.svg +0 -9
  157. package/examples/complete-sites/dog-shelter-multi-page/site/public/robots.txt +0 -2
  158. package/examples/complete-sites/dog-shelter-multi-page/site/sitewide-content.yaml +0 -4
  159. package/examples/complete-sites/dog-shelter-multi-page/site/theme.yaml +0 -1
  160. package/examples/complete-sites/dog-shelter-single-page/.astro/collections/site.schema.json +0 -35
  161. package/examples/complete-sites/dog-shelter-single-page/.astro/collections/sitewide.schema.json +0 -97
  162. package/examples/complete-sites/dog-shelter-single-page/.astro/collections/theme.schema.json +0 -852
  163. package/examples/complete-sites/dog-shelter-single-page/.astro/content-assets.mjs +0 -4
  164. package/examples/complete-sites/dog-shelter-single-page/.astro/content-modules.mjs +0 -1
  165. package/examples/complete-sites/dog-shelter-single-page/.astro/content.d.ts +0 -183
  166. package/examples/complete-sites/dog-shelter-single-page/.astro/data-store.json +0 -1
  167. package/examples/complete-sites/dog-shelter-single-page/.astro/dev-local.json +0 -8
  168. package/examples/complete-sites/dog-shelter-single-page/.astro/dev.json +0 -13
  169. package/examples/complete-sites/dog-shelter-single-page/.astro/dev.log +0 -18
  170. package/examples/complete-sites/dog-shelter-single-page/.astro/settings.json +0 -5
  171. package/examples/complete-sites/dog-shelter-single-page/.astro/types.d.ts +0 -2
  172. package/examples/complete-sites/dog-shelter-single-page/README.md +0 -24
  173. package/examples/complete-sites/dog-shelter-single-page/node_modules/.vite/deps/_metadata.json +0 -74
  174. package/examples/complete-sites/dog-shelter-single-page/node_modules/.vite/deps/astro-B3JHJyiv.js +0 -434
  175. package/examples/complete-sites/dog-shelter-single-page/node_modules/.vite/deps/astro-B3JHJyiv.js.map +0 -1
  176. package/examples/complete-sites/dog-shelter-single-page/node_modules/.vite/deps/astro_n_aria-query.js +0 -6390
  177. package/examples/complete-sites/dog-shelter-single-page/node_modules/.vite/deps/astro_n_aria-query.js.map +0 -1
  178. package/examples/complete-sites/dog-shelter-single-page/node_modules/.vite/deps/astro_n_axobject-query.js +0 -2702
  179. package/examples/complete-sites/dog-shelter-single-page/node_modules/.vite/deps/astro_n_axobject-query.js.map +0 -1
  180. package/examples/complete-sites/dog-shelter-single-page/node_modules/.vite/deps/astro_n_html-escaper.js +0 -65
  181. package/examples/complete-sites/dog-shelter-single-page/node_modules/.vite/deps/astro_n_html-escaper.js.map +0 -1
  182. package/examples/complete-sites/dog-shelter-single-page/node_modules/.vite/deps/astro_runtime_client_dev-toolbar_entrypoint__js.js +0 -455
  183. package/examples/complete-sites/dog-shelter-single-page/node_modules/.vite/deps/astro_runtime_client_dev-toolbar_entrypoint__js.js.map +0 -1
  184. package/examples/complete-sites/dog-shelter-single-page/node_modules/.vite/deps/audit-C3SVr7dT.js +0 -1534
  185. package/examples/complete-sites/dog-shelter-single-page/node_modules/.vite/deps/audit-C3SVr7dT.js.map +0 -1
  186. package/examples/complete-sites/dog-shelter-single-page/node_modules/.vite/deps/highlight-BLtvqtzO.js +0 -48
  187. package/examples/complete-sites/dog-shelter-single-page/node_modules/.vite/deps/highlight-BLtvqtzO.js.map +0 -1
  188. package/examples/complete-sites/dog-shelter-single-page/node_modules/.vite/deps/icons-C92i61-2.js +0 -42
  189. package/examples/complete-sites/dog-shelter-single-page/node_modules/.vite/deps/icons-C92i61-2.js.map +0 -1
  190. package/examples/complete-sites/dog-shelter-single-page/node_modules/.vite/deps/package.json +0 -3
  191. package/examples/complete-sites/dog-shelter-single-page/node_modules/.vite/deps/rolldown-runtime-BvCyGRYZ.js +0 -4
  192. package/examples/complete-sites/dog-shelter-single-page/node_modules/.vite/deps/settings-v5GgKks_.js +0 -190
  193. package/examples/complete-sites/dog-shelter-single-page/node_modules/.vite/deps/settings-v5GgKks_.js.map +0 -1
  194. package/examples/complete-sites/dog-shelter-single-page/node_modules/.vite/deps/toolbar-BFvJVp26.js +0 -458
  195. package/examples/complete-sites/dog-shelter-single-page/node_modules/.vite/deps/toolbar-BFvJVp26.js.map +0 -1
  196. package/examples/complete-sites/dog-shelter-single-page/node_modules/.vite/deps/ui-library-Cd35oAvo.js +0 -1016
  197. package/examples/complete-sites/dog-shelter-single-page/node_modules/.vite/deps/ui-library-Cd35oAvo.js.map +0 -1
  198. package/examples/complete-sites/dog-shelter-single-page/node_modules/.vite/deps/window-vo3A6TMn.js +0 -32
  199. package/examples/complete-sites/dog-shelter-single-page/node_modules/.vite/deps/window-vo3A6TMn.js.map +0 -1
  200. package/examples/complete-sites/dog-shelter-single-page/node_modules/.vite/deps/xray-DwhzGckb.js +0 -111
  201. package/examples/complete-sites/dog-shelter-single-page/node_modules/.vite/deps/xray-DwhzGckb.js.map +0 -1
  202. package/examples/complete-sites/dog-shelter-single-page/site/.norna/generated-images.json +0 -50
  203. package/examples/complete-sites/dog-shelter-single-page/site/config.yaml +0 -1
  204. package/examples/complete-sites/dog-shelter-single-page/site/pages/000-home/content.md +0 -37
  205. package/examples/complete-sites/dog-shelter-single-page/site/pages/000-home/images/foster-dog.jpg +0 -0
  206. package/examples/complete-sites/dog-shelter-single-page/site/pages/000-home/images/rescue-dog.jpg +0 -0
  207. package/examples/complete-sites/dog-shelter-single-page/site/public/favicon.svg +0 -10
  208. package/examples/complete-sites/dog-shelter-single-page/site/public/logo.svg +0 -9
  209. package/examples/complete-sites/dog-shelter-single-page/site/public/robots.txt +0 -2
  210. package/examples/complete-sites/dog-shelter-single-page/site/sitewide-content.yaml +0 -4
  211. package/examples/complete-sites/dog-shelter-single-page/site/theme.yaml +0 -1
  212. package/examples/feature-demos/media-and-surfaces/.astro/collections/site.schema.json +0 -35
  213. package/examples/feature-demos/media-and-surfaces/.astro/collections/sitewide.schema.json +0 -97
  214. package/examples/feature-demos/media-and-surfaces/.astro/collections/theme.schema.json +0 -844
  215. package/examples/feature-demos/media-and-surfaces/.astro/content-assets.mjs +0 -4
  216. package/examples/feature-demos/media-and-surfaces/.astro/content-modules.mjs +0 -1
  217. package/examples/feature-demos/media-and-surfaces/.astro/content.d.ts +0 -183
  218. package/examples/feature-demos/media-and-surfaces/.astro/data-store.json +0 -1
  219. package/examples/feature-demos/media-and-surfaces/.astro/dev.log +0 -14
  220. package/examples/feature-demos/media-and-surfaces/.astro/settings.json +0 -5
  221. package/examples/feature-demos/media-and-surfaces/.astro/types.d.ts +0 -2
  222. package/examples/feature-demos/media-and-surfaces/README.md +0 -21
  223. package/examples/feature-demos/media-and-surfaces/node_modules/.vite/deps/_metadata.json +0 -80
  224. package/examples/feature-demos/media-and-surfaces/node_modules/.vite/deps/astro-B3JHJyiv.js +0 -434
  225. package/examples/feature-demos/media-and-surfaces/node_modules/.vite/deps/astro-B3JHJyiv.js.map +0 -1
  226. package/examples/feature-demos/media-and-surfaces/node_modules/.vite/deps/astro_n_aria-query.js +0 -6390
  227. package/examples/feature-demos/media-and-surfaces/node_modules/.vite/deps/astro_n_aria-query.js.map +0 -1
  228. package/examples/feature-demos/media-and-surfaces/node_modules/.vite/deps/astro_n_axobject-query.js +0 -2702
  229. package/examples/feature-demos/media-and-surfaces/node_modules/.vite/deps/astro_n_axobject-query.js.map +0 -1
  230. package/examples/feature-demos/media-and-surfaces/node_modules/.vite/deps/astro_n_html-escaper.js +0 -65
  231. package/examples/feature-demos/media-and-surfaces/node_modules/.vite/deps/astro_n_html-escaper.js.map +0 -1
  232. package/examples/feature-demos/media-and-surfaces/node_modules/.vite/deps/astro_runtime_client_dev-toolbar_entrypoint__js.js +0 -455
  233. package/examples/feature-demos/media-and-surfaces/node_modules/.vite/deps/astro_runtime_client_dev-toolbar_entrypoint__js.js.map +0 -1
  234. package/examples/feature-demos/media-and-surfaces/node_modules/.vite/deps/audit-C3SVr7dT.js +0 -1534
  235. package/examples/feature-demos/media-and-surfaces/node_modules/.vite/deps/audit-C3SVr7dT.js.map +0 -1
  236. package/examples/feature-demos/media-and-surfaces/node_modules/.vite/deps/embla-carousel.js +0 -1389
  237. package/examples/feature-demos/media-and-surfaces/node_modules/.vite/deps/embla-carousel.js.map +0 -1
  238. package/examples/feature-demos/media-and-surfaces/node_modules/.vite/deps/highlight-BLtvqtzO.js +0 -48
  239. package/examples/feature-demos/media-and-surfaces/node_modules/.vite/deps/highlight-BLtvqtzO.js.map +0 -1
  240. package/examples/feature-demos/media-and-surfaces/node_modules/.vite/deps/icons-C92i61-2.js +0 -42
  241. package/examples/feature-demos/media-and-surfaces/node_modules/.vite/deps/icons-C92i61-2.js.map +0 -1
  242. package/examples/feature-demos/media-and-surfaces/node_modules/.vite/deps/package.json +0 -3
  243. package/examples/feature-demos/media-and-surfaces/node_modules/.vite/deps/rolldown-runtime-BvCyGRYZ.js +0 -4
  244. package/examples/feature-demos/media-and-surfaces/node_modules/.vite/deps/settings-v5GgKks_.js +0 -190
  245. package/examples/feature-demos/media-and-surfaces/node_modules/.vite/deps/settings-v5GgKks_.js.map +0 -1
  246. package/examples/feature-demos/media-and-surfaces/node_modules/.vite/deps/toolbar-BFvJVp26.js +0 -458
  247. package/examples/feature-demos/media-and-surfaces/node_modules/.vite/deps/toolbar-BFvJVp26.js.map +0 -1
  248. package/examples/feature-demos/media-and-surfaces/node_modules/.vite/deps/ui-library-Cd35oAvo.js +0 -1016
  249. package/examples/feature-demos/media-and-surfaces/node_modules/.vite/deps/ui-library-Cd35oAvo.js.map +0 -1
  250. package/examples/feature-demos/media-and-surfaces/node_modules/.vite/deps/window-vo3A6TMn.js +0 -32
  251. package/examples/feature-demos/media-and-surfaces/node_modules/.vite/deps/window-vo3A6TMn.js.map +0 -1
  252. package/examples/feature-demos/media-and-surfaces/node_modules/.vite/deps/xray-DwhzGckb.js +0 -111
  253. package/examples/feature-demos/media-and-surfaces/node_modules/.vite/deps/xray-DwhzGckb.js.map +0 -1
  254. package/examples/feature-demos/media-and-surfaces/site/.norna/generated-images.json +0 -66
  255. package/examples/feature-demos/media-and-surfaces/site/config.yaml +0 -1
  256. package/examples/feature-demos/media-and-surfaces/site/pages/000-home/content.md +0 -15
  257. package/examples/feature-demos/media-and-surfaces/site/pages/010-media/content.md +0 -71
  258. package/examples/feature-demos/media-and-surfaces/site/pages/010-media/images/card-carousel.svg +0 -11
  259. package/examples/feature-demos/media-and-surfaces/site/pages/010-media/images/card-stack.svg +0 -9
  260. package/examples/feature-demos/media-and-surfaces/site/pages/010-media/images/card-surfaces.svg +0 -8
  261. package/examples/feature-demos/media-and-surfaces/site/pages/010-media/images/carousel-one.svg +0 -8
  262. package/examples/feature-demos/media-and-surfaces/site/pages/010-media/images/carousel-three.svg +0 -13
  263. package/examples/feature-demos/media-and-surfaces/site/pages/010-media/images/carousel-two.svg +0 -8
  264. package/examples/feature-demos/media-and-surfaces/site/pages/010-media/images/stack-one.svg +0 -8
  265. package/examples/feature-demos/media-and-surfaces/site/pages/010-media/images/stack-two.svg +0 -9
  266. package/examples/feature-demos/media-and-surfaces/site/pages/020-surfaces/content.md +0 -42
  267. package/examples/feature-demos/media-and-surfaces/site/pages/020-surfaces/theme.yaml +0 -2
  268. package/examples/feature-demos/media-and-surfaces/site/public/robots.txt +0 -2
  269. package/examples/feature-demos/media-and-surfaces/site/sitewide-content.yaml +0 -2
  270. package/examples/feature-demos/media-and-surfaces/site/theme.yaml +0 -1
  271. package/examples/feature-demos/sitewide-content/.astro/collections/site.schema.json +0 -59
  272. package/examples/feature-demos/sitewide-content/.astro/collections/sitewide.schema.json +0 -138
  273. package/examples/feature-demos/sitewide-content/.astro/collections/theme.schema.json +0 -755
  274. package/examples/feature-demos/sitewide-content/.astro/content-assets.mjs +0 -1
  275. package/examples/feature-demos/sitewide-content/.astro/content-modules.mjs +0 -1
  276. package/examples/feature-demos/sitewide-content/.astro/content.d.ts +0 -183
  277. package/examples/feature-demos/sitewide-content/.astro/data-store.json +0 -1
  278. package/examples/feature-demos/sitewide-content/.astro/dev.json +0 -13
  279. package/examples/feature-demos/sitewide-content/.astro/dev.log +0 -18
  280. package/examples/feature-demos/sitewide-content/.astro/settings.json +0 -5
  281. package/examples/feature-demos/sitewide-content/.astro/types.d.ts +0 -2
  282. package/examples/feature-demos/sitewide-content/README.md +0 -26
  283. package/examples/feature-demos/sitewide-content/node_modules/.vite/deps/_metadata.json +0 -74
  284. package/examples/feature-demos/sitewide-content/node_modules/.vite/deps/astro-B3JHJyiv.js +0 -434
  285. package/examples/feature-demos/sitewide-content/node_modules/.vite/deps/astro-B3JHJyiv.js.map +0 -1
  286. package/examples/feature-demos/sitewide-content/node_modules/.vite/deps/astro_n_aria-query.js +0 -6390
  287. package/examples/feature-demos/sitewide-content/node_modules/.vite/deps/astro_n_aria-query.js.map +0 -1
  288. package/examples/feature-demos/sitewide-content/node_modules/.vite/deps/astro_n_axobject-query.js +0 -2702
  289. package/examples/feature-demos/sitewide-content/node_modules/.vite/deps/astro_n_axobject-query.js.map +0 -1
  290. package/examples/feature-demos/sitewide-content/node_modules/.vite/deps/astro_n_html-escaper.js +0 -65
  291. package/examples/feature-demos/sitewide-content/node_modules/.vite/deps/astro_n_html-escaper.js.map +0 -1
  292. package/examples/feature-demos/sitewide-content/node_modules/.vite/deps/astro_runtime_client_dev-toolbar_entrypoint__js.js +0 -455
  293. package/examples/feature-demos/sitewide-content/node_modules/.vite/deps/astro_runtime_client_dev-toolbar_entrypoint__js.js.map +0 -1
  294. package/examples/feature-demos/sitewide-content/node_modules/.vite/deps/audit-C3SVr7dT.js +0 -1534
  295. package/examples/feature-demos/sitewide-content/node_modules/.vite/deps/audit-C3SVr7dT.js.map +0 -1
  296. package/examples/feature-demos/sitewide-content/node_modules/.vite/deps/highlight-BLtvqtzO.js +0 -48
  297. package/examples/feature-demos/sitewide-content/node_modules/.vite/deps/highlight-BLtvqtzO.js.map +0 -1
  298. package/examples/feature-demos/sitewide-content/node_modules/.vite/deps/icons-C92i61-2.js +0 -42
  299. package/examples/feature-demos/sitewide-content/node_modules/.vite/deps/icons-C92i61-2.js.map +0 -1
  300. package/examples/feature-demos/sitewide-content/node_modules/.vite/deps/package.json +0 -3
  301. package/examples/feature-demos/sitewide-content/node_modules/.vite/deps/rolldown-runtime-BvCyGRYZ.js +0 -4
  302. package/examples/feature-demos/sitewide-content/node_modules/.vite/deps/settings-v5GgKks_.js +0 -190
  303. package/examples/feature-demos/sitewide-content/node_modules/.vite/deps/settings-v5GgKks_.js.map +0 -1
  304. package/examples/feature-demos/sitewide-content/node_modules/.vite/deps/toolbar-BFvJVp26.js +0 -458
  305. package/examples/feature-demos/sitewide-content/node_modules/.vite/deps/toolbar-BFvJVp26.js.map +0 -1
  306. package/examples/feature-demos/sitewide-content/node_modules/.vite/deps/ui-library-Cd35oAvo.js +0 -1016
  307. package/examples/feature-demos/sitewide-content/node_modules/.vite/deps/ui-library-Cd35oAvo.js.map +0 -1
  308. package/examples/feature-demos/sitewide-content/node_modules/.vite/deps/window-vo3A6TMn.js +0 -32
  309. package/examples/feature-demos/sitewide-content/node_modules/.vite/deps/window-vo3A6TMn.js.map +0 -1
  310. package/examples/feature-demos/sitewide-content/node_modules/.vite/deps/xray-DwhzGckb.js +0 -111
  311. package/examples/feature-demos/sitewide-content/node_modules/.vite/deps/xray-DwhzGckb.js.map +0 -1
  312. package/examples/feature-demos/sitewide-content/site/.norna/generated-images.json +0 -1
  313. package/examples/feature-demos/sitewide-content/site/config.yaml +0 -1
  314. package/examples/feature-demos/sitewide-content/site/pages/000-home/content.md +0 -17
  315. package/examples/feature-demos/sitewide-content/site/pages/010-logo-and-navigation/content.md +0 -17
  316. package/examples/feature-demos/sitewide-content/site/pages/020-notices/content.md +0 -23
  317. package/examples/feature-demos/sitewide-content/site/pages/030-footer/content.md +0 -18
  318. package/examples/feature-demos/sitewide-content/site/public/logo.svg +0 -6
  319. package/examples/feature-demos/sitewide-content/site/public/robots.txt +0 -2
  320. package/examples/feature-demos/sitewide-content/site/sitewide-content.yaml +0 -14
  321. package/examples/feature-demos/sitewide-content/site/theme.yaml +0 -1
  322. package/examples/feature-demos/theme-preset-documentation/README.md +0 -16
  323. package/examples/feature-demos/theme-preset-documentation/site/.norna/generated-images.json +0 -74
  324. package/examples/feature-demos/theme-preset-documentation/site/config.yaml +0 -1
  325. package/examples/feature-demos/theme-preset-documentation/site/pages/000-home/content.md +0 -30
  326. package/examples/feature-demos/theme-preset-documentation/site/pages/000-home/images/black-schnauzer.jpg +0 -0
  327. package/examples/feature-demos/theme-preset-documentation/site/pages/000-home/images/retriever-portrait.jpg +0 -0
  328. package/examples/feature-demos/theme-preset-documentation/site/pages/000-home/images/schnauzer-portrait.jpg +0 -0
  329. package/examples/feature-demos/theme-preset-documentation/site/public/robots.txt +0 -2
  330. package/examples/feature-demos/theme-preset-documentation/site/sitewide-content.yaml +0 -3
  331. package/examples/feature-demos/theme-preset-documentation/site/theme.yaml +0 -1
  332. package/examples/feature-demos/theme-preset-portfolio/README.md +0 -16
  333. package/examples/feature-demos/theme-preset-portfolio/site/.norna/generated-images.json +0 -74
  334. package/examples/feature-demos/theme-preset-portfolio/site/config.yaml +0 -1
  335. package/examples/feature-demos/theme-preset-portfolio/site/pages/000-home/content.md +0 -31
  336. package/examples/feature-demos/theme-preset-portfolio/site/pages/000-home/images/puppy-portrait.jpg +0 -0
  337. package/examples/feature-demos/theme-preset-portfolio/site/pages/000-home/images/shepherd-portrait.jpg +0 -0
  338. package/examples/feature-demos/theme-preset-portfolio/site/pages/000-home/images/white-puppy.jpg +0 -0
  339. package/examples/feature-demos/theme-preset-portfolio/site/public/robots.txt +0 -2
  340. package/examples/feature-demos/theme-preset-portfolio/site/sitewide-content.yaml +0 -3
  341. package/examples/feature-demos/theme-preset-portfolio/site/theme.yaml +0 -1
  342. package/examples/feature-demos/theme-preset-project/.astro/collections/routeTheme.schema.json +0 -746
  343. package/examples/feature-demos/theme-preset-project/.astro/collections/site.schema.json +0 -59
  344. package/examples/feature-demos/theme-preset-project/.astro/collections/sitewide.schema.json +0 -138
  345. package/examples/feature-demos/theme-preset-project/.astro/collections/theme.schema.json +0 -755
  346. package/examples/feature-demos/theme-preset-project/.astro/content-assets.mjs +0 -4
  347. package/examples/feature-demos/theme-preset-project/.astro/content-modules.mjs +0 -1
  348. package/examples/feature-demos/theme-preset-project/.astro/content.d.ts +0 -183
  349. package/examples/feature-demos/theme-preset-project/.astro/data-store.json +0 -1
  350. package/examples/feature-demos/theme-preset-project/.astro/dev-local.json +0 -8
  351. package/examples/feature-demos/theme-preset-project/.astro/dev.json +0 -15
  352. package/examples/feature-demos/theme-preset-project/.astro/dev.log +0 -164
  353. package/examples/feature-demos/theme-preset-project/.astro/settings.json +0 -5
  354. package/examples/feature-demos/theme-preset-project/.astro/types.d.ts +0 -2
  355. package/examples/feature-demos/theme-preset-project/README.md +0 -16
  356. package/examples/feature-demos/theme-preset-project/node_modules/.vite/deps/_metadata.json +0 -80
  357. package/examples/feature-demos/theme-preset-project/node_modules/.vite/deps/astro-D_GIpJIE.js +0 -434
  358. package/examples/feature-demos/theme-preset-project/node_modules/.vite/deps/astro-D_GIpJIE.js.map +0 -1
  359. package/examples/feature-demos/theme-preset-project/node_modules/.vite/deps/astro_n_aria-query.js +0 -6390
  360. package/examples/feature-demos/theme-preset-project/node_modules/.vite/deps/astro_n_aria-query.js.map +0 -1
  361. package/examples/feature-demos/theme-preset-project/node_modules/.vite/deps/astro_n_axobject-query.js +0 -2702
  362. package/examples/feature-demos/theme-preset-project/node_modules/.vite/deps/astro_n_axobject-query.js.map +0 -1
  363. package/examples/feature-demos/theme-preset-project/node_modules/.vite/deps/astro_n_html-escaper.js +0 -65
  364. package/examples/feature-demos/theme-preset-project/node_modules/.vite/deps/astro_n_html-escaper.js.map +0 -1
  365. package/examples/feature-demos/theme-preset-project/node_modules/.vite/deps/astro_runtime_client_dev-toolbar_entrypoint__js.js +0 -455
  366. package/examples/feature-demos/theme-preset-project/node_modules/.vite/deps/astro_runtime_client_dev-toolbar_entrypoint__js.js.map +0 -1
  367. package/examples/feature-demos/theme-preset-project/node_modules/.vite/deps/audit-DM9Hkl5B.js +0 -1534
  368. package/examples/feature-demos/theme-preset-project/node_modules/.vite/deps/audit-DM9Hkl5B.js.map +0 -1
  369. package/examples/feature-demos/theme-preset-project/node_modules/.vite/deps/embla-carousel.js +0 -1389
  370. package/examples/feature-demos/theme-preset-project/node_modules/.vite/deps/embla-carousel.js.map +0 -1
  371. package/examples/feature-demos/theme-preset-project/node_modules/.vite/deps/highlight-DnZ1ULOL.js +0 -48
  372. package/examples/feature-demos/theme-preset-project/node_modules/.vite/deps/highlight-DnZ1ULOL.js.map +0 -1
  373. package/examples/feature-demos/theme-preset-project/node_modules/.vite/deps/icons-RyebKi45.js +0 -42
  374. package/examples/feature-demos/theme-preset-project/node_modules/.vite/deps/icons-RyebKi45.js.map +0 -1
  375. package/examples/feature-demos/theme-preset-project/node_modules/.vite/deps/package.json +0 -3
  376. package/examples/feature-demos/theme-preset-project/node_modules/.vite/deps/rolldown-runtime-BvCyGRYZ.js +0 -4
  377. package/examples/feature-demos/theme-preset-project/node_modules/.vite/deps/settings-DaU-gNnK.js +0 -190
  378. package/examples/feature-demos/theme-preset-project/node_modules/.vite/deps/settings-DaU-gNnK.js.map +0 -1
  379. package/examples/feature-demos/theme-preset-project/node_modules/.vite/deps/toolbar-63PA619H.js +0 -458
  380. package/examples/feature-demos/theme-preset-project/node_modules/.vite/deps/toolbar-63PA619H.js.map +0 -1
  381. package/examples/feature-demos/theme-preset-project/node_modules/.vite/deps/ui-library--bkcNSYz.js +0 -1016
  382. package/examples/feature-demos/theme-preset-project/node_modules/.vite/deps/ui-library--bkcNSYz.js.map +0 -1
  383. package/examples/feature-demos/theme-preset-project/node_modules/.vite/deps/window-jPkpKVcy.js +0 -32
  384. package/examples/feature-demos/theme-preset-project/node_modules/.vite/deps/window-jPkpKVcy.js.map +0 -1
  385. package/examples/feature-demos/theme-preset-project/node_modules/.vite/deps/xray-BXCHpEJP.js +0 -111
  386. package/examples/feature-demos/theme-preset-project/node_modules/.vite/deps/xray-BXCHpEJP.js.map +0 -1
  387. package/examples/feature-demos/theme-preset-project/site/.norna/generated-images.json +0 -74
  388. package/examples/feature-demos/theme-preset-project/site/config.yaml +0 -1
  389. package/examples/feature-demos/theme-preset-project/site/pages/000-home/content.md +0 -31
  390. package/examples/feature-demos/theme-preset-project/site/pages/000-home/images/boxer-portrait.jpg +0 -0
  391. package/examples/feature-demos/theme-preset-project/site/pages/000-home/images/grass-puppy.jpg +0 -0
  392. package/examples/feature-demos/theme-preset-project/site/pages/000-home/images/grey-street-dog.jpg +0 -0
  393. package/examples/feature-demos/theme-preset-project/site/public/robots.txt +0 -2
  394. package/examples/feature-demos/theme-preset-project/site/sitewide-content.yaml +0 -3
  395. package/examples/feature-demos/theme-preset-project/site/theme.yaml +0 -1
  396. package/examples/feature-demos/theme-preset-statement/README.md +0 -16
  397. package/examples/feature-demos/theme-preset-statement/site/.norna/generated-images.json +0 -74
  398. package/examples/feature-demos/theme-preset-statement/site/config.yaml +0 -1
  399. package/examples/feature-demos/theme-preset-statement/site/pages/000-home/content.md +0 -31
  400. package/examples/feature-demos/theme-preset-statement/site/pages/000-home/images/black-pedigree.jpg +0 -0
  401. package/examples/feature-demos/theme-preset-statement/site/pages/000-home/images/sheepdog-grass.jpg +0 -0
  402. package/examples/feature-demos/theme-preset-statement/site/pages/000-home/images/sheepdog-wide.jpg +0 -0
  403. package/examples/feature-demos/theme-preset-statement/site/public/robots.txt +0 -2
  404. package/examples/feature-demos/theme-preset-statement/site/sitewide-content.yaml +0 -3
  405. package/examples/feature-demos/theme-preset-statement/site/theme.yaml +0 -1
  406. package/fixtures/basic/site/.norna/generated-images.json +0 -1
  407. package/fixtures/basic/site/config.yaml +0 -1
  408. package/fixtures/basic/site/pages/000-home/content.md +0 -14
  409. package/fixtures/basic/site/pages/000-home/images/.gitkeep +0 -1
  410. package/fixtures/basic/site/public/robots.txt +0 -2
  411. package/fixtures/basic/site/sitewide-content.yaml +0 -3
  412. package/fixtures/basic/site/theme.yaml +0 -1
  413. package/fixtures/content-model-v2/.astro/collections/site.schema.json +0 -776
  414. package/fixtures/content-model-v2/.astro/collections/theme.schema.json +0 -668
  415. package/fixtures/content-model-v2/.astro/content-assets.mjs +0 -4
  416. package/fixtures/content-model-v2/.astro/content-modules.mjs +0 -1
  417. package/fixtures/content-model-v2/.astro/content.d.ts +0 -175
  418. package/fixtures/content-model-v2/.astro/data-store.json +0 -1
  419. package/fixtures/content-model-v2/.astro/dev-local.json +0 -8
  420. package/fixtures/content-model-v2/.astro/dev.json +0 -13
  421. package/fixtures/content-model-v2/.astro/dev.log +0 -231
  422. package/fixtures/content-model-v2/.astro/settings.json +0 -5
  423. package/fixtures/content-model-v2/.astro/types.d.ts +0 -2
  424. package/fixtures/content-model-v2/dist/_astro/GalleryGrid.astro_astro_type_script_index_0_lang.B0kxDyGz.js +0 -1
  425. package/fixtures/content-model-v2/dist/_astro/SitePage.BbfZub4g.css +0 -1
  426. package/fixtures/content-model-v2/dist/guide/index.html +0 -3
  427. package/fixtures/content-model-v2/dist/images/generated/intro/detail-27930b14-480.webp +0 -0
  428. package/fixtures/content-model-v2/dist/images/generated/intro/detail-27930b14-768.webp +0 -0
  429. package/fixtures/content-model-v2/dist/images/generated/intro/detail-27930b14-971.webp +0 -0
  430. package/fixtures/content-model-v2/dist/images/generated/intro/duplicate-49c98f6c-480.webp +0 -0
  431. package/fixtures/content-model-v2/dist/images/generated/intro/duplicate-49c98f6c-768.webp +0 -0
  432. package/fixtures/content-model-v2/dist/images/generated/intro/duplicate-49c98f6c-971.webp +0 -0
  433. package/fixtures/content-model-v2/dist/images/generated/intro/hero-6d588a83-480.webp +0 -0
  434. package/fixtures/content-model-v2/dist/images/generated/intro/hero-6d588a83-768.webp +0 -0
  435. package/fixtures/content-model-v2/dist/images/generated/intro/hero-6d588a83-971.webp +0 -0
  436. package/fixtures/content-model-v2/dist/images/generated/plain/image-3770d763-1080.webp +0 -0
  437. package/fixtures/content-model-v2/dist/images/generated/plain/image-3770d763-1440.webp +0 -0
  438. package/fixtures/content-model-v2/dist/images/generated/plain/image-3770d763-1600.webp +0 -0
  439. package/fixtures/content-model-v2/dist/images/generated/plain/image-3770d763-480.webp +0 -0
  440. package/fixtures/content-model-v2/dist/images/generated/plain/image-3770d763-768.webp +0 -0
  441. package/fixtures/content-model-v2/dist/images/generated/routes/010-guide/images/intro/duplicate-5cf614d2-480.webp +0 -0
  442. package/fixtures/content-model-v2/dist/images/generated/routes/010-guide/images/intro/duplicate-5cf614d2-768.webp +0 -0
  443. package/fixtures/content-model-v2/dist/images/generated/routes/010-guide/images/intro/duplicate-5cf614d2-960.webp +0 -0
  444. package/fixtures/content-model-v2/dist/images/generated/timed/slide-one-3770d763-1080.webp +0 -0
  445. package/fixtures/content-model-v2/dist/images/generated/timed/slide-one-3770d763-1440.webp +0 -0
  446. package/fixtures/content-model-v2/dist/images/generated/timed/slide-one-3770d763-1600.webp +0 -0
  447. package/fixtures/content-model-v2/dist/images/generated/timed/slide-one-3770d763-480.webp +0 -0
  448. package/fixtures/content-model-v2/dist/images/generated/timed/slide-one-3770d763-768.webp +0 -0
  449. package/fixtures/content-model-v2/dist/images/generated/timed/slide-three-5bdec65e-1080.webp +0 -0
  450. package/fixtures/content-model-v2/dist/images/generated/timed/slide-three-5bdec65e-1440.webp +0 -0
  451. package/fixtures/content-model-v2/dist/images/generated/timed/slide-three-5bdec65e-1600.webp +0 -0
  452. package/fixtures/content-model-v2/dist/images/generated/timed/slide-three-5bdec65e-480.webp +0 -0
  453. package/fixtures/content-model-v2/dist/images/generated/timed/slide-three-5bdec65e-768.webp +0 -0
  454. package/fixtures/content-model-v2/dist/images/generated/timed/slide-two-26c08aee-1080.webp +0 -0
  455. package/fixtures/content-model-v2/dist/images/generated/timed/slide-two-26c08aee-1440.webp +0 -0
  456. package/fixtures/content-model-v2/dist/images/generated/timed/slide-two-26c08aee-1600.webp +0 -0
  457. package/fixtures/content-model-v2/dist/images/generated/timed/slide-two-26c08aee-480.webp +0 -0
  458. package/fixtures/content-model-v2/dist/images/generated/timed/slide-two-26c08aee-768.webp +0 -0
  459. package/fixtures/content-model-v2/dist/index.html +0 -8
  460. package/fixtures/content-model-v2/node_modules/.vite/deps/_metadata.json +0 -80
  461. package/fixtures/content-model-v2/node_modules/.vite/deps/astro-D_GIpJIE.js +0 -434
  462. package/fixtures/content-model-v2/node_modules/.vite/deps/astro-D_GIpJIE.js.map +0 -1
  463. package/fixtures/content-model-v2/node_modules/.vite/deps/astro_n_aria-query.js +0 -6390
  464. package/fixtures/content-model-v2/node_modules/.vite/deps/astro_n_aria-query.js.map +0 -1
  465. package/fixtures/content-model-v2/node_modules/.vite/deps/astro_n_axobject-query.js +0 -2702
  466. package/fixtures/content-model-v2/node_modules/.vite/deps/astro_n_axobject-query.js.map +0 -1
  467. package/fixtures/content-model-v2/node_modules/.vite/deps/astro_n_html-escaper.js +0 -65
  468. package/fixtures/content-model-v2/node_modules/.vite/deps/astro_n_html-escaper.js.map +0 -1
  469. package/fixtures/content-model-v2/node_modules/.vite/deps/astro_runtime_client_dev-toolbar_entrypoint__js.js +0 -455
  470. package/fixtures/content-model-v2/node_modules/.vite/deps/astro_runtime_client_dev-toolbar_entrypoint__js.js.map +0 -1
  471. package/fixtures/content-model-v2/node_modules/.vite/deps/audit-DM9Hkl5B.js +0 -1534
  472. package/fixtures/content-model-v2/node_modules/.vite/deps/audit-DM9Hkl5B.js.map +0 -1
  473. package/fixtures/content-model-v2/node_modules/.vite/deps/embla-carousel.js +0 -1389
  474. package/fixtures/content-model-v2/node_modules/.vite/deps/embla-carousel.js.map +0 -1
  475. package/fixtures/content-model-v2/node_modules/.vite/deps/highlight-DnZ1ULOL.js +0 -48
  476. package/fixtures/content-model-v2/node_modules/.vite/deps/highlight-DnZ1ULOL.js.map +0 -1
  477. package/fixtures/content-model-v2/node_modules/.vite/deps/icons-RyebKi45.js +0 -42
  478. package/fixtures/content-model-v2/node_modules/.vite/deps/icons-RyebKi45.js.map +0 -1
  479. package/fixtures/content-model-v2/node_modules/.vite/deps/package.json +0 -3
  480. package/fixtures/content-model-v2/node_modules/.vite/deps/rolldown-runtime-BvCyGRYZ.js +0 -4
  481. package/fixtures/content-model-v2/node_modules/.vite/deps/settings-DaU-gNnK.js +0 -190
  482. package/fixtures/content-model-v2/node_modules/.vite/deps/settings-DaU-gNnK.js.map +0 -1
  483. package/fixtures/content-model-v2/node_modules/.vite/deps/toolbar-63PA619H.js +0 -458
  484. package/fixtures/content-model-v2/node_modules/.vite/deps/toolbar-63PA619H.js.map +0 -1
  485. package/fixtures/content-model-v2/node_modules/.vite/deps/ui-library--bkcNSYz.js +0 -1016
  486. package/fixtures/content-model-v2/node_modules/.vite/deps/ui-library--bkcNSYz.js.map +0 -1
  487. package/fixtures/content-model-v2/node_modules/.vite/deps/window-jPkpKVcy.js +0 -32
  488. package/fixtures/content-model-v2/node_modules/.vite/deps/window-jPkpKVcy.js.map +0 -1
  489. package/fixtures/content-model-v2/node_modules/.vite/deps/xray-BXCHpEJP.js +0 -111
  490. package/fixtures/content-model-v2/node_modules/.vite/deps/xray-BXCHpEJP.js.map +0 -1
  491. package/fixtures/content-model-v2/site/.norna/generated-images.json +0 -210
  492. package/fixtures/content-model-v2/site/config.yaml +0 -1
  493. package/fixtures/content-model-v2/site/pages/000-home/content.md +0 -79
  494. package/fixtures/content-model-v2/site/pages/000-home/images/adopt.svg +0 -9
  495. package/fixtures/content-model-v2/site/pages/000-home/images/detail.jpg +0 -0
  496. package/fixtures/content-model-v2/site/pages/000-home/images/duplicate.jpg +0 -0
  497. package/fixtures/content-model-v2/site/pages/000-home/images/foster.svg +0 -12
  498. package/fixtures/content-model-v2/site/pages/000-home/images/hero.jpg +0 -0
  499. package/fixtures/content-model-v2/site/pages/000-home/images/image.jpg +0 -0
  500. package/fixtures/content-model-v2/site/pages/000-home/images/slide-one.jpg +0 -0
  501. package/fixtures/content-model-v2/site/pages/000-home/images/slide-three.jpg +0 -0
  502. package/fixtures/content-model-v2/site/pages/000-home/images/slide-two.jpg +0 -0
  503. package/fixtures/content-model-v2/site/pages/010-guide/content.md +0 -18
  504. package/fixtures/content-model-v2/site/pages/010-guide/images/duplicate.jpg +0 -0
  505. package/fixtures/content-model-v2/site/theme.yaml +0 -4
  506. package/fixtures/nested-pages/.astro/collections/site.schema.json +0 -35
  507. package/fixtures/nested-pages/.astro/collections/sitewide.schema.json +0 -97
  508. package/fixtures/nested-pages/.astro/collections/theme.schema.json +0 -844
  509. package/fixtures/nested-pages/.astro/content-assets.mjs +0 -4
  510. package/fixtures/nested-pages/.astro/content-modules.mjs +0 -1
  511. package/fixtures/nested-pages/.astro/content.d.ts +0 -183
  512. package/fixtures/nested-pages/.astro/data-store.json +0 -1
  513. package/fixtures/nested-pages/.astro/dev-local.json +0 -8
  514. package/fixtures/nested-pages/.astro/dev.log +0 -1128
  515. package/fixtures/nested-pages/.astro/settings.json +0 -5
  516. package/fixtures/nested-pages/.astro/types.d.ts +0 -2
  517. package/fixtures/nested-pages/node_modules/.vite/deps/_metadata.json +0 -74
  518. package/fixtures/nested-pages/node_modules/.vite/deps/astro-D_GIpJIE.js +0 -434
  519. package/fixtures/nested-pages/node_modules/.vite/deps/astro-D_GIpJIE.js.map +0 -1
  520. package/fixtures/nested-pages/node_modules/.vite/deps/astro_n_aria-query.js +0 -6390
  521. package/fixtures/nested-pages/node_modules/.vite/deps/astro_n_aria-query.js.map +0 -1
  522. package/fixtures/nested-pages/node_modules/.vite/deps/astro_n_axobject-query.js +0 -2702
  523. package/fixtures/nested-pages/node_modules/.vite/deps/astro_n_axobject-query.js.map +0 -1
  524. package/fixtures/nested-pages/node_modules/.vite/deps/astro_n_html-escaper.js +0 -65
  525. package/fixtures/nested-pages/node_modules/.vite/deps/astro_n_html-escaper.js.map +0 -1
  526. package/fixtures/nested-pages/node_modules/.vite/deps/astro_runtime_client_dev-toolbar_entrypoint__js.js +0 -455
  527. package/fixtures/nested-pages/node_modules/.vite/deps/astro_runtime_client_dev-toolbar_entrypoint__js.js.map +0 -1
  528. package/fixtures/nested-pages/node_modules/.vite/deps/audit-DM9Hkl5B.js +0 -1534
  529. package/fixtures/nested-pages/node_modules/.vite/deps/audit-DM9Hkl5B.js.map +0 -1
  530. package/fixtures/nested-pages/node_modules/.vite/deps/highlight-DnZ1ULOL.js +0 -48
  531. package/fixtures/nested-pages/node_modules/.vite/deps/highlight-DnZ1ULOL.js.map +0 -1
  532. package/fixtures/nested-pages/node_modules/.vite/deps/icons-RyebKi45.js +0 -42
  533. package/fixtures/nested-pages/node_modules/.vite/deps/icons-RyebKi45.js.map +0 -1
  534. package/fixtures/nested-pages/node_modules/.vite/deps/package.json +0 -3
  535. package/fixtures/nested-pages/node_modules/.vite/deps/rolldown-runtime-BvCyGRYZ.js +0 -4
  536. package/fixtures/nested-pages/node_modules/.vite/deps/settings-DaU-gNnK.js +0 -190
  537. package/fixtures/nested-pages/node_modules/.vite/deps/settings-DaU-gNnK.js.map +0 -1
  538. package/fixtures/nested-pages/node_modules/.vite/deps/toolbar-63PA619H.js +0 -458
  539. package/fixtures/nested-pages/node_modules/.vite/deps/toolbar-63PA619H.js.map +0 -1
  540. package/fixtures/nested-pages/node_modules/.vite/deps/ui-library--bkcNSYz.js +0 -1016
  541. package/fixtures/nested-pages/node_modules/.vite/deps/ui-library--bkcNSYz.js.map +0 -1
  542. package/fixtures/nested-pages/node_modules/.vite/deps/window-jPkpKVcy.js +0 -32
  543. package/fixtures/nested-pages/node_modules/.vite/deps/window-jPkpKVcy.js.map +0 -1
  544. package/fixtures/nested-pages/node_modules/.vite/deps/xray-BXCHpEJP.js +0 -111
  545. package/fixtures/nested-pages/node_modules/.vite/deps/xray-BXCHpEJP.js.map +0 -1
  546. package/fixtures/nested-pages/site/.norna/generated-images.json +0 -10
  547. package/fixtures/nested-pages/site/config.yaml +0 -3
  548. package/fixtures/nested-pages/site/pages/000-home/content.md +0 -15
  549. package/fixtures/nested-pages/site/pages/010-guides/content.md +0 -15
  550. package/fixtures/nested-pages/site/pages/010-guides/pages/010-installation/content.md +0 -21
  551. package/fixtures/nested-pages/site/pages/010-guides/pages/010-installation/images/diagram.svg +0 -21
  552. package/fixtures/nested-pages/site/pages/010-guides/pages/010-installation/pages/010-macos/content.md +0 -18
  553. package/fixtures/nested-pages/site/pages/010-guides/pages/010-installation/theme.yaml +0 -2
  554. package/fixtures/nested-pages/site/pages/010-guides/pages/020-workflows/content.md +0 -11
  555. package/fixtures/nested-pages/site/pages/010-guides/pages/030-release-notes/content.md +0 -9
  556. package/fixtures/nested-pages/site/pages/010-guides/pages/040-configuration/content.md +0 -3
  557. package/fixtures/nested-pages/site/pages/010-guides/pages/050-content/content.md +0 -3
  558. package/fixtures/nested-pages/site/pages/010-guides/pages/060-themes/content.md +0 -3
  559. package/fixtures/nested-pages/site/pages/010-guides/pages/070-images/content.md +0 -3
  560. package/fixtures/nested-pages/site/pages/010-guides/pages/080-cards/content.md +0 -3
  561. package/fixtures/nested-pages/site/pages/010-guides/pages/090-notes/content.md +0 -3
  562. package/fixtures/nested-pages/site/pages/010-guides/pages/100-validation/content.md +0 -3
  563. package/fixtures/nested-pages/site/pages/010-guides/pages/110-synchronization/content.md +0 -3
  564. package/fixtures/nested-pages/site/pages/010-guides/pages/120-building/content.md +0 -3
  565. package/fixtures/nested-pages/site/pages/010-guides/pages/130-publishing/content.md +0 -3
  566. package/fixtures/nested-pages/site/pages/010-guides/pages/140-troubleshooting/content.md +0 -3
  567. package/fixtures/nested-pages/site/pages/010-guides/pages/150-migration/content.md +0 -3
  568. package/fixtures/nested-pages/site/pages/010-guides/pages/160-accessibility/content.md +0 -3
  569. package/fixtures/nested-pages/site/pages/010-guides/pages/170-performance/content.md +0 -3
  570. package/fixtures/nested-pages/site/pages/010-guides/pages/180-security/content.md +0 -3
  571. package/fixtures/nested-pages/site/pages/010-guides/pages/190-localization/content.md +0 -3
  572. package/fixtures/nested-pages/site/pages/010-guides/pages/200-upgrading/content.md +0 -3
  573. package/fixtures/nested-pages/site/pages/010-guides/pages/210-faq/content.md +0 -3
  574. package/fixtures/nested-pages/site/pages/010-guides/theme.yaml +0 -7
  575. package/fixtures/nested-pages/site/pages/020-reference/content.md +0 -10
  576. package/fixtures/nested-pages/site/pages/020-reference/pages/010-installation/content.md +0 -11
  577. package/fixtures/nested-pages/site/theme.yaml +0 -1
  578. package/scripts/build-pages.mjs +0 -69
  579. package/scripts/lib/example-sites.mjs +0 -49
  580. package/scripts/lib/frontmatter-yaml.mjs +0 -113
  581. package/scripts/lib/git-status.mjs +0 -7
  582. package/scripts/release.mjs +0 -153
  583. package/scripts/test-banner-visibility.mjs +0 -80
  584. package/scripts/test-ci-lockfile.mjs +0 -65
  585. package/scripts/test-cli-discovery.mjs +0 -124
  586. package/scripts/test-client-javascript.mjs +0 -225
  587. package/scripts/test-content-check.mjs +0 -621
  588. package/scripts/test-content-model-v2.mjs +0 -1693
  589. package/scripts/test-documentation.mjs +0 -189
  590. package/scripts/test-editor-language-service.mjs +0 -305
  591. package/scripts/test-engine-commands.mjs +0 -204
  592. package/scripts/test-examples.mjs +0 -53
  593. package/scripts/test-heading-ids.mjs +0 -68
  594. package/scripts/test-navigation-model.mjs +0 -63
  595. package/scripts/test-navigation-preview.mjs +0 -108
  596. package/scripts/test-navigation.mjs +0 -157
  597. package/scripts/test-nested-pages.mjs +0 -125
  598. package/scripts/test-package-check.mjs +0 -500
  599. package/scripts/test-page-model.mjs +0 -108
  600. package/scripts/test-project-config.mjs +0 -139
  601. package/scripts/test-schemas.mjs +0 -169
  602. package/scripts/test-site-public.mjs +0 -85
  603. package/scripts/test-theme-presets.mjs +0 -188
  604. package/src/components/SiteNotesScript.astro +0 -43
  605. package/starters/project/.github/workflows/deploy.yml +0 -64
  606. package/starters/project/README.md +0 -84
  607. package/starters/project/package-lock.json +0 -4296
  608. package/starters/project/package.json +0 -37
  609. package/starters/project/site/config.yaml +0 -1
  610. package/starters/project/site/pages/000-home/content.md +0 -119
  611. package/starters/project/site/pages/010-guide/content.md +0 -80
  612. package/starters/project/site/public/robots.txt +0 -2
  613. package/starters/project/site/sitewide-content.yaml +0 -3
  614. package/starters/project/site/theme.yaml +0 -1
  615. package/tsconfig.json +0 -5
@@ -2,6 +2,7 @@ import { readFile } from 'node:fs/promises';
2
2
  import {
3
3
  validateConfigYamlStructure,
4
4
  } from './site-content.mjs';
5
+ import { defaultImagePresentation, imagePresentationNames } from './image-presentation.mjs';
5
6
  import { navigationModeNames } from './navigation-model.mjs';
6
7
  import {
7
8
  siteConfigLabel,
@@ -184,26 +185,64 @@ const readSiteUrl = (config) => {
184
185
  const localeLabels = Object.freeze({
185
186
  en: Object.freeze({
186
187
  breadcrumb: 'Breadcrumb',
188
+ appearance: 'Appearance',
189
+ appearanceDark: 'Dark',
190
+ appearanceLight: 'Light',
191
+ appearanceSystem: 'System',
192
+ codeCopied: 'Copied',
193
+ codeCopyFailed: 'Could not copy code',
194
+ copyCode: 'Copy code',
195
+ displaySettings: 'Display',
196
+ focusReading: 'Focus reading',
197
+ readingWidth: 'Reading width',
198
+ readingWidthNarrow: 'Narrow',
199
+ readingWidthStandard: 'Standard',
200
+ readingWidthWide: 'Wide',
201
+ resetDisplaySettings: 'Reset',
187
202
  dismissBanner: 'Dismiss notice',
188
203
  built: 'Built',
189
204
  images: 'Images',
205
+ imageCarousel: 'image carousel',
190
206
  navigationChildren: 'Child pages',
191
207
  navigationMenu: 'Menu',
208
+ nextImage: 'Next image',
192
209
  note: 'Note',
210
+ pageMoved: 'Page moved',
211
+ pageMovedText: 'This address now identifies',
193
212
  pageNavigation: 'Page contents',
213
+ previousImage: 'Previous image',
194
214
  siteBanners: 'Site notices',
195
215
  siteNavigation: 'Pages',
196
216
  skipToContent: 'Skip to content',
197
217
  }),
198
218
  sv: Object.freeze({
199
219
  breadcrumb: 'Brödsmulor',
220
+ appearance: 'Utseende',
221
+ appearanceDark: 'Mörkt',
222
+ appearanceLight: 'Ljust',
223
+ appearanceSystem: 'System',
224
+ codeCopied: 'Kopierat',
225
+ codeCopyFailed: 'Kunde inte kopiera koden',
226
+ copyCode: 'Kopiera kod',
227
+ displaySettings: 'Visning',
228
+ focusReading: 'Fokuserad läsning',
229
+ readingWidth: 'Textbredd',
230
+ readingWidthNarrow: 'Smal',
231
+ readingWidthStandard: 'Standard',
232
+ readingWidthWide: 'Bred',
233
+ resetDisplaySettings: 'Återställ',
200
234
  dismissBanner: 'Stäng meddelande',
201
235
  built: 'Byggd',
202
236
  images: 'Bilder',
237
+ imageCarousel: 'bildkarusell',
203
238
  navigationChildren: 'Undersidor',
204
239
  navigationMenu: 'Meny',
240
+ nextImage: 'Nästa bild',
205
241
  note: 'Not',
242
+ pageMoved: 'Sidan har flyttats',
243
+ pageMovedText: 'Den här adressen identifierar nu',
206
244
  pageNavigation: 'Sidinnehåll',
245
+ previousImage: 'Föregående bild',
207
246
  siteBanners: 'Meddelanden',
208
247
  siteNavigation: 'Sidor',
209
248
  skipToContent: 'Hoppa till innehållet',
@@ -326,7 +365,22 @@ export const resolveThemeVisualConfig = (theme, sourceLabel = siteThemeLabel) =>
326
365
  const rawTypographyConfig = assertObject(rawThemeConfig.typography ?? {}, 'typography', sourceLabel);
327
366
  const resolvedContentSpacing = readEnum(rawLayoutConfig, 'contentSpacing', 'layout', contentSpacingNames, 'normal', sourceLabel);
328
367
  const resolvedLayoutSpacingDefaults = contentSpacingProfiles[resolvedContentSpacing];
329
- const shape = readEnum(rawThemeConfig, 'shape', 'theme', ['square', 'soft'], 'soft', sourceLabel);
368
+ const corners = readEnum(rawThemeConfig, 'corners', 'theme', ['square', 'rounded'], 'rounded', sourceLabel);
369
+ const imagePresentation = readEnum(
370
+ rawImagesConfig,
371
+ 'presentation',
372
+ 'images',
373
+ imagePresentationNames,
374
+ defaultImagePresentation,
375
+ sourceLabel,
376
+ );
377
+ if (imagePresentation === 'prose-aligned' && rawImagesConfig.maxAvailableHeightPercent !== undefined) {
378
+ throw new Error([
379
+ `images.maxAvailableHeightPercent cannot be used with images.presentation "prose-aligned" in ${sourceLabel}.`,
380
+ 'Prose-aligned images follow available horizontal space instead of a viewport-height limit.',
381
+ 'Remove images.maxAvailableHeightPercent or set images.presentation to "centered-fit".',
382
+ ].join('\n'));
383
+ }
330
384
 
331
385
  return Object.freeze({
332
386
  layout: Object.freeze({
@@ -337,6 +391,8 @@ export const resolveThemeVisualConfig = (theme, sourceLabel = siteThemeLabel) =>
337
391
  'layout.localNavigationGap',
338
392
  sourceLabel,
339
393
  ),
394
+ noteWidth: readCssLengthValue(rawLayoutConfig.noteWidth ?? '12rem', 'layout.noteWidth', sourceLabel),
395
+ noteGap: readCssLengthValue(rawLayoutConfig.noteGap ?? '1.25rem', 'layout.noteGap', sourceLabel),
340
396
  gutter: readResponsiveCssLength(rawLayoutConfig, 'gutter', 'layout', Object.freeze({
341
397
  desktop: 'clamp(1.25rem, 4vw, 3rem)',
342
398
  mobile: '1rem',
@@ -352,10 +408,15 @@ export const resolveThemeVisualConfig = (theme, sourceLabel = siteThemeLabel) =>
352
408
  }),
353
409
  }),
354
410
  images: Object.freeze({
355
- maxAvailableHeightPercent: readResponsivePercent(rawImagesConfig, 'maxAvailableHeightPercent', 'images', Object.freeze({
356
- desktop: 74,
357
- mobile: 68,
358
- }), sourceLabel),
411
+ presentation: imagePresentation,
412
+ ...(imagePresentation === 'centered-fit'
413
+ ? {
414
+ maxAvailableHeightPercent: readResponsivePercent(rawImagesConfig, 'maxAvailableHeightPercent', 'images', Object.freeze({
415
+ desktop: 74,
416
+ mobile: 68,
417
+ }), sourceLabel),
418
+ }
419
+ : {}),
359
420
  maxAvailableWidthPercent: readResponsivePercent(rawImagesConfig, 'maxAvailableWidthPercent', 'images', Object.freeze({
360
421
  desktop: 100,
361
422
  mobile: 100,
@@ -365,17 +426,24 @@ export const resolveThemeVisualConfig = (theme, sourceLabel = siteThemeLabel) =>
365
426
  typography: Object.freeze({
366
427
  fontFamily: readFontFamily(rawTypographyConfig, 'fontFamily', 'typography', defaultFontFamily, sourceLabel),
367
428
  }),
368
- shape: Object.freeze({
369
- name: shape,
370
- radiusSmall: shape === 'square' ? '0' : '2px',
371
- radiusMedium: shape === 'square' ? '0' : '6px',
372
- radiusLarge: shape === 'square' ? '0' : '8px',
429
+ corners: Object.freeze({
430
+ name: corners,
431
+ radiusSmall: corners === 'square' ? '0' : '2px',
432
+ radiusMedium: corners === 'square' ? '0' : '6px',
433
+ radiusLarge: corners === 'square' ? '0' : '8px',
373
434
  }),
374
435
  });
375
436
  };
376
437
 
377
438
  export const resolveNavigationConfig = (config, sourceLabel = siteConfigLabel) => {
378
439
  const rawNavigation = assertObject(config.navigation ?? {}, 'navigation', sourceLabel);
440
+ if (Object.hasOwn(rawNavigation, 'sectionTracking')) {
441
+ throw new Error([
442
+ `navigation.sectionTracking is no longer supported in ${sourceLabel}.`,
443
+ 'Section tracking is automatic on pages with a contents rail.',
444
+ 'Remove navigation.sectionTracking.',
445
+ ].join('\n'));
446
+ }
379
447
 
380
448
  return Object.freeze({
381
449
  mode: readEnum(
@@ -1,5 +1,7 @@
1
1
  import { z } from 'astro/zod';
2
+ import { imagePresentationNames } from './image-presentation.mjs';
2
3
  import { navigationModeNames } from './navigation-model.mjs';
4
+ import { presentationPaletteNames } from './presentation-palette-metadata.mjs';
3
5
  import { themePresetNames } from './theme-presets.mjs';
4
6
 
5
7
  const isDateOnly = (value) => {
@@ -15,16 +17,34 @@ const textWidth = z.enum(['narrow', 'normal', 'wide']).describe('Maximum width o
15
17
  const headingWeight = z.union([z.literal(400), z.literal(500), z.literal(600), z.literal(700)]).describe('CSS font weight.');
16
18
  const typographyProfile = z.enum(['restrained', 'dense', 'reading', 'statement']).describe('Coordinated typography defaults. Omit this to use the selected preset.');
17
19
  const themePreset = z.enum(themePresetNames).describe('Complete Norna visual preset. Start here and add overrides only when needed.');
18
- const presentationPalette = z.enum(['dark', 'light', 'paper']).describe('Coordinated site color palette. Omit this to use the selected preset.');
20
+ const presentationPalette = z.enum(presentationPaletteNames).describe('Coordinated site color palette. Every palette provides light and dark variants. Omit this to use the selected preset.');
21
+ const themeAppearance = z.object({
22
+ default: z.enum(['system', 'light', 'dark']).optional().describe('Initial appearance. System follows the visitor\'s operating-system preference.'),
23
+ }).strict().refine(
24
+ (value) => value.default !== undefined,
25
+ 'Specify default.',
26
+ ).describe('Site-wide initial appearance.');
27
+ const readerControls = z.object({
28
+ appearance: z.boolean().optional().describe('Show an Appearance control that lets readers choose System, Light, or Dark.'),
29
+ focusReading: z.boolean().optional().describe('Show a Focus reading control that lets readers hide navigation, breadcrumbs, and the footer. Sites with tree navigation always show this control.'),
30
+ }).strict().refine(
31
+ (value) => value.appearance !== undefined || value.focusReading !== undefined,
32
+ 'Specify appearance, focusReading, or both.',
33
+ ).describe('Optional controls for the site-wide Display panel.');
19
34
  const spacingDensity = z.enum(['compact', 'normal', 'airy']).describe('Coordinated spacing density. Omit this to use the selected preset.');
20
35
  const contentSpacing = z.enum(['compact', 'normal', 'spacious']).describe('Vertical spacing between page sections and structured content blocks.');
21
- const backgroundPattern = z.enum(['uniform', 'alternating', 'cycling']).describe('How sections cycle through the active palette surfaces.');
22
- const shapeProfile = z.enum(['square', 'soft']).describe('Site-wide corner treatment for interface and content surfaces.');
23
- const navigationMode = z.enum(navigationModeNames).describe('Site-wide navigation model. Automatic selects from the site structure.');
24
- const lineHeight = z.number()
25
- .min(1, 'Use a unitless line height of at least 1.')
26
- .max(3, 'Use a unitless line height of at most 3.')
27
- .describe('Unitless line height between 1 and 3.');
36
+ const backgroundPattern = z.enum(['uniform', 'alternating', 'accented']).describe('How coordinated backgrounds are assigned to H2 sections. Non-uniform patterns are unavailable with tree navigation.');
37
+ const cornerTreatment = z.enum(['square', 'rounded']).describe('Site-wide corner treatment for navigation, cards and framed content.');
38
+ const cardListWidth = z.enum(['text', 'narrow', 'normal', 'wide']).describe('Default maximum width for card lists. A width written in a norna-card-list block overrides this value.');
39
+ const imagePresentation = z.enum(imagePresentationNames).describe('How managed image stacks and carousels are placed on the page. Prose-aligned starts them at the body-text edge; centered-fit centers them and constrains them by available width and viewport height.');
40
+ const navigationMode = z.enum(navigationModeNames).describe('Site-wide navigation policy. Automatic selects an effective mode for each page from its active top-level branch.');
41
+ const createLineHeight = (minimum, role) => z.number()
42
+ .min(minimum, `Use a unitless ${role} line height of at least ${minimum}.`)
43
+ .max(3, `Use a unitless ${role} line height of at most 3.`)
44
+ .describe(`Unitless ${role} line height between ${minimum} and 3.`);
45
+ const headingLineHeight = createLineHeight(1, 'heading');
46
+ const bodyLineHeight = createLineHeight(1.4, 'body-text');
47
+ const captionLineHeight = createLineHeight(1.25, 'caption');
28
48
  const cssLength = z.string().regex(
29
49
  /^(?:0|(?:\d+(?:\.\d+)?|\.\d+)(?:px|rem|em|ch|lh))$/,
30
50
  'Use a CSS length such as "0", "0.8em", "1rem", or "12px".',
@@ -59,10 +79,10 @@ const overrideResponsiveTextAlign = z.object({
59
79
  const commonTextPresentationOverride = {
60
80
  align: overrideResponsiveTextAlign.optional().describe('Responsive text alignment override.'),
61
81
  size: textSize.optional(),
62
- lineHeight: lineHeight.optional(),
63
82
  };
64
83
  const headingPresentationOverride = z.object({
65
84
  ...commonTextPresentationOverride,
85
+ lineHeight: headingLineHeight.optional(),
66
86
  weight: headingWeight.optional().describe('Heading font weight. Omit this to keep the profile value.'),
67
87
  spacingBefore: cssLength.optional().describe('Vertical space before the heading.'),
68
88
  spacingAfter: cssLength.optional().describe('Vertical space after the heading.'),
@@ -75,10 +95,12 @@ const headingLevelsPresentationOverride = z.object({
75
95
  }).strict().describe('Heading overrides by Markdown level.');
76
96
  const bodyPresentationOverride = z.object({
77
97
  ...commonTextPresentationOverride,
98
+ lineHeight: bodyLineHeight.optional(),
78
99
  paragraphSpacing: cssLength.optional().describe('Vertical space between body paragraphs.'),
79
100
  }).strict().describe('Focused overrides for body text.');
80
101
  const captionPresentationOverride = z.object({
81
102
  ...commonTextPresentationOverride,
103
+ lineHeight: captionLineHeight.optional(),
82
104
  spacingBefore: cssLength.optional().describe('Vertical space between an image and its caption.'),
83
105
  }).strict().describe('Focused overrides for image captions.');
84
106
  const typographyOverrides = z.object({
@@ -136,18 +158,28 @@ const pageThemeLayout = z.object({
136
158
  'Specify contentSpacing, textWidth, or both.',
137
159
  ).describe('Page-local layout settings inherited by descendant pages.');
138
160
  const themeImages = z.object({
161
+ presentation: imagePresentation.optional().describe('Managed-image presentation method. Omit this to keep the selected preset or inherited page setting.'),
139
162
  width: visualCssLength.optional().describe('Maximum managed-image width. Omit this to keep the selected preset.'),
140
163
  maxAvailableWidthPercent: responsivePercent.optional().describe('Maximum percentage of available horizontal space used by managed images.'),
141
- maxAvailableHeightPercent: responsivePercent.optional().describe('Maximum percentage of viewport height used by managed images.'),
142
- }).strict().describe('Optional defaults for managed image presentation.');
164
+ maxAvailableHeightPercent: responsivePercent.optional().describe('Maximum percentage of viewport height used by centered-fit images. This setting is unavailable with prose-aligned presentation.'),
165
+ }).strict().describe('Optional defaults for placing managed images inside the page content area. Persistent navigation remains outside this area.');
166
+ const themeCardList = z.object({
167
+ width: cardListWidth,
168
+ }).strict().describe('Site-wide card-list defaults.');
169
+ const themeBlocks = z.object({
170
+ cardList: themeCardList.optional(),
171
+ }).strict().refine(
172
+ (value) => value.cardList !== undefined,
173
+ 'Specify cardList.',
174
+ ).describe('Optional site-wide defaults for structured Norna content blocks.');
143
175
  const configNavigation = z.object({
144
176
  mode: navigationMode.optional().describe('Navigation model. Omit this to let Norna choose from the site structure.'),
145
177
  }).strict().describe('Site-wide navigation behavior.');
146
178
  const themeSections = z.object({
147
- backgroundPattern: backgroundPattern.optional().describe('Section background sequence. Omit this to keep the selected preset or inherited page setting.'),
179
+ backgroundPattern: backgroundPattern.optional().describe('Section background pattern. Alternating and accented create full-width bands with sections or top navigation; tree navigation requires uniform.'),
148
180
  }).strict().describe('Defaults for page section presentation.');
149
181
  const pageThemeSections = z.object({
150
- backgroundPattern: backgroundPattern.optional().describe('Section background sequence inherited by descendant pages.'),
182
+ backgroundPattern: backgroundPattern.optional().describe('Section background sequence inherited by descendant pages. Non-uniform patterns are invalid with tree navigation.'),
151
183
  }).strict().refine(
152
184
  (value) => value.backgroundPattern !== undefined,
153
185
  'Specify backgroundPattern.',
@@ -155,11 +187,20 @@ const pageThemeSections = z.object({
155
187
  const pageNavigation = z.object({
156
188
  listed: z.boolean().optional().default(true).describe('List this page in site navigation. The page remains public when false.'),
157
189
  }).strict();
190
+ const pageAlias = z.string().regex(
191
+ /^\/(?:[a-z0-9]+(?:-[a-z0-9]+)*\/)+$/,
192
+ 'Use an old site-relative Norna page URL such as "/guides/install/". Start and end with / and use lowercase letters, numbers, and single hyphens.',
193
+ ).describe('Previous site-relative URL that permanently identifies this page.');
158
194
  const pageMetadata = z.object({
159
195
  description: z.string().min(1).optional().describe('Optional page-specific meta description.'),
196
+ aliases: z.array(pageAlias)
197
+ .min(1)
198
+ .refine((values) => new Set(values).size === values.length, 'Page aliases must be unique within the page.')
199
+ .optional()
200
+ .describe('Previous site-relative URLs that permanently identify this page. The current page is always the target.'),
160
201
  }).strict().describe('Optional metadata for this homepage or additional page. The Markdown H1 supplies the page title.');
161
202
  const sitewideLogo = z.object({
162
- height: visualCssLength.optional().describe('Displayed logo height. Width follows the intrinsic aspect ratio.'),
203
+ height: visualCssLength.optional().describe('Displayed logo height on wider screens. Omit it to use 2.6rem; narrow screens cap the height at 2.15rem. Width follows the intrinsic aspect ratio.'),
163
204
  }).strict().describe('Optional display settings for a convention-based navigation logo.');
164
205
 
165
206
  const banner = z.object({
@@ -192,9 +233,12 @@ const siteShape = {
192
233
 
193
234
  const themeVisualShape = {
194
235
  preset: themePreset.optional().describe('Complete visual starting point. Add only the overrides the site actually needs.'),
195
- shape: shapeProfile.optional().describe('Site-wide shape profile. Omit this to use the selected preset.'),
236
+ appearance: themeAppearance.optional(),
237
+ readerControls: readerControls.optional(),
238
+ corners: cornerTreatment.optional().describe('Site-wide corner treatment. Omit this to use the selected preset.'),
196
239
  layout: themeLayout.optional(),
197
240
  images: themeImages.optional(),
241
+ blocks: themeBlocks.optional(),
198
242
  typography: themeTypography.optional(),
199
243
  palette: presentationPalette.optional(),
200
244
  sections: themeSections.optional(),
@@ -212,8 +256,13 @@ const sitewideShape = {
212
256
  footer: sitewideFooter.optional().describe('Site-wide footer content.'),
213
257
  };
214
258
 
259
+ const categoryShape = {
260
+ label: z.string().trim().min(1).describe('Navigation label for this non-routable page category.'),
261
+ };
262
+
215
263
  export const schemaTopLevelKeys = Object.freeze({
216
264
  config: Object.freeze(Object.keys(configShape)),
265
+ category: Object.freeze(Object.keys(categoryShape)),
217
266
  content: Object.freeze(Object.keys(siteShape)),
218
267
  sitewide: Object.freeze(Object.keys(sitewideShape)),
219
268
  theme: Object.freeze(Object.keys(themeVisualShape)),
@@ -222,6 +271,8 @@ export const schemaTopLevelKeys = Object.freeze({
222
271
 
223
272
  export const configSchema = z.object(configShape).strict()
224
273
  .describe('Technical settings for one Norna site. Additional pages cannot provide technical configuration.');
274
+ export const categorySchema = z.object(categoryShape).strict()
275
+ .describe('A non-routable navigation category containing child pages.');
225
276
  export const siteSchema = z.object(siteShape).strict()
226
277
  .describe('Frontmatter for a homepage or additional page content.md file.');
227
278
  export const themeVisualSchema = z.object(themeVisualShape).strict()
@@ -231,6 +282,6 @@ export const pageThemeSchema = z.object(pageThemeShape).strict()
231
282
  (value) => value.layout !== undefined || value.images !== undefined || value.sections !== undefined,
232
283
  'Specify layout, images, sections, or a combination of them.',
233
284
  )
234
- .describe('Limited page presentation overrides inherited by descendant pages. Site colors, shapes, typography and navigation remain global.');
285
+ .describe('Limited page presentation overrides inherited by descendant pages. Site colors, corners, typography, content-block defaults and navigation remain global.');
235
286
  export const sitewideSchema = z.object(sitewideShape).strict()
236
287
  .describe('Editorial content and optional navigation logo display settings shared by every page.');
@@ -1,4 +1,5 @@
1
1
  import { documentationLink } from './documentation-links.mjs';
2
+ import { presentationPaletteNames } from './presentation-palette-metadata.mjs';
2
3
  import { getSchemaValueDefinition } from './schema-value-definitions.mjs';
3
4
 
4
5
  const yamlExample = (source) => `\`\`\`yaml\n${source}\n\`\`\``;
@@ -32,6 +33,13 @@ const schemaProperty = (schema, propertyPath) => schemaProperties(schema, proper
32
33
  const addHelp = (schema, propertyPath, paragraphs, examples = []) => {
33
34
  for (const property of schemaProperties(schema, propertyPath)) {
34
35
  property.markdownDescription = paragraphs.join('\n\n');
36
+ const reference = paragraphs.findLast((paragraph) => /^\[[^\]]+\]\(https:\/\//.test(paragraph));
37
+ if (reference && Array.isArray(property.oneOf)) {
38
+ for (const candidate of property.oneOf) {
39
+ if (!Object.hasOwn(candidate, 'const') || !candidate.description) continue;
40
+ candidate.markdownDescription = [candidate.description, reference].join('\n\n');
41
+ }
42
+ }
35
43
  if (examples.length > 0) property.examples = examples;
36
44
  }
37
45
  };
@@ -121,7 +129,7 @@ const addSitewideLogoHelp = (jsonSchema) => {
121
129
 
122
130
  logo.markdownDescription = [
123
131
  yamlExample('logo:\n height: 2rem'),
124
- '`logo` optionally overrides the displayed height of the convention-based logo file. The logo links home, and its alternative text comes from the homepage Markdown H1. This setting does not enable or select the file.',
132
+ '`logo` optionally overrides the displayed height of the convention-based logo file. Without an override, Norna uses 2.6rem on wider screens and caps the logo at 2.15rem on narrow screens. The logo links home, and its alternative text comes from the homepage Markdown H1. This setting does not enable or select the file.',
125
133
  documentationLink('Navigation logo filenames and placement', 'public-files.md', 'navigation-logo'),
126
134
  ].join('\n\n');
127
135
  logo.properties.height.examples = ['2rem'];
@@ -153,7 +161,7 @@ const addConfigHelp = (jsonSchema) => {
153
161
  ], ['en', 'sv', 'en-GB', 'sv-SE']);
154
162
  addHelp(jsonSchema, 'navigation', [
155
163
  yamlExample('navigation:\n mode: automatic'),
156
- 'Sets one navigation model for the complete site. `automatic` selects from the page hierarchy.',
164
+ 'Sets the site-wide navigation policy. `automatic` selects an effective mode for each page from its active top-level branch.',
157
165
  documentationLink('Navigation reference', 'pages.md', 'navigation'),
158
166
  ]);
159
167
  addFieldHelp(
@@ -179,40 +187,108 @@ const addThemeHelp = (jsonSchema) => {
179
187
  ].join('\n\n');
180
188
  addHelp(jsonSchema, 'preset', [
181
189
  yamlExample('preset: documentation'),
182
- 'Selects coordinated shapes, layout, image sizing, typography, palette and section backgrounds. This is the normal starting point for a theme.',
190
+ 'Selects coordinated corners, layout, image sizing, content-block defaults, typography, palette and section backgrounds. This is the normal starting point for a theme.',
183
191
  documentationLink('Compare theme presets', 'theme.md', 'theme-presets'),
184
192
  ]);
185
- addHelp(jsonSchema, 'shape', [
186
- yamlExample('shape: soft'),
193
+ addHelp(jsonSchema, 'corners', [
194
+ yamlExample('corners: rounded'),
187
195
  'Chooses one consistent corner treatment for navigation, cards and framed content throughout the site.',
188
- documentationLink('Theme reference', 'theme.md'),
189
- ], ['square', 'soft']);
196
+ documentationLink('Corner reference', 'theme.md', 'corners'),
197
+ ], ['square', 'rounded']);
190
198
  addHelp(jsonSchema, 'layout', [
191
199
  yamlExample('layout:\n contentSpacing: compact\n textWidth: narrow'),
192
200
  'Overrides text width, content spacing, page width and gutters after the selected preset.',
193
201
  documentationLink('Layout reference', 'theme.md', 'layout'),
194
202
  ]);
195
203
  addHelp(jsonSchema, 'images', [
196
- yamlExample('images:\n width: 900px\n maxAvailableHeightPercent: 74'),
197
- 'Overrides the available width and height used by Norna-managed images.',
204
+ yamlExample('images:\n presentation: prose-aligned\n width: 900px'),
205
+ 'Overrides how Norna-managed image stacks and carousels align inside the page content area and how much space they may use. Persistent navigation remains outside this area.',
198
206
  documentationLink('Image sizing reference', 'theme.md', 'image-sizing'),
199
207
  ]);
208
+ addHelp(jsonSchema, 'blocks', [
209
+ yamlExample('blocks:\n cardList:\n width: text'),
210
+ 'Overrides preset defaults for structured Norna content blocks throughout the site. Options written directly in a Markdown block take priority.',
211
+ documentationLink('Content block defaults', 'theme.md', 'content-block-defaults'),
212
+ ]);
213
+ addHelp(jsonSchema, 'blocks.cardList', [
214
+ yamlExample('blocks:\n cardList:\n width: text'),
215
+ 'Sets site-wide defaults for card lists. A `width` option in an individual `norna-card-list` block overrides this setting.',
216
+ documentationLink('Content block defaults', 'theme.md', 'content-block-defaults'),
217
+ ]);
218
+ addFieldHelp(
219
+ jsonSchema,
220
+ 'blocks.cardList.width',
221
+ 'blocks:\n cardList:\n width: text',
222
+ 'theme.md',
223
+ 'content-block-defaults',
224
+ ['text', 'narrow', 'normal', 'wide'],
225
+ );
226
+ addSnippets(jsonSchema, 'blocks', [schemaSnippet({
227
+ label: 'Override content-block defaults',
228
+ body: {
229
+ cardList: {
230
+ width: '${1:text}',
231
+ },
232
+ },
233
+ description: 'Override a preset default for structured content blocks across the site.',
234
+ file: 'theme.md',
235
+ anchor: 'content-block-defaults',
236
+ })]);
200
237
  addHelp(jsonSchema, 'typography', [
201
238
  yamlExample('typography:\n profile: reading\n rhythm: normal'),
202
239
  'Overrides the preset\'s font stack, typography profile, rhythm or individual text settings.',
203
240
  documentationLink('Typography configuration reference', 'typography.md', 'configuration-shape'),
204
241
  ]);
205
242
  addHelp(jsonSchema, 'palette', [
206
- yamlExample('palette: paper'),
207
- 'Chooses a coordinated color system for the page frame, navigation, footer and section surfaces.',
208
- documentationLink('Palette and section surfaces', 'theme.md', 'palette-and-section-surfaces'),
209
- ], ['dark', 'light', 'paper']);
243
+ yamlExample('palette: warm-paper'),
244
+ 'Chooses the site color character. Every palette provides coordinated light and dark variants.',
245
+ documentationLink('Palette and appearance', 'theme.md', 'palette-and-appearance'),
246
+ ], presentationPaletteNames);
247
+ addHelp(jsonSchema, 'appearance', [
248
+ yamlExample('appearance:\n default: system'),
249
+ 'Selects the initial appearance. Enable the reader-facing choice under readerControls.',
250
+ documentationLink('Appearance', 'theme.md', 'appearance'),
251
+ ]);
252
+ addFieldHelp(jsonSchema, 'appearance.default', 'appearance:\n default: system', 'theme.md', 'appearance', ['system', 'light', 'dark']);
253
+ addSnippets(jsonSchema, 'appearance', [schemaSnippet({
254
+ label: 'Set the initial appearance',
255
+ body: 'appearance:\n default: ${1:system}',
256
+ description: 'Follow the system color preference or choose a fixed initial appearance.',
257
+ file: 'theme.md',
258
+ anchor: 'appearance',
259
+ })]);
260
+ addHelp(jsonSchema, 'readerControls', [
261
+ yamlExample('readerControls:\n appearance: true\n focusReading: true'),
262
+ 'Choose which optional controls readers can use in the site-wide Display panel.',
263
+ '`appearance: true` lets readers choose System, Light, or Dark. `focusReading: true` lets them hide navigation, breadcrumbs, and the footer while reading.',
264
+ 'Reading width is always included. Sites with tree navigation always include Focus reading, even when it is not enabled here.',
265
+ documentationLink('Reader Display controls', 'theme.md', 'reader-display-controls'),
266
+ ]);
267
+ for (const [propertyPath, example] of [
268
+ ['readerControls.appearance', 'readerControls:\n appearance: true'],
269
+ ['readerControls.focusReading', 'readerControls:\n focusReading: true'],
270
+ ]) {
271
+ addFieldHelp(
272
+ jsonSchema,
273
+ propertyPath,
274
+ example,
275
+ 'theme.md',
276
+ 'reader-display-controls',
277
+ );
278
+ }
279
+ addSnippets(jsonSchema, 'readerControls', [schemaSnippet({
280
+ label: 'Configure the Display panel',
281
+ body: 'readerControls:\n appearance: ${1:true}\n focusReading: ${2:true}',
282
+ description: 'Show optional Appearance and Focus reading controls. Reading width is already included, and tree navigation always includes Focus reading.',
283
+ file: 'theme.md',
284
+ anchor: 'reader-display-controls',
285
+ })]);
210
286
  addHelp(jsonSchema, 'sections', [
211
287
  yamlExample('sections:\n backgroundPattern: alternating'),
212
- 'Chooses whether section backgrounds stay uniform, alternate between two surfaces or cycle through three.',
213
- documentationLink('Palette and section surfaces', 'theme.md', 'palette-and-section-surfaces'),
288
+ 'Chooses whether H2 section backgrounds stay uniform, alternate between two backgrounds or move from base to soft to emphasis and back through soft. Non-uniform patterns are available with sections and top navigation; tree navigation requires uniform.',
289
+ documentationLink('Section backgrounds', 'theme.md', 'section-backgrounds'),
214
290
  ]);
215
- addFieldHelp(jsonSchema, 'sections.backgroundPattern', 'sections:\n backgroundPattern: alternating', 'theme.md', 'palette-and-section-surfaces', ['uniform', 'alternating', 'cycling']);
291
+ addFieldHelp(jsonSchema, 'sections.backgroundPattern', 'sections:\n backgroundPattern: alternating', 'theme.md', 'section-backgrounds', ['uniform', 'alternating', 'accented']);
216
292
 
217
293
  const layoutFields = [
218
294
  ['layout.contentSpacing', 'layout:\n contentSpacing: compact'],
@@ -277,6 +353,7 @@ const addThemeHelp = (jsonSchema) => {
277
353
  })]);
278
354
 
279
355
  const imageFields = [
356
+ ['images.presentation', 'images:\n presentation: prose-aligned'],
280
357
  ['images.width', 'images:\n width: 900px'],
281
358
  ['images.maxAvailableWidthPercent', 'images:\n maxAvailableWidthPercent:\n desktop: 100\n mobile: 100'],
282
359
  ['images.maxAvailableWidthPercent.desktop', 'images:\n maxAvailableWidthPercent:\n desktop: 100'],
@@ -378,22 +455,23 @@ const addThemeHelp = (jsonSchema) => {
378
455
  const addPageThemeHelp = (jsonSchema) => {
379
456
  jsonSchema.markdownDescription = [
380
457
  yamlExample('layout:\n textWidth: narrow\n contentSpacing: compact'),
381
- 'A page theme may adjust only page layout, managed-image sizing and the section background pattern. Descendant pages inherit these values. Site colors, shapes and typography stay consistent.',
458
+ 'A limited theme in a page or category directory may adjust only page layout, managed-image sizing and the section background pattern. Descendant pages inherit these values. Tree navigation requires a uniform section background. Site colors, corners, typography, content-block defaults and navigation stay consistent.',
382
459
  documentationLink('Page theme reference', 'theme.md', 'page-themes'),
383
460
  ].join('\n\n');
384
461
  addHelp(jsonSchema, 'layout', [
385
462
  yamlExample('layout:\n textWidth: narrow\n contentSpacing: compact'),
386
- 'Adjusts body-text line length and vertical content spacing for this page and its descendants.',
463
+ 'Adjusts body-text line length and vertical content spacing for pages below this directory.',
387
464
  documentationLink('Page theme reference', 'theme.md', 'page-themes'),
388
465
  ]);
389
466
  addFieldHelp(jsonSchema, 'layout.textWidth', 'layout:\n textWidth: narrow', 'theme.md', 'page-themes', ['narrow', 'normal', 'wide']);
390
467
  addFieldHelp(jsonSchema, 'layout.contentSpacing', 'layout:\n contentSpacing: compact', 'theme.md', 'page-themes', ['compact', 'normal', 'spacious']);
391
468
  addHelp(jsonSchema, 'images', [
392
- yamlExample('images:\n width: 900px'),
393
- 'Adjusts managed-image sizing for this page and its descendants.',
469
+ yamlExample('images:\n presentation: prose-aligned\n width: 900px'),
470
+ 'Adjusts managed-image presentation and sizing inside the content area for pages below this directory. Persistent navigation remains outside this area.',
394
471
  documentationLink('Image sizing reference', 'theme.md', 'image-sizing'),
395
472
  ]);
396
473
  const imageFields = [
474
+ ['images.presentation', 'images:\n presentation: prose-aligned'],
397
475
  ['images.width', 'images:\n width: 900px'],
398
476
  ['images.maxAvailableWidthPercent', 'images:\n maxAvailableWidthPercent:\n desktop: 100\n mobile: 100'],
399
477
  ['images.maxAvailableWidthPercent.desktop', 'images:\n maxAvailableWidthPercent:\n desktop: 100'],
@@ -407,10 +485,10 @@ const addPageThemeHelp = (jsonSchema) => {
407
485
  }
408
486
  addHelp(jsonSchema, 'sections', [
409
487
  yamlExample('sections:\n backgroundPattern: alternating'),
410
- 'Adjusts the section background sequence for this page and its descendants.',
488
+ 'Adjusts the H2 section background pattern for pages below this directory. Alternating and accented create full-width bands but are invalid when navigation resolves to tree.',
411
489
  documentationLink('Page theme reference', 'theme.md', 'page-themes'),
412
490
  ]);
413
- addFieldHelp(jsonSchema, 'sections.backgroundPattern', 'sections:\n backgroundPattern: alternating', 'theme.md', 'page-themes', ['uniform', 'alternating', 'cycling']);
491
+ addFieldHelp(jsonSchema, 'sections.backgroundPattern', 'sections:\n backgroundPattern: alternating', 'theme.md', 'page-themes', ['uniform', 'alternating', 'accented']);
414
492
  };
415
493
 
416
494
  const addSitewideHelp = (jsonSchema) => {
@@ -488,8 +566,8 @@ const addContentHelp = (jsonSchema) => {
488
566
  documentationLink('Page title and frontmatter reference', 'content.md', 'page-title-and-frontmatter'),
489
567
  ].join('\n\n');
490
568
  addHelp(jsonSchema, 'page', [
491
- yamlExample('page:\n description: About this project.'),
492
- 'Contains optional metadata for the current homepage or additional page. The Markdown H1 supplies its title.',
569
+ yamlExample('page:\n description: About this project.\n aliases:\n - /old-about/'),
570
+ 'Contains optional metadata for the current homepage or additional page. The Markdown H1 supplies its title. An alias records an old URL for this same page.',
493
571
  documentationLink('Page title and frontmatter reference', 'content.md', 'page-title-and-frontmatter'),
494
572
  ]);
495
573
  addHelp(jsonSchema, 'page.description', [
@@ -497,6 +575,16 @@ const addContentHelp = (jsonSchema) => {
497
575
  'An optional page-specific description rendered as `<meta name="description">`. It is not visible in page content.',
498
576
  documentationLink('Page title and frontmatter reference', 'content.md', 'page-title-and-frontmatter'),
499
577
  ], ['About this project.']);
578
+ addHelp(jsonSchema, 'page.aliases', [
579
+ yamlExample('page:\n aliases:\n - /old-about/'),
580
+ 'Lists previous site-relative URLs that permanently identify this page. The page containing the list is always the target. Paths omit the configured base path and are excluded from the sitemap.',
581
+ documentationLink('Preserve old page URLs', 'pages.md', 'preserve-old-page-urls'),
582
+ ], [['/old-about/']]);
583
+ addHelp(jsonSchema, 'page.aliases.[]', [
584
+ yamlExample('page:\n aliases:\n - /old-about/'),
585
+ 'Use a previous Norna page URL. Start and end with `/`; use lowercase ASCII letters, numbers, and single hyphens; do not include the configured base path, a query string, or a fragment.',
586
+ documentationLink('Alias path rules', 'pages.md', 'preserve-old-page-urls'),
587
+ ], ['/old-about/']);
500
588
  addHelp(jsonSchema, 'navigation', [
501
589
  yamlExample('navigation:\n listed: false'),
502
590
  'Optionally excludes an additional page from site navigation without removing its public URL.',
@@ -505,8 +593,22 @@ const addContentHelp = (jsonSchema) => {
505
593
  addFieldHelp(jsonSchema, 'navigation.listed', 'navigation:\n listed: false', 'pages.md', 'navigation', [true, false]);
506
594
  };
507
595
 
596
+ const addCategoryHelp = (jsonSchema) => {
597
+ jsonSchema.markdownDescription = [
598
+ yamlExample('label: Guides'),
599
+ '`category.yaml` creates a navigation-only group for child pages. It has no page content and produces no URL of its own.',
600
+ documentationLink('Navigation category reference', 'pages.md', 'navigation-categories'),
601
+ ].join('\n\n');
602
+ addHelp(jsonSchema, 'label', [
603
+ yamlExample('label: Guides'),
604
+ 'The category label shown in global navigation, tree navigation, mobile navigation, and breadcrumbs.',
605
+ documentationLink('Navigation category reference', 'pages.md', 'navigation-categories'),
606
+ ]);
607
+ };
608
+
508
609
  export const applySchemaEditorMetadata = (filename, jsonSchema) => {
509
610
  addValueDescriptions(jsonSchema);
611
+ if (filename === 'category.schema.json') addCategoryHelp(jsonSchema);
510
612
  if (filename === 'config.schema.json') {
511
613
  addLanguageSuggestions(jsonSchema);
512
614
  addConfigHelp(jsonSchema);