@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
@@ -0,0 +1,179 @@
1
+ import path from 'node:path';
2
+
3
+ import { toPosixPath } from './site-content.mjs';
4
+
5
+ export const getExpectedImagePath = (contentFile, imageName) =>
6
+ path.join(contentFile.imagesDir, imageName);
7
+
8
+ export const getExpectedImageLabel = (contentFile, imageName) =>
9
+ `${contentFile.imagesLabel}/${imageName}`;
10
+
11
+ export const getImageRootLabel = (contentFile) => contentFile.imagesLabel.replace(/\/images$/, '');
12
+
13
+ export const getImageCandidateLabel = ({ contentFile, imagePath }) =>
14
+ `${contentFile.imagesLabel}/${toPosixPath(path.relative(contentFile.imagesDir, imagePath))}`;
15
+
16
+ const getReferenceLabel = (contentFile, section) =>
17
+ `${contentFile.contentLabel} [${section.id ?? 'page title'}]`;
18
+
19
+ const addMapEntry = (map, key, value) => {
20
+ if (!map.has(key)) map.set(key, []);
21
+ map.get(key).push(value);
22
+ };
23
+
24
+ const addReferenceIssue = (issues, entry, issue) => {
25
+ issues.push({ ...entry, issue, phase: 'reference' });
26
+ };
27
+
28
+ const addConflictIssue = (issues, move, issue) => {
29
+ issues.push({
30
+ contentFile: move.contentFile,
31
+ section: move.section,
32
+ reference: move.reference,
33
+ issue,
34
+ phase: 'conflict',
35
+ });
36
+ };
37
+
38
+ const addMoveConflicts = (moves, issues) => {
39
+ const movesBySource = new Map();
40
+ const movesByDestination = new Map();
41
+
42
+ for (const move of moves) {
43
+ addMapEntry(movesBySource, move.from, move);
44
+ addMapEntry(movesByDestination, move.to, move);
45
+ }
46
+
47
+ for (const sourceMoves of movesBySource.values()) {
48
+ const destinations = new Set(sourceMoves.map((move) => move.to));
49
+ if (destinations.size <= 1) continue;
50
+
51
+ const firstMove = sourceMoves[0];
52
+ addConflictIssue(issues, firstMove, {
53
+ severity: 'error',
54
+ message: `Cannot relocate "${firstMove.imageName}" because the same source file is referenced from multiple destinations: ${sourceMoves.map((move) => getExpectedImageLabel(move.contentFile, move.imageName)).join(', ')}.`,
55
+ fix: 'Duplicate the image manually or rename one of the image files so each move has a single destination.',
56
+ });
57
+ }
58
+
59
+ for (const destinationMoves of movesByDestination.values()) {
60
+ const sources = new Set(destinationMoves.map((move) => move.from));
61
+ if (sources.size <= 1) continue;
62
+
63
+ const firstMove = destinationMoves[0];
64
+ addConflictIssue(issues, firstMove, {
65
+ severity: 'error',
66
+ message: `Cannot relocate "${firstMove.imageName}" because multiple source files would move to ${getExpectedImageLabel(firstMove.contentFile, firstMove.imageName)}: ${destinationMoves.map((move) => getImageCandidateLabel({ contentFile: move.sourceContentFile, imagePath: move.from })).join(', ')}.`,
67
+ fix: 'Move the intended file manually or rename files so the destination is unambiguous.',
68
+ });
69
+ }
70
+ };
71
+
72
+ export const createImageSyncPlan = ({
73
+ imageCandidates,
74
+ references,
75
+ reportMisplaced,
76
+ }) => {
77
+ const candidatesByName = new Map();
78
+ const expectedReferencesByPath = new Map();
79
+ const issues = [];
80
+ const moves = [];
81
+ const referencedImagePaths = new Set();
82
+ const resolvedPathByReference = new Map();
83
+
84
+ for (const candidate of imageCandidates) {
85
+ addMapEntry(candidatesByName, candidate.imageName, candidate);
86
+ }
87
+
88
+ for (const candidates of candidatesByName.values()) {
89
+ candidates.sort((left, right) => left.imagePath.localeCompare(right.imagePath, 'sv'));
90
+ }
91
+
92
+ for (const entry of references) {
93
+ const expectedPath = getExpectedImagePath(entry.contentFile, entry.reference.image);
94
+ addMapEntry(expectedReferencesByPath, expectedPath, entry);
95
+ }
96
+
97
+ for (const entry of references) {
98
+ const { contentFile, reference, section } = entry;
99
+ const imageName = reference.image;
100
+ const expectedPath = getExpectedImagePath(contentFile, imageName);
101
+ const expectedLabel = getExpectedImageLabel(contentFile, imageName);
102
+ const candidates = (candidatesByName.get(imageName) ?? [])
103
+ .filter(({ imagePath }) => imagePath !== expectedPath);
104
+ const expectedCandidate = (candidatesByName.get(imageName) ?? [])
105
+ .find(({ imagePath }) => imagePath === expectedPath);
106
+
107
+ if (expectedCandidate) {
108
+ referencedImagePaths.add(expectedPath);
109
+ resolvedPathByReference.set(reference, expectedPath);
110
+ continue;
111
+ }
112
+
113
+ if (candidates.length === 0) {
114
+ addReferenceIssue(issues, entry, {
115
+ severity: 'error',
116
+ message: `Image "${imageName}" does not exist at ${expectedLabel} or anywhere under any page image root.`,
117
+ fix: `Add the source image directly to ${contentFile.imagesLabel}/ or remove the Norna-managed image reference.`,
118
+ });
119
+ continue;
120
+ }
121
+
122
+ if (candidates.length > 1) {
123
+ addReferenceIssue(issues, entry, {
124
+ severity: 'error',
125
+ message: `Cannot relocate "${imageName}". Multiple files with this filename were found: ${candidates.map(getImageCandidateLabel).join(', ')}.`,
126
+ fix: 'Move the intended file manually or rename files so the move is unambiguous.',
127
+ });
128
+ continue;
129
+ }
130
+
131
+ const sourceCandidate = candidates[0];
132
+ const sourcePath = sourceCandidate.imagePath;
133
+ const referencesAtCurrentLocation = (expectedReferencesByPath.get(sourcePath) ?? [])
134
+ .filter((expectedReference) => expectedReference.contentFile !== contentFile);
135
+
136
+ if (referencesAtCurrentLocation.length > 0) {
137
+ addReferenceIssue(issues, entry, {
138
+ severity: 'error',
139
+ message: `Cannot relocate "${imageName}" from ${getImageCandidateLabel(sourceCandidate)} because it is still referenced from ${referencesAtCurrentLocation.map((expectedReference) => getReferenceLabel(expectedReference.contentFile, expectedReference.section)).join(', ')}.`,
140
+ fix: 'Remove the extra reference, duplicate the image file manually, or rename one of the image files so the intended move is unambiguous.',
141
+ });
142
+ continue;
143
+ }
144
+
145
+ if (!moves.some((move) => move.from === sourcePath && move.to === expectedPath)) {
146
+ moves.push({
147
+ imageName,
148
+ from: sourcePath,
149
+ to: expectedPath,
150
+ contentFile,
151
+ sourceContentFile: sourceCandidate.contentFile,
152
+ section,
153
+ reference,
154
+ });
155
+ }
156
+
157
+ referencedImagePaths.add(sourcePath);
158
+ resolvedPathByReference.set(reference, sourcePath);
159
+
160
+ if (reportMisplaced) {
161
+ addReferenceIssue(issues, entry, {
162
+ severity: 'error',
163
+ message: `Image "${imageName}" is used here but is located in ${getImageCandidateLabel(sourceCandidate)}.`,
164
+ fix: sourceCandidate.contentFile === contentFile
165
+ ? 'Run norna content:sync to move it directly into the current page image root.'
166
+ : `Run norna content:sync to move it from ${getImageRootLabel(sourceCandidate.contentFile)} to ${getImageRootLabel(contentFile)}.`,
167
+ });
168
+ }
169
+ }
170
+
171
+ addMoveConflicts(moves, issues);
172
+
173
+ return {
174
+ issues,
175
+ moves,
176
+ referencedImagePaths,
177
+ resolvedPathByReference,
178
+ };
179
+ };
@@ -2,15 +2,14 @@ import { access, readdir, readFile } from 'node:fs/promises';
2
2
  import path from 'node:path';
3
3
  import { load } from 'js-yaml';
4
4
  import {
5
- extractInlineNoteDiagnostics,
6
- extractMarkdownImageReferences,
7
- extractNornaMarkdownBlockDiagnostics,
8
- getNornaBlockImageReferences,
5
+ getOpenMarkdownFenceAtLine,
9
6
  nornaMarkdownBlockDefinitions,
10
7
  } from './norna-markdown-blocks.mjs';
8
+ import { resolveNavigationModel } from './navigation-model.mjs';
11
9
  import { inspectPublicAssetFilenames, logoAssetFilenames } from './public-asset-conventions.mjs';
12
- import { getHeadingIdentifierIssues, getMarkdownHeadings } from './heading-ids.mjs';
10
+ import { parsePageMarkdownSource } from './page-markdown.mjs';
13
11
  import { siteSchema } from './schema-definitions.mjs';
12
+ import { homePageDirectory } from './site-conventions.mjs';
14
13
 
15
14
  const supportedImageExtensions = new Set(['.jpg', '.jpeg', '.png', '.svg']);
16
15
  const siteConfigNames = ['config.yaml'];
@@ -36,6 +35,132 @@ export const findNornaSiteRoot = async (documentPath) => {
36
35
  }
37
36
  };
38
37
 
38
+ const readEditorYaml = async (filePath) => {
39
+ try {
40
+ const source = await readFile(filePath, 'utf8');
41
+ const data = load(source) ?? {};
42
+ return data && typeof data === 'object' && !Array.isArray(data) ? data : {};
43
+ } catch {
44
+ return null;
45
+ }
46
+ };
47
+
48
+ const readContentFrontmatterForEditor = (source) => {
49
+ const match = source.match(/^---\r?\n([\s\S]*?)\r?\n---(?:\r?\n|$)/);
50
+ if (!match) return {};
51
+ try {
52
+ const data = load(match[1]) ?? {};
53
+ return data && typeof data === 'object' && !Array.isArray(data) ? data : {};
54
+ } catch {
55
+ return {};
56
+ }
57
+ };
58
+
59
+ const getNavigationNodesForEditor = async (siteRoot) => {
60
+ const nodes = [];
61
+
62
+ const visit = async (pagesDirectory, depth = 1) => {
63
+ const entries = (await readdir(pagesDirectory, { withFileTypes: true }).catch((error) => {
64
+ if (error?.code === 'ENOENT') return [];
65
+ throw error;
66
+ }))
67
+ .filter((entry) => entry.isDirectory())
68
+ .sort((left, right) => left.name.localeCompare(right.name, 'en'));
69
+
70
+ for (const entry of entries) {
71
+ const nodeDirectory = path.join(pagesDirectory, entry.name);
72
+ const contentPath = path.join(nodeDirectory, 'content.md');
73
+ const categoryPath = path.join(nodeDirectory, 'category.yaml');
74
+ const [hasContent, hasCategory] = await Promise.all([
75
+ fileExists(contentPath),
76
+ fileExists(categoryPath),
77
+ ]);
78
+
79
+ if (hasContent !== hasCategory) {
80
+ if (hasCategory) {
81
+ nodes.push({
82
+ depth,
83
+ headings: [],
84
+ isHome: false,
85
+ kind: 'category',
86
+ listed: true,
87
+ });
88
+ } else {
89
+ const source = await readFile(contentPath, 'utf8');
90
+ const data = readContentFrontmatterForEditor(source);
91
+ const document = await parsePageMarkdownSource(source, { label: contentPath });
92
+ nodes.push({
93
+ depth,
94
+ headings: document.navigationHeadings,
95
+ isHome: depth === 1 && entry.name === homePageDirectory,
96
+ kind: 'page',
97
+ listed: data.navigation?.listed !== false,
98
+ });
99
+ }
100
+ }
101
+
102
+ await visit(path.join(nodeDirectory, 'pages'), depth + 1);
103
+ }
104
+ };
105
+
106
+ await visit(path.join(siteRoot, 'pages'));
107
+ return nodes;
108
+ };
109
+
110
+ const getNavigationModeForEditor = async (siteRoot) => {
111
+ const config = await readEditorYaml(path.join(siteRoot, 'config.yaml'));
112
+ if (!config) return null;
113
+ const requestedMode = config.navigation?.mode ?? 'automatic';
114
+ if (requestedMode !== 'automatic') return requestedMode;
115
+
116
+ try {
117
+ return resolveNavigationModel({
118
+ mode: requestedMode,
119
+ nodes: await getNavigationNodesForEditor(siteRoot),
120
+ }).mode;
121
+ } catch {
122
+ return null;
123
+ }
124
+ };
125
+
126
+ const findNestedYamlPropertyLine = (source, parentKey, propertyKey) => {
127
+ const lines = source.replace(/\r\n?/g, '\n').split('\n');
128
+ let insideParent = false;
129
+ for (let index = 0; index < lines.length; index += 1) {
130
+ const line = lines[index];
131
+ if (new RegExp(`^${parentKey}:\\s*(?:#.*)?$`).test(line)) {
132
+ insideParent = true;
133
+ continue;
134
+ }
135
+ if (!insideParent) continue;
136
+ if (/^[A-Za-z][A-Za-z0-9-]*:/.test(line)) return 1;
137
+ if (new RegExp(`^ ${propertyKey}:`).test(line)) return index + 1;
138
+ }
139
+ return 1;
140
+ };
141
+
142
+ export const getThemeDiagnostics = async ({ documentPath, source }) => {
143
+ let theme;
144
+ try {
145
+ theme = load(source) ?? {};
146
+ } catch {
147
+ return [];
148
+ }
149
+ if (!theme || typeof theme !== 'object' || Array.isArray(theme)) return [];
150
+
151
+ const backgroundPattern = theme.sections?.backgroundPattern;
152
+ if (backgroundPattern === undefined || backgroundPattern === 'uniform') return [];
153
+ const siteRoot = await findNornaSiteRoot(documentPath);
154
+ if (!siteRoot || await getNavigationModeForEditor(siteRoot) !== 'tree') return [];
155
+
156
+ return [{
157
+ code: 'tree-section-background-pattern',
158
+ line: findNestedYamlPropertyLine(source, 'sections', 'backgroundPattern'),
159
+ message: `sections.backgroundPattern "${backgroundPattern}" cannot be used because this site resolves to tree navigation. Tree navigation uses one uniform reading surface so the navigation rail and page content remain distinct. Remove sections.backgroundPattern or set it to uniform.`,
160
+ severity: 'error',
161
+ }];
162
+ };
163
+
39
164
  const readSitewideLogoForEditor = async (siteRoot) => {
40
165
  const filename = await findFile(siteRoot, ['sitewide-content.yaml']);
41
166
  if (!filename) return null;
@@ -128,32 +253,6 @@ const getPageContext = (siteRoot, documentPath) => {
128
253
  };
129
254
  };
130
255
 
131
- const getOpenFenceAtLine = (source, lineIndex) => {
132
- const lines = source.replace(/\r\n?/g, '\n').split('\n');
133
- let open = null;
134
-
135
- for (let index = 0; index <= Math.min(lineIndex, lines.length - 1); index += 1) {
136
- const match = lines[index].match(/^ {0,3}(`{3,}|~{3,})([^\r\n]*)$/);
137
- if (!match) continue;
138
-
139
- if (!open) {
140
- open = {
141
- character: match[1][0],
142
- length: match[1].length,
143
- line: index,
144
- type: match[2].trim().split(/\s+/)[0] ?? '',
145
- };
146
- continue;
147
- }
148
-
149
- if (match[1][0] === open.character && match[1].length >= open.length && !match[2].trim()) {
150
- open = null;
151
- }
152
- }
153
-
154
- return open;
155
- };
156
-
157
256
  const getBlockField = (definition, key, itemField = false) => (
158
257
  itemField ? definition.item?.fields?.[key] : definition.options?.[key]
159
258
  );
@@ -185,7 +284,7 @@ const fieldCandidate = (key, fieldDefinition, options = {}) => ({
185
284
 
186
285
  export const getNornaBlockCompletionContext = ({ source, line }) => {
187
286
  const lines = source.replace(/\r\n?/g, '\n').split('\n');
188
- const fence = getOpenFenceAtLine(source, line);
287
+ const fence = getOpenMarkdownFenceAtLine(source, line);
189
288
  const definition = fence ? nornaMarkdownBlockDefinitions[fence.type] : null;
190
289
  if (!fence || !definition) return null;
191
290
 
@@ -249,7 +348,7 @@ export const getNornaBlockCompletionContext = ({ source, line }) => {
249
348
 
250
349
  export const getNornaBlockFieldContext = ({ source, line }) => {
251
350
  const lines = source.replace(/\r\n?/g, '\n').split('\n');
252
- const fence = getOpenFenceAtLine(source, line);
351
+ const fence = getOpenMarkdownFenceAtLine(source, line);
253
352
  const definition = fence ? nornaMarkdownBlockDefinitions[fence.type] : null;
254
353
  if (!fence || !definition) return null;
255
354
  const currentLine = lines[line] ?? '';
@@ -328,8 +427,8 @@ const getReferencesByFilename = async (siteRoot) => {
328
427
  const references = new Map();
329
428
  for (const contentPath of await getContentFiles(siteRoot)) {
330
429
  const source = await readFile(contentPath, 'utf8');
331
- const { blocks } = extractNornaMarkdownBlockDiagnostics(source, { label: toPosixPath(path.relative(siteRoot, contentPath)) });
332
- for (const reference of getNornaBlockImageReferences(blocks)) {
430
+ const page = await parsePageMarkdownSource(source, { label: toPosixPath(path.relative(siteRoot, contentPath)) });
431
+ for (const reference of page.managedImages) {
333
432
  if (!references.has(reference.image)) references.set(reference.image, []);
334
433
  references.get(reference.image).push(toPosixPath(path.relative(siteRoot, contentPath)));
335
434
  }
@@ -364,7 +463,7 @@ export const getImageCompletionContext = async ({ documentPath, source, line })
364
463
  if (!siteRoot) return null;
365
464
  const page = getPageContext(siteRoot, documentPath);
366
465
  if (!page) return null;
367
- const fence = getOpenFenceAtLine(source, line);
466
+ const fence = getOpenMarkdownFenceAtLine(source, line);
368
467
  if (!fence || !['norna-image-stack', 'norna-image-carousel', 'norna-card-list'].includes(fence.type)) return null;
369
468
 
370
469
  const currentLine = source.replace(/\r\n?/g, '\n').split('\n')[line] ?? '';
@@ -417,35 +516,6 @@ export const getImageDefinitionContext = async ({ documentPath, source, line })
417
516
  };
418
517
  };
419
518
 
420
- const getLineFromMessage = (message, fallback = 1) => {
421
- const match = String(message).match(/\bline\s+(\d+)\b/i);
422
- return match ? Number.parseInt(match[1], 10) : fallback;
423
- };
424
-
425
- const getImageReferenceLines = (source) => {
426
- const lines = source.replace(/\r\n?/g, '\n').split('\n');
427
- const references = [];
428
- let fence = null;
429
-
430
- for (const [index, line] of lines.entries()) {
431
- const fenceMatch = line.match(/^ {0,3}(`{3,}|~{3,})([^\r\n]*)$/);
432
- if (fenceMatch) {
433
- if (!fence) {
434
- fence = { character: fenceMatch[1][0], length: fenceMatch[1].length, type: fenceMatch[2].trim().split(/\s+/)[0] ?? '' };
435
- } else if (fenceMatch[1][0] === fence.character && fenceMatch[1].length >= fence.length && !fenceMatch[2].trim()) {
436
- fence = null;
437
- }
438
- continue;
439
- }
440
- if (!fence || !fence.type.startsWith('norna-')) continue;
441
-
442
- const match = line.match(/^\s*(?:-\s+)?image:\s*([^\s#]+)\s*(?:#.*)?$/);
443
- if (match) references.push({ filename: match[1].replace(/^['"]|['"]$/g, ''), line: index + 1 });
444
- }
445
-
446
- return references;
447
- };
448
-
449
519
  const getContentFrontmatterDiagnostics = (source) => {
450
520
  const match = source.match(/^---\r?\n([\s\S]*?)\r?\n---(?:\r?\n|$)/);
451
521
  if (!match) {
@@ -475,112 +545,20 @@ const getContentFrontmatterDiagnostics = (source) => {
475
545
  }));
476
546
  };
477
547
 
478
- const getMarkdownStructure = (source) => {
479
- const lines = source.replace(/\r\n?/g, '\n').split('\n');
480
- let bodyStart = 0;
481
- if (lines[0]?.trim() === '---') {
482
- const closingIndex = lines.findIndex((line, index) => index > 0 && line.trim() === '---');
483
- if (closingIndex < 0) return { bodyStart: lines.length, headings: [], lines };
484
- bodyStart = closingIndex + 1;
485
- }
486
-
487
- const headings = [];
488
- let fence = null;
489
- for (let index = bodyStart; index < lines.length; index += 1) {
490
- const line = lines[index];
491
- const fenceMatch = line.match(/^ {0,3}(`{3,}|~{3,})([^\r\n]*)$/);
492
- if (fenceMatch) {
493
- if (!fence) {
494
- fence = { character: fenceMatch[1][0], length: fenceMatch[1].length };
495
- } else if (
496
- fenceMatch[1][0] === fence.character
497
- && fenceMatch[1].length >= fence.length
498
- && !fenceMatch[2].trim()
499
- ) {
500
- fence = null;
501
- }
502
- continue;
503
- }
504
- if (fence) continue;
505
-
506
- const match = line.match(/^(#{1,2})\s+(.+?)\s*$/);
507
- if (match) headings.push({ level: match[1].length, line: index + 1, source: line });
508
- }
509
-
510
- return { bodyStart, headings, lines };
511
- };
512
-
513
- const getPageTitleDiagnostics = (structure) => {
514
- const { bodyStart, headings, lines } = structure;
515
- const pageHeadings = headings.filter((heading) => heading.level === 1);
516
- const diagnostics = [];
517
-
518
- if (pageHeadings.length === 0) {
519
- diagnostics.push({
520
- code: 'missing-page-title',
521
- severity: 'error',
522
- line: 1,
523
- message: 'Norna pages require exactly one Markdown H1 page title, for example "# About".',
524
- });
525
- } else if (pageHeadings.length > 1) {
526
- for (const heading of pageHeadings.slice(1)) {
527
- diagnostics.push({
528
- code: 'duplicate-page-title',
529
- severity: 'error',
530
- line: heading.line,
531
- message: 'A Norna page can contain only one Markdown H1. Use a level 2 heading with an explicit id for a section.',
532
- });
533
- }
534
- }
535
-
536
- if (headings[0] && headings[0].level !== 1) {
537
- diagnostics.push({
538
- code: 'page-title-order',
539
- severity: 'error',
540
- line: headings[0].line,
541
- message: 'The Markdown H1 page title must come before every level 2 section.',
542
- });
543
- }
544
-
545
- const firstHeadingLineIndex = (headings[0]?.line ?? lines.length + 1) - 1;
546
- if (lines.slice(bodyStart, firstHeadingLineIndex).some((line) => line.trim())) {
547
- diagnostics.push({
548
- code: 'page-title-order',
549
- severity: 'error',
550
- line: bodyStart + 1,
551
- message: 'The Markdown H1 page title must be the first content after optional frontmatter.',
552
- });
553
- }
554
-
555
- return diagnostics;
556
- };
557
-
558
548
  export const getMarkdownDiagnostics = async ({ documentPath, source }) => {
559
- const markdownStructure = getMarkdownStructure(source);
560
- const { headings } = await getMarkdownHeadings(source);
549
+ const document = await parsePageMarkdownSource(source, { label: path.basename(documentPath) });
561
550
  const diagnostics = [
562
551
  ...getContentFrontmatterDiagnostics(source),
563
- ...getPageTitleDiagnostics(markdownStructure),
564
- ...getHeadingIdentifierIssues(headings).map((issue) => ({
565
- code: issue.code,
566
- severity: 'error',
567
- line: issue.heading.line,
568
- message: `${issue.message} ${issue.fix}`,
552
+ ...document.diagnostics.map((diagnostic) => ({
553
+ code: diagnostic.code,
554
+ severity: diagnostic.severity,
555
+ line: diagnostic.line,
556
+ message: diagnostic.fix
557
+ ? `${diagnostic.message} ${diagnostic.fix}`
558
+ : diagnostic.message,
569
559
  })),
570
560
  ];
571
- const blockResult = extractNornaMarkdownBlockDiagnostics(source, { label: path.basename(documentPath) });
572
- for (const error of blockResult.errors) {
573
- diagnostics.push({
574
- code: error.message.includes('but not closed') ? 'unclosed-norna-block' : 'invalid-norna-block',
575
- severity: 'error',
576
- line: getLineFromMessage(error.message, error.line),
577
- message: error.message,
578
- });
579
- }
580
- for (const error of extractInlineNoteDiagnostics(source, { label: path.basename(documentPath) }).errors) {
581
- diagnostics.push({ severity: 'error', line: error.line ?? getLineFromMessage(error.message), message: error.message });
582
- }
583
- for (const reference of extractMarkdownImageReferences(source)) {
561
+ for (const reference of document.markdownImages) {
584
562
  diagnostics.push({
585
563
  code: 'local-markdown-image',
586
564
  severity: 'warning',
@@ -590,21 +568,22 @@ export const getMarkdownDiagnostics = async ({ documentPath, source }) => {
590
568
  }
591
569
 
592
570
  const siteRoot = await findNornaSiteRoot(documentPath);
593
- const page = siteRoot ? getPageContext(siteRoot, documentPath) : null;
594
- if (!siteRoot || !page) return diagnostics;
571
+ const pageContext = siteRoot ? getPageContext(siteRoot, documentPath) : null;
572
+ if (!siteRoot || !pageContext) return diagnostics;
595
573
 
596
574
  const index = await createSiteImageIndex(siteRoot);
597
- for (const reference of getImageReferenceLines(source)) {
598
- const expectedPath = path.join(page.imagesRoot, reference.filename);
575
+ for (const reference of document.managedImages) {
576
+ const filename = reference.image;
577
+ const expectedPath = path.join(pageContext.imagesRoot, filename);
599
578
  if (await fileExists(expectedPath)) continue;
600
579
 
601
- const candidates = index.filesByName.get(reference.filename) ?? [];
580
+ const candidates = index.filesByName.get(filename) ?? [];
602
581
  if (candidates.length === 0) {
603
582
  diagnostics.push({
604
583
  code: 'missing-image',
605
584
  severity: 'error',
606
585
  line: reference.line,
607
- message: `Image "${reference.filename}" was not found in this page's images folder or elsewhere in this Norna site.`,
586
+ message: `Image "${filename}" was not found in this page's images folder or elsewhere in this Norna site.`,
608
587
  });
609
588
  continue;
610
589
  }
@@ -613,13 +592,13 @@ export const getMarkdownDiagnostics = async ({ documentPath, source }) => {
613
592
  code: 'ambiguous-image',
614
593
  severity: 'warning',
615
594
  line: reference.line,
616
- message: `Image "${reference.filename}" is ambiguous. Found: ${candidates.map((candidate) => toPosixPath(path.relative(siteRoot, candidate.absolutePath))).join(', ')}.`,
595
+ message: `Image "${filename}" is ambiguous. Found: ${candidates.map((candidate) => toPosixPath(path.relative(siteRoot, candidate.absolutePath))).join(', ')}.`,
617
596
  });
618
597
  continue;
619
598
  }
620
599
 
621
600
  const candidate = candidates[0];
622
- const referencedBy = index.referencesByFilename.get(reference.filename) ?? [];
601
+ const referencedBy = index.referencesByFilename.get(filename) ?? [];
623
602
  const currentRelativePath = toPosixPath(path.relative(siteRoot, documentPath));
624
603
  const otherReferences = referencedBy.filter((contentPath) => contentPath !== currentRelativePath);
625
604
  diagnostics.push({
@@ -631,8 +610,8 @@ export const getMarkdownDiagnostics = async ({ documentPath, source }) => {
631
610
  severity: 'warning',
632
611
  line: reference.line,
633
612
  message: otherReferences.length > 0
634
- ? `Image "${reference.filename}" is stored at ${toPosixPath(path.relative(siteRoot, candidate.absolutePath))} and is still referenced by ${otherReferences.join(', ')}. Norna cannot relocate it safely.`
635
- : `Image "${reference.filename}" is stored at ${toPosixPath(path.relative(siteRoot, candidate.absolutePath))}. Run "norna content:sync" to relocate it to this page's images folder.`,
613
+ ? `Image "${filename}" is stored at ${toPosixPath(path.relative(siteRoot, candidate.absolutePath))} and is still referenced by ${otherReferences.join(', ')}. Norna cannot relocate it safely.`
614
+ : `Image "${filename}" is stored at ${toPosixPath(path.relative(siteRoot, candidate.absolutePath))}. Run "norna content:sync" to relocate it to this page's images folder.`,
636
615
  });
637
616
  }
638
617
 
@@ -650,6 +629,6 @@ export const nornaBlockDefinitions = Object.freeze({
650
629
  }),
651
630
  'norna-card-list': Object.freeze({
652
631
  ...nornaMarkdownBlockDefinitions['norna-card-list'],
653
- snippet: '```norna-card-list\nlayout: ${1|image-top,image-left,image-right|}\nflow: ${2|grid,stack|}\nsize: ${3|s,m,l,xl|}\nwidth: ${4|text,narrow,normal,wide|}\n\n- title: ${5:Card title}\n text: ${6:Card text}\n image: ${7:filename.jpg}\n```',
632
+ snippet: '```norna-card-list\nlayout: ${1|image-top,image-left,image-right|}\nflow: ${2|grid,stack|}\nsize: ${3|s,m,l,xl|}\n\n- title: ${4:Card title}\n text: ${5:Card text}\n image: ${6:filename.jpg}\n```',
654
633
  }),
655
634
  });
@@ -21,7 +21,7 @@ const transliterateToAscii = (value) => Array.from(value)
21
21
  .map((character) => transliterations.get(character) ?? character)
22
22
  .join('');
23
23
 
24
- export const slugifyHeadingText = (value) => transliterateToAscii(value
24
+ export const slugifyAsciiIdentifier = (value) => transliterateToAscii(value
25
25
  .normalize('NFKD')
26
26
  .toLowerCase())
27
27
  .replace(/\p{Mark}+/gu, '')
@@ -29,6 +29,8 @@ export const slugifyHeadingText = (value) => transliterateToAscii(value
29
29
  .replace(/[^a-z0-9]+/g, '-')
30
30
  .replace(/^-+|-+$/g, '');
31
31
 
32
+ export const slugifyHeadingText = slugifyAsciiIdentifier;
33
+
32
34
  const getNodeText = (node) => {
33
35
  if (!node || typeof node !== 'object') return '';
34
36
  if (node.type === 'text' || node.type === 'inlineCode') return node.value ?? '';
@@ -77,7 +79,7 @@ export const getMarkdownHeadings = async (source) => {
77
79
  ),
78
80
  }));
79
81
 
80
- return { headings, source: normalizedSource };
82
+ return { headings, source: normalizedSource, tree };
81
83
  };
82
84
 
83
85
  export const getHeadingIdentifierIssues = (headings) => {
@@ -0,0 +1,2 @@
1
+ export const imagePresentationNames = Object.freeze(['prose-aligned', 'centered-fit']);
2
+ export const defaultImagePresentation = 'prose-aligned';