@janga/norna 0.7.18 → 0.7.22

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 (595) hide show
  1. package/README.md +22 -12
  2. package/astro.config.mjs +22 -0
  3. package/bin/norna-cli.mjs +6 -0
  4. package/package.json +45 -12
  5. package/schemas/category.schema.json +20 -0
  6. package/schemas/config.schema.json +16 -6
  7. package/schemas/content-frontmatter.schema.json +5 -5
  8. package/schemas/manifest.json +2 -1
  9. package/schemas/page-theme.schema.json +22 -22
  10. package/schemas/sitewide-content.schema.json +18 -18
  11. package/schemas/theme.schema.json +312 -146
  12. package/scripts/add-site-node.mjs +251 -0
  13. package/scripts/check-config.mjs +10 -2
  14. package/scripts/deploy-site.mjs +5 -8
  15. package/scripts/generate-images.mjs +11 -15
  16. package/scripts/generate-schemas.mjs +4 -1
  17. package/scripts/init-site.mjs +35 -0
  18. package/scripts/lib/astro-command.mjs +14 -9
  19. package/scripts/lib/editor-language-service.mjs +28 -177
  20. package/scripts/lib/heading-ids.mjs +3 -1
  21. package/scripts/lib/navigation-model.mjs +23 -17
  22. package/scripts/lib/norna-markdown-blocks.mjs +64 -145
  23. package/scripts/lib/norna-markdown-render-plugin.mjs +37 -0
  24. package/scripts/lib/object.mjs +28 -0
  25. package/scripts/lib/page-markdown.mjs +282 -0
  26. package/scripts/lib/presentation-contract.mjs +266 -0
  27. package/scripts/lib/presentation-palette-metadata.mjs +51 -0
  28. package/scripts/lib/presentation.mjs +526 -79
  29. package/scripts/lib/project-config.mjs +53 -6
  30. package/scripts/lib/schema-definitions.mjs +53 -13
  31. package/scripts/lib/schema-editor-metadata.mjs +107 -18
  32. package/scripts/lib/schema-value-definitions.mjs +24 -10
  33. package/scripts/lib/site-content.mjs +23 -238
  34. package/scripts/lib/site-paths.mjs +2 -3
  35. package/scripts/lib/site-structure.mjs +189 -0
  36. package/scripts/lib/theme-presets.mjs +75 -104
  37. package/scripts/lib/theme-profiles.mjs +221 -0
  38. package/scripts/lib/typography.mjs +220 -35
  39. package/scripts/lib/yaml-config.mjs +46 -6
  40. package/scripts/lib/yaml-indentation.mjs +86 -0
  41. package/scripts/show-typography.mjs +2 -3
  42. package/scripts/sync-content-sections.mjs +87 -76
  43. package/src/components/DisplaySettings.astro +107 -0
  44. package/src/components/ImageCarousel.astro +34 -13
  45. package/src/components/NavigationPageTree.astro +74 -43
  46. package/src/components/SectionNavigationScript.astro +56 -2
  47. package/src/components/SiteBreadcrumbs.astro +15 -12
  48. package/src/components/SiteNavigation.astro +92 -41
  49. package/src/components/SitePage.astro +35 -39
  50. package/src/components/SiteSection.astro +35 -191
  51. package/src/components/SiteTreeNavigation.astro +10 -9
  52. package/src/layouts/BaseLayout.astro +46 -6
  53. package/src/lib/generatedImages.ts +0 -7
  54. package/src/lib/readerPreferencesScript.mjs +141 -0
  55. package/src/lib/sectionContent.ts +119 -201
  56. package/src/lib/siteNavigation.ts +36 -18
  57. package/src/lib/sitePages.ts +91 -20
  58. package/src/pages/[...slug].astro +2 -2
  59. package/src/styles/global.css +759 -296
  60. package/starters/basic/README.md +2 -2
  61. package/docs/README.md +0 -137
  62. package/docs/assets/norna-dog-shelter.jpg +0 -0
  63. package/docs/commands.md +0 -189
  64. package/docs/configuration.md +0 -142
  65. package/docs/content.md +0 -351
  66. package/docs/design/command-organization.md +0 -414
  67. package/docs/design/navigation-and-theme-plan.md +0 -186
  68. package/docs/design/norna-diagram-design.md +0 -159
  69. package/docs/design/site-examples-structure.md +0 -119
  70. package/docs/engine-development.md +0 -215
  71. package/docs/getting-started.md +0 -206
  72. package/docs/how-to/embedded-site.md +0 -35
  73. package/docs/images-and-metadata.md +0 -188
  74. package/docs/local-development.md +0 -82
  75. package/docs/pages.md +0 -190
  76. package/docs/public-files.md +0 -118
  77. package/docs/publishing.md +0 -117
  78. package/docs/requirements.md +0 -54
  79. package/docs/site-files.md +0 -152
  80. package/docs/sitewide-content.md +0 -73
  81. package/docs/theme.md +0 -237
  82. package/docs/typography.md +0 -168
  83. package/examples/README.md +0 -49
  84. package/examples/complete-sites/dog-shelter-multi-page/.astro/collections/site.schema.json +0 -35
  85. package/examples/complete-sites/dog-shelter-multi-page/.astro/collections/sitewide.schema.json +0 -97
  86. package/examples/complete-sites/dog-shelter-multi-page/.astro/collections/theme.schema.json +0 -852
  87. package/examples/complete-sites/dog-shelter-multi-page/.astro/content-assets.mjs +0 -4
  88. package/examples/complete-sites/dog-shelter-multi-page/.astro/content-modules.mjs +0 -1
  89. package/examples/complete-sites/dog-shelter-multi-page/.astro/content.d.ts +0 -183
  90. package/examples/complete-sites/dog-shelter-multi-page/.astro/data-store.json +0 -1
  91. package/examples/complete-sites/dog-shelter-multi-page/.astro/dev-local.json +0 -8
  92. package/examples/complete-sites/dog-shelter-multi-page/.astro/dev.json +0 -13
  93. package/examples/complete-sites/dog-shelter-multi-page/.astro/dev.log +0 -36
  94. package/examples/complete-sites/dog-shelter-multi-page/.astro/settings.json +0 -5
  95. package/examples/complete-sites/dog-shelter-multi-page/.astro/types.d.ts +0 -2
  96. package/examples/complete-sites/dog-shelter-multi-page/README.md +0 -24
  97. package/examples/complete-sites/dog-shelter-multi-page/node_modules/.vite/deps/_metadata.json +0 -74
  98. package/examples/complete-sites/dog-shelter-multi-page/node_modules/.vite/deps/astro-B3JHJyiv.js +0 -434
  99. package/examples/complete-sites/dog-shelter-multi-page/node_modules/.vite/deps/astro-B3JHJyiv.js.map +0 -1
  100. package/examples/complete-sites/dog-shelter-multi-page/node_modules/.vite/deps/astro_n_aria-query.js +0 -6390
  101. package/examples/complete-sites/dog-shelter-multi-page/node_modules/.vite/deps/astro_n_aria-query.js.map +0 -1
  102. package/examples/complete-sites/dog-shelter-multi-page/node_modules/.vite/deps/astro_n_axobject-query.js +0 -2702
  103. package/examples/complete-sites/dog-shelter-multi-page/node_modules/.vite/deps/astro_n_axobject-query.js.map +0 -1
  104. package/examples/complete-sites/dog-shelter-multi-page/node_modules/.vite/deps/astro_n_html-escaper.js +0 -65
  105. package/examples/complete-sites/dog-shelter-multi-page/node_modules/.vite/deps/astro_n_html-escaper.js.map +0 -1
  106. package/examples/complete-sites/dog-shelter-multi-page/node_modules/.vite/deps/astro_runtime_client_dev-toolbar_entrypoint__js.js +0 -455
  107. package/examples/complete-sites/dog-shelter-multi-page/node_modules/.vite/deps/astro_runtime_client_dev-toolbar_entrypoint__js.js.map +0 -1
  108. package/examples/complete-sites/dog-shelter-multi-page/node_modules/.vite/deps/audit-C3SVr7dT.js +0 -1534
  109. package/examples/complete-sites/dog-shelter-multi-page/node_modules/.vite/deps/audit-C3SVr7dT.js.map +0 -1
  110. package/examples/complete-sites/dog-shelter-multi-page/node_modules/.vite/deps/highlight-BLtvqtzO.js +0 -48
  111. package/examples/complete-sites/dog-shelter-multi-page/node_modules/.vite/deps/highlight-BLtvqtzO.js.map +0 -1
  112. package/examples/complete-sites/dog-shelter-multi-page/node_modules/.vite/deps/icons-C92i61-2.js +0 -42
  113. package/examples/complete-sites/dog-shelter-multi-page/node_modules/.vite/deps/icons-C92i61-2.js.map +0 -1
  114. package/examples/complete-sites/dog-shelter-multi-page/node_modules/.vite/deps/package.json +0 -3
  115. package/examples/complete-sites/dog-shelter-multi-page/node_modules/.vite/deps/rolldown-runtime-BvCyGRYZ.js +0 -4
  116. package/examples/complete-sites/dog-shelter-multi-page/node_modules/.vite/deps/settings-v5GgKks_.js +0 -190
  117. package/examples/complete-sites/dog-shelter-multi-page/node_modules/.vite/deps/settings-v5GgKks_.js.map +0 -1
  118. package/examples/complete-sites/dog-shelter-multi-page/node_modules/.vite/deps/toolbar-BFvJVp26.js +0 -458
  119. package/examples/complete-sites/dog-shelter-multi-page/node_modules/.vite/deps/toolbar-BFvJVp26.js.map +0 -1
  120. package/examples/complete-sites/dog-shelter-multi-page/node_modules/.vite/deps/ui-library-Cd35oAvo.js +0 -1016
  121. package/examples/complete-sites/dog-shelter-multi-page/node_modules/.vite/deps/ui-library-Cd35oAvo.js.map +0 -1
  122. package/examples/complete-sites/dog-shelter-multi-page/node_modules/.vite/deps/window-vo3A6TMn.js +0 -32
  123. package/examples/complete-sites/dog-shelter-multi-page/node_modules/.vite/deps/window-vo3A6TMn.js.map +0 -1
  124. package/examples/complete-sites/dog-shelter-multi-page/node_modules/.vite/deps/xray-DwhzGckb.js +0 -111
  125. package/examples/complete-sites/dog-shelter-multi-page/node_modules/.vite/deps/xray-DwhzGckb.js.map +0 -1
  126. package/examples/complete-sites/dog-shelter-multi-page/site/.norna/generated-images.json +0 -98
  127. package/examples/complete-sites/dog-shelter-multi-page/site/config.yaml +0 -1
  128. package/examples/complete-sites/dog-shelter-multi-page/site/pages/000-home/content.md +0 -23
  129. package/examples/complete-sites/dog-shelter-multi-page/site/pages/000-home/images/shelter-dog.jpg +0 -0
  130. package/examples/complete-sites/dog-shelter-multi-page/site/pages/010-dogs/content.md +0 -21
  131. package/examples/complete-sites/dog-shelter-multi-page/site/pages/010-dogs/images/rex.jpg +0 -0
  132. package/examples/complete-sites/dog-shelter-multi-page/site/pages/010-dogs/images/rover.jpg +0 -0
  133. package/examples/complete-sites/dog-shelter-multi-page/site/pages/020-adopt/content.md +0 -22
  134. package/examples/complete-sites/dog-shelter-multi-page/site/pages/020-adopt/images/adoption-dog.jpg +0 -0
  135. package/examples/complete-sites/dog-shelter-multi-page/site/public/favicon.svg +0 -10
  136. package/examples/complete-sites/dog-shelter-multi-page/site/public/logo.svg +0 -9
  137. package/examples/complete-sites/dog-shelter-multi-page/site/public/robots.txt +0 -2
  138. package/examples/complete-sites/dog-shelter-multi-page/site/sitewide-content.yaml +0 -4
  139. package/examples/complete-sites/dog-shelter-multi-page/site/theme.yaml +0 -1
  140. package/examples/complete-sites/dog-shelter-single-page/.astro/collections/site.schema.json +0 -35
  141. package/examples/complete-sites/dog-shelter-single-page/.astro/collections/sitewide.schema.json +0 -97
  142. package/examples/complete-sites/dog-shelter-single-page/.astro/collections/theme.schema.json +0 -852
  143. package/examples/complete-sites/dog-shelter-single-page/.astro/content-assets.mjs +0 -4
  144. package/examples/complete-sites/dog-shelter-single-page/.astro/content-modules.mjs +0 -1
  145. package/examples/complete-sites/dog-shelter-single-page/.astro/content.d.ts +0 -183
  146. package/examples/complete-sites/dog-shelter-single-page/.astro/data-store.json +0 -1
  147. package/examples/complete-sites/dog-shelter-single-page/.astro/dev-local.json +0 -8
  148. package/examples/complete-sites/dog-shelter-single-page/.astro/dev.json +0 -13
  149. package/examples/complete-sites/dog-shelter-single-page/.astro/dev.log +0 -18
  150. package/examples/complete-sites/dog-shelter-single-page/.astro/settings.json +0 -5
  151. package/examples/complete-sites/dog-shelter-single-page/.astro/types.d.ts +0 -2
  152. package/examples/complete-sites/dog-shelter-single-page/README.md +0 -24
  153. package/examples/complete-sites/dog-shelter-single-page/node_modules/.vite/deps/_metadata.json +0 -74
  154. package/examples/complete-sites/dog-shelter-single-page/node_modules/.vite/deps/astro-B3JHJyiv.js +0 -434
  155. package/examples/complete-sites/dog-shelter-single-page/node_modules/.vite/deps/astro-B3JHJyiv.js.map +0 -1
  156. package/examples/complete-sites/dog-shelter-single-page/node_modules/.vite/deps/astro_n_aria-query.js +0 -6390
  157. package/examples/complete-sites/dog-shelter-single-page/node_modules/.vite/deps/astro_n_aria-query.js.map +0 -1
  158. package/examples/complete-sites/dog-shelter-single-page/node_modules/.vite/deps/astro_n_axobject-query.js +0 -2702
  159. package/examples/complete-sites/dog-shelter-single-page/node_modules/.vite/deps/astro_n_axobject-query.js.map +0 -1
  160. package/examples/complete-sites/dog-shelter-single-page/node_modules/.vite/deps/astro_n_html-escaper.js +0 -65
  161. package/examples/complete-sites/dog-shelter-single-page/node_modules/.vite/deps/astro_n_html-escaper.js.map +0 -1
  162. package/examples/complete-sites/dog-shelter-single-page/node_modules/.vite/deps/astro_runtime_client_dev-toolbar_entrypoint__js.js +0 -455
  163. package/examples/complete-sites/dog-shelter-single-page/node_modules/.vite/deps/astro_runtime_client_dev-toolbar_entrypoint__js.js.map +0 -1
  164. package/examples/complete-sites/dog-shelter-single-page/node_modules/.vite/deps/audit-C3SVr7dT.js +0 -1534
  165. package/examples/complete-sites/dog-shelter-single-page/node_modules/.vite/deps/audit-C3SVr7dT.js.map +0 -1
  166. package/examples/complete-sites/dog-shelter-single-page/node_modules/.vite/deps/highlight-BLtvqtzO.js +0 -48
  167. package/examples/complete-sites/dog-shelter-single-page/node_modules/.vite/deps/highlight-BLtvqtzO.js.map +0 -1
  168. package/examples/complete-sites/dog-shelter-single-page/node_modules/.vite/deps/icons-C92i61-2.js +0 -42
  169. package/examples/complete-sites/dog-shelter-single-page/node_modules/.vite/deps/icons-C92i61-2.js.map +0 -1
  170. package/examples/complete-sites/dog-shelter-single-page/node_modules/.vite/deps/package.json +0 -3
  171. package/examples/complete-sites/dog-shelter-single-page/node_modules/.vite/deps/rolldown-runtime-BvCyGRYZ.js +0 -4
  172. package/examples/complete-sites/dog-shelter-single-page/node_modules/.vite/deps/settings-v5GgKks_.js +0 -190
  173. package/examples/complete-sites/dog-shelter-single-page/node_modules/.vite/deps/settings-v5GgKks_.js.map +0 -1
  174. package/examples/complete-sites/dog-shelter-single-page/node_modules/.vite/deps/toolbar-BFvJVp26.js +0 -458
  175. package/examples/complete-sites/dog-shelter-single-page/node_modules/.vite/deps/toolbar-BFvJVp26.js.map +0 -1
  176. package/examples/complete-sites/dog-shelter-single-page/node_modules/.vite/deps/ui-library-Cd35oAvo.js +0 -1016
  177. package/examples/complete-sites/dog-shelter-single-page/node_modules/.vite/deps/ui-library-Cd35oAvo.js.map +0 -1
  178. package/examples/complete-sites/dog-shelter-single-page/node_modules/.vite/deps/window-vo3A6TMn.js +0 -32
  179. package/examples/complete-sites/dog-shelter-single-page/node_modules/.vite/deps/window-vo3A6TMn.js.map +0 -1
  180. package/examples/complete-sites/dog-shelter-single-page/node_modules/.vite/deps/xray-DwhzGckb.js +0 -111
  181. package/examples/complete-sites/dog-shelter-single-page/node_modules/.vite/deps/xray-DwhzGckb.js.map +0 -1
  182. package/examples/complete-sites/dog-shelter-single-page/site/.norna/generated-images.json +0 -50
  183. package/examples/complete-sites/dog-shelter-single-page/site/config.yaml +0 -1
  184. package/examples/complete-sites/dog-shelter-single-page/site/pages/000-home/content.md +0 -37
  185. package/examples/complete-sites/dog-shelter-single-page/site/pages/000-home/images/foster-dog.jpg +0 -0
  186. package/examples/complete-sites/dog-shelter-single-page/site/pages/000-home/images/rescue-dog.jpg +0 -0
  187. package/examples/complete-sites/dog-shelter-single-page/site/public/favicon.svg +0 -10
  188. package/examples/complete-sites/dog-shelter-single-page/site/public/logo.svg +0 -9
  189. package/examples/complete-sites/dog-shelter-single-page/site/public/robots.txt +0 -2
  190. package/examples/complete-sites/dog-shelter-single-page/site/sitewide-content.yaml +0 -4
  191. package/examples/complete-sites/dog-shelter-single-page/site/theme.yaml +0 -1
  192. package/examples/feature-demos/media-and-surfaces/.astro/collections/site.schema.json +0 -35
  193. package/examples/feature-demos/media-and-surfaces/.astro/collections/sitewide.schema.json +0 -97
  194. package/examples/feature-demos/media-and-surfaces/.astro/collections/theme.schema.json +0 -844
  195. package/examples/feature-demos/media-and-surfaces/.astro/content-assets.mjs +0 -4
  196. package/examples/feature-demos/media-and-surfaces/.astro/content-modules.mjs +0 -1
  197. package/examples/feature-demos/media-and-surfaces/.astro/content.d.ts +0 -183
  198. package/examples/feature-demos/media-and-surfaces/.astro/data-store.json +0 -1
  199. package/examples/feature-demos/media-and-surfaces/.astro/dev.log +0 -14
  200. package/examples/feature-demos/media-and-surfaces/.astro/settings.json +0 -5
  201. package/examples/feature-demos/media-and-surfaces/.astro/types.d.ts +0 -2
  202. package/examples/feature-demos/media-and-surfaces/README.md +0 -21
  203. package/examples/feature-demos/media-and-surfaces/node_modules/.vite/deps/_metadata.json +0 -80
  204. package/examples/feature-demos/media-and-surfaces/node_modules/.vite/deps/astro-B3JHJyiv.js +0 -434
  205. package/examples/feature-demos/media-and-surfaces/node_modules/.vite/deps/astro-B3JHJyiv.js.map +0 -1
  206. package/examples/feature-demos/media-and-surfaces/node_modules/.vite/deps/astro_n_aria-query.js +0 -6390
  207. package/examples/feature-demos/media-and-surfaces/node_modules/.vite/deps/astro_n_aria-query.js.map +0 -1
  208. package/examples/feature-demos/media-and-surfaces/node_modules/.vite/deps/astro_n_axobject-query.js +0 -2702
  209. package/examples/feature-demos/media-and-surfaces/node_modules/.vite/deps/astro_n_axobject-query.js.map +0 -1
  210. package/examples/feature-demos/media-and-surfaces/node_modules/.vite/deps/astro_n_html-escaper.js +0 -65
  211. package/examples/feature-demos/media-and-surfaces/node_modules/.vite/deps/astro_n_html-escaper.js.map +0 -1
  212. package/examples/feature-demos/media-and-surfaces/node_modules/.vite/deps/astro_runtime_client_dev-toolbar_entrypoint__js.js +0 -455
  213. package/examples/feature-demos/media-and-surfaces/node_modules/.vite/deps/astro_runtime_client_dev-toolbar_entrypoint__js.js.map +0 -1
  214. package/examples/feature-demos/media-and-surfaces/node_modules/.vite/deps/audit-C3SVr7dT.js +0 -1534
  215. package/examples/feature-demos/media-and-surfaces/node_modules/.vite/deps/audit-C3SVr7dT.js.map +0 -1
  216. package/examples/feature-demos/media-and-surfaces/node_modules/.vite/deps/embla-carousel.js +0 -1389
  217. package/examples/feature-demos/media-and-surfaces/node_modules/.vite/deps/embla-carousel.js.map +0 -1
  218. package/examples/feature-demos/media-and-surfaces/node_modules/.vite/deps/highlight-BLtvqtzO.js +0 -48
  219. package/examples/feature-demos/media-and-surfaces/node_modules/.vite/deps/highlight-BLtvqtzO.js.map +0 -1
  220. package/examples/feature-demos/media-and-surfaces/node_modules/.vite/deps/icons-C92i61-2.js +0 -42
  221. package/examples/feature-demos/media-and-surfaces/node_modules/.vite/deps/icons-C92i61-2.js.map +0 -1
  222. package/examples/feature-demos/media-and-surfaces/node_modules/.vite/deps/package.json +0 -3
  223. package/examples/feature-demos/media-and-surfaces/node_modules/.vite/deps/rolldown-runtime-BvCyGRYZ.js +0 -4
  224. package/examples/feature-demos/media-and-surfaces/node_modules/.vite/deps/settings-v5GgKks_.js +0 -190
  225. package/examples/feature-demos/media-and-surfaces/node_modules/.vite/deps/settings-v5GgKks_.js.map +0 -1
  226. package/examples/feature-demos/media-and-surfaces/node_modules/.vite/deps/toolbar-BFvJVp26.js +0 -458
  227. package/examples/feature-demos/media-and-surfaces/node_modules/.vite/deps/toolbar-BFvJVp26.js.map +0 -1
  228. package/examples/feature-demos/media-and-surfaces/node_modules/.vite/deps/ui-library-Cd35oAvo.js +0 -1016
  229. package/examples/feature-demos/media-and-surfaces/node_modules/.vite/deps/ui-library-Cd35oAvo.js.map +0 -1
  230. package/examples/feature-demos/media-and-surfaces/node_modules/.vite/deps/window-vo3A6TMn.js +0 -32
  231. package/examples/feature-demos/media-and-surfaces/node_modules/.vite/deps/window-vo3A6TMn.js.map +0 -1
  232. package/examples/feature-demos/media-and-surfaces/node_modules/.vite/deps/xray-DwhzGckb.js +0 -111
  233. package/examples/feature-demos/media-and-surfaces/node_modules/.vite/deps/xray-DwhzGckb.js.map +0 -1
  234. package/examples/feature-demos/media-and-surfaces/site/.norna/generated-images.json +0 -66
  235. package/examples/feature-demos/media-and-surfaces/site/config.yaml +0 -1
  236. package/examples/feature-demos/media-and-surfaces/site/pages/000-home/content.md +0 -15
  237. package/examples/feature-demos/media-and-surfaces/site/pages/010-media/content.md +0 -71
  238. package/examples/feature-demos/media-and-surfaces/site/pages/010-media/images/card-carousel.svg +0 -11
  239. package/examples/feature-demos/media-and-surfaces/site/pages/010-media/images/card-stack.svg +0 -9
  240. package/examples/feature-demos/media-and-surfaces/site/pages/010-media/images/card-surfaces.svg +0 -8
  241. package/examples/feature-demos/media-and-surfaces/site/pages/010-media/images/carousel-one.svg +0 -8
  242. package/examples/feature-demos/media-and-surfaces/site/pages/010-media/images/carousel-three.svg +0 -13
  243. package/examples/feature-demos/media-and-surfaces/site/pages/010-media/images/carousel-two.svg +0 -8
  244. package/examples/feature-demos/media-and-surfaces/site/pages/010-media/images/stack-one.svg +0 -8
  245. package/examples/feature-demos/media-and-surfaces/site/pages/010-media/images/stack-two.svg +0 -9
  246. package/examples/feature-demos/media-and-surfaces/site/pages/020-surfaces/content.md +0 -42
  247. package/examples/feature-demos/media-and-surfaces/site/pages/020-surfaces/theme.yaml +0 -2
  248. package/examples/feature-demos/media-and-surfaces/site/public/robots.txt +0 -2
  249. package/examples/feature-demos/media-and-surfaces/site/sitewide-content.yaml +0 -2
  250. package/examples/feature-demos/media-and-surfaces/site/theme.yaml +0 -1
  251. package/examples/feature-demos/sitewide-content/.astro/collections/site.schema.json +0 -59
  252. package/examples/feature-demos/sitewide-content/.astro/collections/sitewide.schema.json +0 -138
  253. package/examples/feature-demos/sitewide-content/.astro/collections/theme.schema.json +0 -755
  254. package/examples/feature-demos/sitewide-content/.astro/content-assets.mjs +0 -1
  255. package/examples/feature-demos/sitewide-content/.astro/content-modules.mjs +0 -1
  256. package/examples/feature-demos/sitewide-content/.astro/content.d.ts +0 -183
  257. package/examples/feature-demos/sitewide-content/.astro/data-store.json +0 -1
  258. package/examples/feature-demos/sitewide-content/.astro/dev.json +0 -13
  259. package/examples/feature-demos/sitewide-content/.astro/dev.log +0 -18
  260. package/examples/feature-demos/sitewide-content/.astro/settings.json +0 -5
  261. package/examples/feature-demos/sitewide-content/.astro/types.d.ts +0 -2
  262. package/examples/feature-demos/sitewide-content/README.md +0 -26
  263. package/examples/feature-demos/sitewide-content/node_modules/.vite/deps/_metadata.json +0 -74
  264. package/examples/feature-demos/sitewide-content/node_modules/.vite/deps/astro-B3JHJyiv.js +0 -434
  265. package/examples/feature-demos/sitewide-content/node_modules/.vite/deps/astro-B3JHJyiv.js.map +0 -1
  266. package/examples/feature-demos/sitewide-content/node_modules/.vite/deps/astro_n_aria-query.js +0 -6390
  267. package/examples/feature-demos/sitewide-content/node_modules/.vite/deps/astro_n_aria-query.js.map +0 -1
  268. package/examples/feature-demos/sitewide-content/node_modules/.vite/deps/astro_n_axobject-query.js +0 -2702
  269. package/examples/feature-demos/sitewide-content/node_modules/.vite/deps/astro_n_axobject-query.js.map +0 -1
  270. package/examples/feature-demos/sitewide-content/node_modules/.vite/deps/astro_n_html-escaper.js +0 -65
  271. package/examples/feature-demos/sitewide-content/node_modules/.vite/deps/astro_n_html-escaper.js.map +0 -1
  272. package/examples/feature-demos/sitewide-content/node_modules/.vite/deps/astro_runtime_client_dev-toolbar_entrypoint__js.js +0 -455
  273. package/examples/feature-demos/sitewide-content/node_modules/.vite/deps/astro_runtime_client_dev-toolbar_entrypoint__js.js.map +0 -1
  274. package/examples/feature-demos/sitewide-content/node_modules/.vite/deps/audit-C3SVr7dT.js +0 -1534
  275. package/examples/feature-demos/sitewide-content/node_modules/.vite/deps/audit-C3SVr7dT.js.map +0 -1
  276. package/examples/feature-demos/sitewide-content/node_modules/.vite/deps/highlight-BLtvqtzO.js +0 -48
  277. package/examples/feature-demos/sitewide-content/node_modules/.vite/deps/highlight-BLtvqtzO.js.map +0 -1
  278. package/examples/feature-demos/sitewide-content/node_modules/.vite/deps/icons-C92i61-2.js +0 -42
  279. package/examples/feature-demos/sitewide-content/node_modules/.vite/deps/icons-C92i61-2.js.map +0 -1
  280. package/examples/feature-demos/sitewide-content/node_modules/.vite/deps/package.json +0 -3
  281. package/examples/feature-demos/sitewide-content/node_modules/.vite/deps/rolldown-runtime-BvCyGRYZ.js +0 -4
  282. package/examples/feature-demos/sitewide-content/node_modules/.vite/deps/settings-v5GgKks_.js +0 -190
  283. package/examples/feature-demos/sitewide-content/node_modules/.vite/deps/settings-v5GgKks_.js.map +0 -1
  284. package/examples/feature-demos/sitewide-content/node_modules/.vite/deps/toolbar-BFvJVp26.js +0 -458
  285. package/examples/feature-demos/sitewide-content/node_modules/.vite/deps/toolbar-BFvJVp26.js.map +0 -1
  286. package/examples/feature-demos/sitewide-content/node_modules/.vite/deps/ui-library-Cd35oAvo.js +0 -1016
  287. package/examples/feature-demos/sitewide-content/node_modules/.vite/deps/ui-library-Cd35oAvo.js.map +0 -1
  288. package/examples/feature-demos/sitewide-content/node_modules/.vite/deps/window-vo3A6TMn.js +0 -32
  289. package/examples/feature-demos/sitewide-content/node_modules/.vite/deps/window-vo3A6TMn.js.map +0 -1
  290. package/examples/feature-demos/sitewide-content/node_modules/.vite/deps/xray-DwhzGckb.js +0 -111
  291. package/examples/feature-demos/sitewide-content/node_modules/.vite/deps/xray-DwhzGckb.js.map +0 -1
  292. package/examples/feature-demos/sitewide-content/site/.norna/generated-images.json +0 -1
  293. package/examples/feature-demos/sitewide-content/site/config.yaml +0 -1
  294. package/examples/feature-demos/sitewide-content/site/pages/000-home/content.md +0 -17
  295. package/examples/feature-demos/sitewide-content/site/pages/010-logo-and-navigation/content.md +0 -17
  296. package/examples/feature-demos/sitewide-content/site/pages/020-notices/content.md +0 -23
  297. package/examples/feature-demos/sitewide-content/site/pages/030-footer/content.md +0 -18
  298. package/examples/feature-demos/sitewide-content/site/public/logo.svg +0 -6
  299. package/examples/feature-demos/sitewide-content/site/public/robots.txt +0 -2
  300. package/examples/feature-demos/sitewide-content/site/sitewide-content.yaml +0 -14
  301. package/examples/feature-demos/sitewide-content/site/theme.yaml +0 -1
  302. package/examples/feature-demos/theme-preset-documentation/README.md +0 -16
  303. package/examples/feature-demos/theme-preset-documentation/site/.norna/generated-images.json +0 -74
  304. package/examples/feature-demos/theme-preset-documentation/site/config.yaml +0 -1
  305. package/examples/feature-demos/theme-preset-documentation/site/pages/000-home/content.md +0 -30
  306. package/examples/feature-demos/theme-preset-documentation/site/pages/000-home/images/black-schnauzer.jpg +0 -0
  307. package/examples/feature-demos/theme-preset-documentation/site/pages/000-home/images/retriever-portrait.jpg +0 -0
  308. package/examples/feature-demos/theme-preset-documentation/site/pages/000-home/images/schnauzer-portrait.jpg +0 -0
  309. package/examples/feature-demos/theme-preset-documentation/site/public/robots.txt +0 -2
  310. package/examples/feature-demos/theme-preset-documentation/site/sitewide-content.yaml +0 -3
  311. package/examples/feature-demos/theme-preset-documentation/site/theme.yaml +0 -1
  312. package/examples/feature-demos/theme-preset-portfolio/README.md +0 -16
  313. package/examples/feature-demos/theme-preset-portfolio/site/.norna/generated-images.json +0 -74
  314. package/examples/feature-demos/theme-preset-portfolio/site/config.yaml +0 -1
  315. package/examples/feature-demos/theme-preset-portfolio/site/pages/000-home/content.md +0 -31
  316. package/examples/feature-demos/theme-preset-portfolio/site/pages/000-home/images/puppy-portrait.jpg +0 -0
  317. package/examples/feature-demos/theme-preset-portfolio/site/pages/000-home/images/shepherd-portrait.jpg +0 -0
  318. package/examples/feature-demos/theme-preset-portfolio/site/pages/000-home/images/white-puppy.jpg +0 -0
  319. package/examples/feature-demos/theme-preset-portfolio/site/public/robots.txt +0 -2
  320. package/examples/feature-demos/theme-preset-portfolio/site/sitewide-content.yaml +0 -3
  321. package/examples/feature-demos/theme-preset-portfolio/site/theme.yaml +0 -1
  322. package/examples/feature-demos/theme-preset-project/.astro/collections/routeTheme.schema.json +0 -746
  323. package/examples/feature-demos/theme-preset-project/.astro/collections/site.schema.json +0 -59
  324. package/examples/feature-demos/theme-preset-project/.astro/collections/sitewide.schema.json +0 -138
  325. package/examples/feature-demos/theme-preset-project/.astro/collections/theme.schema.json +0 -755
  326. package/examples/feature-demos/theme-preset-project/.astro/content-assets.mjs +0 -4
  327. package/examples/feature-demos/theme-preset-project/.astro/content-modules.mjs +0 -1
  328. package/examples/feature-demos/theme-preset-project/.astro/content.d.ts +0 -183
  329. package/examples/feature-demos/theme-preset-project/.astro/data-store.json +0 -1
  330. package/examples/feature-demos/theme-preset-project/.astro/dev-local.json +0 -8
  331. package/examples/feature-demos/theme-preset-project/.astro/dev.json +0 -15
  332. package/examples/feature-demos/theme-preset-project/.astro/dev.log +0 -164
  333. package/examples/feature-demos/theme-preset-project/.astro/settings.json +0 -5
  334. package/examples/feature-demos/theme-preset-project/.astro/types.d.ts +0 -2
  335. package/examples/feature-demos/theme-preset-project/README.md +0 -16
  336. package/examples/feature-demos/theme-preset-project/node_modules/.vite/deps/_metadata.json +0 -80
  337. package/examples/feature-demos/theme-preset-project/node_modules/.vite/deps/astro-D_GIpJIE.js +0 -434
  338. package/examples/feature-demos/theme-preset-project/node_modules/.vite/deps/astro-D_GIpJIE.js.map +0 -1
  339. package/examples/feature-demos/theme-preset-project/node_modules/.vite/deps/astro_n_aria-query.js +0 -6390
  340. package/examples/feature-demos/theme-preset-project/node_modules/.vite/deps/astro_n_aria-query.js.map +0 -1
  341. package/examples/feature-demos/theme-preset-project/node_modules/.vite/deps/astro_n_axobject-query.js +0 -2702
  342. package/examples/feature-demos/theme-preset-project/node_modules/.vite/deps/astro_n_axobject-query.js.map +0 -1
  343. package/examples/feature-demos/theme-preset-project/node_modules/.vite/deps/astro_n_html-escaper.js +0 -65
  344. package/examples/feature-demos/theme-preset-project/node_modules/.vite/deps/astro_n_html-escaper.js.map +0 -1
  345. package/examples/feature-demos/theme-preset-project/node_modules/.vite/deps/astro_runtime_client_dev-toolbar_entrypoint__js.js +0 -455
  346. package/examples/feature-demos/theme-preset-project/node_modules/.vite/deps/astro_runtime_client_dev-toolbar_entrypoint__js.js.map +0 -1
  347. package/examples/feature-demos/theme-preset-project/node_modules/.vite/deps/audit-DM9Hkl5B.js +0 -1534
  348. package/examples/feature-demos/theme-preset-project/node_modules/.vite/deps/audit-DM9Hkl5B.js.map +0 -1
  349. package/examples/feature-demos/theme-preset-project/node_modules/.vite/deps/embla-carousel.js +0 -1389
  350. package/examples/feature-demos/theme-preset-project/node_modules/.vite/deps/embla-carousel.js.map +0 -1
  351. package/examples/feature-demos/theme-preset-project/node_modules/.vite/deps/highlight-DnZ1ULOL.js +0 -48
  352. package/examples/feature-demos/theme-preset-project/node_modules/.vite/deps/highlight-DnZ1ULOL.js.map +0 -1
  353. package/examples/feature-demos/theme-preset-project/node_modules/.vite/deps/icons-RyebKi45.js +0 -42
  354. package/examples/feature-demos/theme-preset-project/node_modules/.vite/deps/icons-RyebKi45.js.map +0 -1
  355. package/examples/feature-demos/theme-preset-project/node_modules/.vite/deps/package.json +0 -3
  356. package/examples/feature-demos/theme-preset-project/node_modules/.vite/deps/rolldown-runtime-BvCyGRYZ.js +0 -4
  357. package/examples/feature-demos/theme-preset-project/node_modules/.vite/deps/settings-DaU-gNnK.js +0 -190
  358. package/examples/feature-demos/theme-preset-project/node_modules/.vite/deps/settings-DaU-gNnK.js.map +0 -1
  359. package/examples/feature-demos/theme-preset-project/node_modules/.vite/deps/toolbar-63PA619H.js +0 -458
  360. package/examples/feature-demos/theme-preset-project/node_modules/.vite/deps/toolbar-63PA619H.js.map +0 -1
  361. package/examples/feature-demos/theme-preset-project/node_modules/.vite/deps/ui-library--bkcNSYz.js +0 -1016
  362. package/examples/feature-demos/theme-preset-project/node_modules/.vite/deps/ui-library--bkcNSYz.js.map +0 -1
  363. package/examples/feature-demos/theme-preset-project/node_modules/.vite/deps/window-jPkpKVcy.js +0 -32
  364. package/examples/feature-demos/theme-preset-project/node_modules/.vite/deps/window-jPkpKVcy.js.map +0 -1
  365. package/examples/feature-demos/theme-preset-project/node_modules/.vite/deps/xray-BXCHpEJP.js +0 -111
  366. package/examples/feature-demos/theme-preset-project/node_modules/.vite/deps/xray-BXCHpEJP.js.map +0 -1
  367. package/examples/feature-demos/theme-preset-project/site/.norna/generated-images.json +0 -74
  368. package/examples/feature-demos/theme-preset-project/site/config.yaml +0 -1
  369. package/examples/feature-demos/theme-preset-project/site/pages/000-home/content.md +0 -31
  370. package/examples/feature-demos/theme-preset-project/site/pages/000-home/images/boxer-portrait.jpg +0 -0
  371. package/examples/feature-demos/theme-preset-project/site/pages/000-home/images/grass-puppy.jpg +0 -0
  372. package/examples/feature-demos/theme-preset-project/site/pages/000-home/images/grey-street-dog.jpg +0 -0
  373. package/examples/feature-demos/theme-preset-project/site/public/robots.txt +0 -2
  374. package/examples/feature-demos/theme-preset-project/site/sitewide-content.yaml +0 -3
  375. package/examples/feature-demos/theme-preset-project/site/theme.yaml +0 -1
  376. package/examples/feature-demos/theme-preset-statement/README.md +0 -16
  377. package/examples/feature-demos/theme-preset-statement/site/.norna/generated-images.json +0 -74
  378. package/examples/feature-demos/theme-preset-statement/site/config.yaml +0 -1
  379. package/examples/feature-demos/theme-preset-statement/site/pages/000-home/content.md +0 -31
  380. package/examples/feature-demos/theme-preset-statement/site/pages/000-home/images/black-pedigree.jpg +0 -0
  381. package/examples/feature-demos/theme-preset-statement/site/pages/000-home/images/sheepdog-grass.jpg +0 -0
  382. package/examples/feature-demos/theme-preset-statement/site/pages/000-home/images/sheepdog-wide.jpg +0 -0
  383. package/examples/feature-demos/theme-preset-statement/site/public/robots.txt +0 -2
  384. package/examples/feature-demos/theme-preset-statement/site/sitewide-content.yaml +0 -3
  385. package/examples/feature-demos/theme-preset-statement/site/theme.yaml +0 -1
  386. package/fixtures/basic/site/.norna/generated-images.json +0 -1
  387. package/fixtures/basic/site/config.yaml +0 -1
  388. package/fixtures/basic/site/pages/000-home/content.md +0 -14
  389. package/fixtures/basic/site/pages/000-home/images/.gitkeep +0 -1
  390. package/fixtures/basic/site/public/robots.txt +0 -2
  391. package/fixtures/basic/site/sitewide-content.yaml +0 -3
  392. package/fixtures/basic/site/theme.yaml +0 -1
  393. package/fixtures/content-model-v2/.astro/collections/site.schema.json +0 -776
  394. package/fixtures/content-model-v2/.astro/collections/theme.schema.json +0 -668
  395. package/fixtures/content-model-v2/.astro/content-assets.mjs +0 -4
  396. package/fixtures/content-model-v2/.astro/content-modules.mjs +0 -1
  397. package/fixtures/content-model-v2/.astro/content.d.ts +0 -175
  398. package/fixtures/content-model-v2/.astro/data-store.json +0 -1
  399. package/fixtures/content-model-v2/.astro/dev-local.json +0 -8
  400. package/fixtures/content-model-v2/.astro/dev.json +0 -13
  401. package/fixtures/content-model-v2/.astro/dev.log +0 -231
  402. package/fixtures/content-model-v2/.astro/settings.json +0 -5
  403. package/fixtures/content-model-v2/.astro/types.d.ts +0 -2
  404. package/fixtures/content-model-v2/dist/_astro/GalleryGrid.astro_astro_type_script_index_0_lang.B0kxDyGz.js +0 -1
  405. package/fixtures/content-model-v2/dist/_astro/SitePage.BbfZub4g.css +0 -1
  406. package/fixtures/content-model-v2/dist/guide/index.html +0 -3
  407. package/fixtures/content-model-v2/dist/images/generated/intro/detail-27930b14-480.webp +0 -0
  408. package/fixtures/content-model-v2/dist/images/generated/intro/detail-27930b14-768.webp +0 -0
  409. package/fixtures/content-model-v2/dist/images/generated/intro/detail-27930b14-971.webp +0 -0
  410. package/fixtures/content-model-v2/dist/images/generated/intro/duplicate-49c98f6c-480.webp +0 -0
  411. package/fixtures/content-model-v2/dist/images/generated/intro/duplicate-49c98f6c-768.webp +0 -0
  412. package/fixtures/content-model-v2/dist/images/generated/intro/duplicate-49c98f6c-971.webp +0 -0
  413. package/fixtures/content-model-v2/dist/images/generated/intro/hero-6d588a83-480.webp +0 -0
  414. package/fixtures/content-model-v2/dist/images/generated/intro/hero-6d588a83-768.webp +0 -0
  415. package/fixtures/content-model-v2/dist/images/generated/intro/hero-6d588a83-971.webp +0 -0
  416. package/fixtures/content-model-v2/dist/images/generated/plain/image-3770d763-1080.webp +0 -0
  417. package/fixtures/content-model-v2/dist/images/generated/plain/image-3770d763-1440.webp +0 -0
  418. package/fixtures/content-model-v2/dist/images/generated/plain/image-3770d763-1600.webp +0 -0
  419. package/fixtures/content-model-v2/dist/images/generated/plain/image-3770d763-480.webp +0 -0
  420. package/fixtures/content-model-v2/dist/images/generated/plain/image-3770d763-768.webp +0 -0
  421. package/fixtures/content-model-v2/dist/images/generated/routes/010-guide/images/intro/duplicate-5cf614d2-480.webp +0 -0
  422. package/fixtures/content-model-v2/dist/images/generated/routes/010-guide/images/intro/duplicate-5cf614d2-768.webp +0 -0
  423. package/fixtures/content-model-v2/dist/images/generated/routes/010-guide/images/intro/duplicate-5cf614d2-960.webp +0 -0
  424. package/fixtures/content-model-v2/dist/images/generated/timed/slide-one-3770d763-1080.webp +0 -0
  425. package/fixtures/content-model-v2/dist/images/generated/timed/slide-one-3770d763-1440.webp +0 -0
  426. package/fixtures/content-model-v2/dist/images/generated/timed/slide-one-3770d763-1600.webp +0 -0
  427. package/fixtures/content-model-v2/dist/images/generated/timed/slide-one-3770d763-480.webp +0 -0
  428. package/fixtures/content-model-v2/dist/images/generated/timed/slide-one-3770d763-768.webp +0 -0
  429. package/fixtures/content-model-v2/dist/images/generated/timed/slide-three-5bdec65e-1080.webp +0 -0
  430. package/fixtures/content-model-v2/dist/images/generated/timed/slide-three-5bdec65e-1440.webp +0 -0
  431. package/fixtures/content-model-v2/dist/images/generated/timed/slide-three-5bdec65e-1600.webp +0 -0
  432. package/fixtures/content-model-v2/dist/images/generated/timed/slide-three-5bdec65e-480.webp +0 -0
  433. package/fixtures/content-model-v2/dist/images/generated/timed/slide-three-5bdec65e-768.webp +0 -0
  434. package/fixtures/content-model-v2/dist/images/generated/timed/slide-two-26c08aee-1080.webp +0 -0
  435. package/fixtures/content-model-v2/dist/images/generated/timed/slide-two-26c08aee-1440.webp +0 -0
  436. package/fixtures/content-model-v2/dist/images/generated/timed/slide-two-26c08aee-1600.webp +0 -0
  437. package/fixtures/content-model-v2/dist/images/generated/timed/slide-two-26c08aee-480.webp +0 -0
  438. package/fixtures/content-model-v2/dist/images/generated/timed/slide-two-26c08aee-768.webp +0 -0
  439. package/fixtures/content-model-v2/dist/index.html +0 -8
  440. package/fixtures/content-model-v2/node_modules/.vite/deps/_metadata.json +0 -80
  441. package/fixtures/content-model-v2/node_modules/.vite/deps/astro-D_GIpJIE.js +0 -434
  442. package/fixtures/content-model-v2/node_modules/.vite/deps/astro-D_GIpJIE.js.map +0 -1
  443. package/fixtures/content-model-v2/node_modules/.vite/deps/astro_n_aria-query.js +0 -6390
  444. package/fixtures/content-model-v2/node_modules/.vite/deps/astro_n_aria-query.js.map +0 -1
  445. package/fixtures/content-model-v2/node_modules/.vite/deps/astro_n_axobject-query.js +0 -2702
  446. package/fixtures/content-model-v2/node_modules/.vite/deps/astro_n_axobject-query.js.map +0 -1
  447. package/fixtures/content-model-v2/node_modules/.vite/deps/astro_n_html-escaper.js +0 -65
  448. package/fixtures/content-model-v2/node_modules/.vite/deps/astro_n_html-escaper.js.map +0 -1
  449. package/fixtures/content-model-v2/node_modules/.vite/deps/astro_runtime_client_dev-toolbar_entrypoint__js.js +0 -455
  450. package/fixtures/content-model-v2/node_modules/.vite/deps/astro_runtime_client_dev-toolbar_entrypoint__js.js.map +0 -1
  451. package/fixtures/content-model-v2/node_modules/.vite/deps/audit-DM9Hkl5B.js +0 -1534
  452. package/fixtures/content-model-v2/node_modules/.vite/deps/audit-DM9Hkl5B.js.map +0 -1
  453. package/fixtures/content-model-v2/node_modules/.vite/deps/embla-carousel.js +0 -1389
  454. package/fixtures/content-model-v2/node_modules/.vite/deps/embla-carousel.js.map +0 -1
  455. package/fixtures/content-model-v2/node_modules/.vite/deps/highlight-DnZ1ULOL.js +0 -48
  456. package/fixtures/content-model-v2/node_modules/.vite/deps/highlight-DnZ1ULOL.js.map +0 -1
  457. package/fixtures/content-model-v2/node_modules/.vite/deps/icons-RyebKi45.js +0 -42
  458. package/fixtures/content-model-v2/node_modules/.vite/deps/icons-RyebKi45.js.map +0 -1
  459. package/fixtures/content-model-v2/node_modules/.vite/deps/package.json +0 -3
  460. package/fixtures/content-model-v2/node_modules/.vite/deps/rolldown-runtime-BvCyGRYZ.js +0 -4
  461. package/fixtures/content-model-v2/node_modules/.vite/deps/settings-DaU-gNnK.js +0 -190
  462. package/fixtures/content-model-v2/node_modules/.vite/deps/settings-DaU-gNnK.js.map +0 -1
  463. package/fixtures/content-model-v2/node_modules/.vite/deps/toolbar-63PA619H.js +0 -458
  464. package/fixtures/content-model-v2/node_modules/.vite/deps/toolbar-63PA619H.js.map +0 -1
  465. package/fixtures/content-model-v2/node_modules/.vite/deps/ui-library--bkcNSYz.js +0 -1016
  466. package/fixtures/content-model-v2/node_modules/.vite/deps/ui-library--bkcNSYz.js.map +0 -1
  467. package/fixtures/content-model-v2/node_modules/.vite/deps/window-jPkpKVcy.js +0 -32
  468. package/fixtures/content-model-v2/node_modules/.vite/deps/window-jPkpKVcy.js.map +0 -1
  469. package/fixtures/content-model-v2/node_modules/.vite/deps/xray-BXCHpEJP.js +0 -111
  470. package/fixtures/content-model-v2/node_modules/.vite/deps/xray-BXCHpEJP.js.map +0 -1
  471. package/fixtures/content-model-v2/site/.norna/generated-images.json +0 -210
  472. package/fixtures/content-model-v2/site/config.yaml +0 -1
  473. package/fixtures/content-model-v2/site/pages/000-home/content.md +0 -79
  474. package/fixtures/content-model-v2/site/pages/000-home/images/adopt.svg +0 -9
  475. package/fixtures/content-model-v2/site/pages/000-home/images/detail.jpg +0 -0
  476. package/fixtures/content-model-v2/site/pages/000-home/images/duplicate.jpg +0 -0
  477. package/fixtures/content-model-v2/site/pages/000-home/images/foster.svg +0 -12
  478. package/fixtures/content-model-v2/site/pages/000-home/images/hero.jpg +0 -0
  479. package/fixtures/content-model-v2/site/pages/000-home/images/image.jpg +0 -0
  480. package/fixtures/content-model-v2/site/pages/000-home/images/slide-one.jpg +0 -0
  481. package/fixtures/content-model-v2/site/pages/000-home/images/slide-three.jpg +0 -0
  482. package/fixtures/content-model-v2/site/pages/000-home/images/slide-two.jpg +0 -0
  483. package/fixtures/content-model-v2/site/pages/010-guide/content.md +0 -18
  484. package/fixtures/content-model-v2/site/pages/010-guide/images/duplicate.jpg +0 -0
  485. package/fixtures/content-model-v2/site/theme.yaml +0 -4
  486. package/fixtures/nested-pages/.astro/collections/site.schema.json +0 -35
  487. package/fixtures/nested-pages/.astro/collections/sitewide.schema.json +0 -97
  488. package/fixtures/nested-pages/.astro/collections/theme.schema.json +0 -844
  489. package/fixtures/nested-pages/.astro/content-assets.mjs +0 -4
  490. package/fixtures/nested-pages/.astro/content-modules.mjs +0 -1
  491. package/fixtures/nested-pages/.astro/content.d.ts +0 -183
  492. package/fixtures/nested-pages/.astro/data-store.json +0 -1
  493. package/fixtures/nested-pages/.astro/dev-local.json +0 -8
  494. package/fixtures/nested-pages/.astro/dev.log +0 -1128
  495. package/fixtures/nested-pages/.astro/settings.json +0 -5
  496. package/fixtures/nested-pages/.astro/types.d.ts +0 -2
  497. package/fixtures/nested-pages/node_modules/.vite/deps/_metadata.json +0 -74
  498. package/fixtures/nested-pages/node_modules/.vite/deps/astro-D_GIpJIE.js +0 -434
  499. package/fixtures/nested-pages/node_modules/.vite/deps/astro-D_GIpJIE.js.map +0 -1
  500. package/fixtures/nested-pages/node_modules/.vite/deps/astro_n_aria-query.js +0 -6390
  501. package/fixtures/nested-pages/node_modules/.vite/deps/astro_n_aria-query.js.map +0 -1
  502. package/fixtures/nested-pages/node_modules/.vite/deps/astro_n_axobject-query.js +0 -2702
  503. package/fixtures/nested-pages/node_modules/.vite/deps/astro_n_axobject-query.js.map +0 -1
  504. package/fixtures/nested-pages/node_modules/.vite/deps/astro_n_html-escaper.js +0 -65
  505. package/fixtures/nested-pages/node_modules/.vite/deps/astro_n_html-escaper.js.map +0 -1
  506. package/fixtures/nested-pages/node_modules/.vite/deps/astro_runtime_client_dev-toolbar_entrypoint__js.js +0 -455
  507. package/fixtures/nested-pages/node_modules/.vite/deps/astro_runtime_client_dev-toolbar_entrypoint__js.js.map +0 -1
  508. package/fixtures/nested-pages/node_modules/.vite/deps/audit-DM9Hkl5B.js +0 -1534
  509. package/fixtures/nested-pages/node_modules/.vite/deps/audit-DM9Hkl5B.js.map +0 -1
  510. package/fixtures/nested-pages/node_modules/.vite/deps/highlight-DnZ1ULOL.js +0 -48
  511. package/fixtures/nested-pages/node_modules/.vite/deps/highlight-DnZ1ULOL.js.map +0 -1
  512. package/fixtures/nested-pages/node_modules/.vite/deps/icons-RyebKi45.js +0 -42
  513. package/fixtures/nested-pages/node_modules/.vite/deps/icons-RyebKi45.js.map +0 -1
  514. package/fixtures/nested-pages/node_modules/.vite/deps/package.json +0 -3
  515. package/fixtures/nested-pages/node_modules/.vite/deps/rolldown-runtime-BvCyGRYZ.js +0 -4
  516. package/fixtures/nested-pages/node_modules/.vite/deps/settings-DaU-gNnK.js +0 -190
  517. package/fixtures/nested-pages/node_modules/.vite/deps/settings-DaU-gNnK.js.map +0 -1
  518. package/fixtures/nested-pages/node_modules/.vite/deps/toolbar-63PA619H.js +0 -458
  519. package/fixtures/nested-pages/node_modules/.vite/deps/toolbar-63PA619H.js.map +0 -1
  520. package/fixtures/nested-pages/node_modules/.vite/deps/ui-library--bkcNSYz.js +0 -1016
  521. package/fixtures/nested-pages/node_modules/.vite/deps/ui-library--bkcNSYz.js.map +0 -1
  522. package/fixtures/nested-pages/node_modules/.vite/deps/window-jPkpKVcy.js +0 -32
  523. package/fixtures/nested-pages/node_modules/.vite/deps/window-jPkpKVcy.js.map +0 -1
  524. package/fixtures/nested-pages/node_modules/.vite/deps/xray-BXCHpEJP.js +0 -111
  525. package/fixtures/nested-pages/node_modules/.vite/deps/xray-BXCHpEJP.js.map +0 -1
  526. package/fixtures/nested-pages/site/.norna/generated-images.json +0 -10
  527. package/fixtures/nested-pages/site/config.yaml +0 -3
  528. package/fixtures/nested-pages/site/pages/000-home/content.md +0 -15
  529. package/fixtures/nested-pages/site/pages/010-guides/content.md +0 -15
  530. package/fixtures/nested-pages/site/pages/010-guides/pages/010-installation/content.md +0 -21
  531. package/fixtures/nested-pages/site/pages/010-guides/pages/010-installation/images/diagram.svg +0 -21
  532. package/fixtures/nested-pages/site/pages/010-guides/pages/010-installation/pages/010-macos/content.md +0 -18
  533. package/fixtures/nested-pages/site/pages/010-guides/pages/010-installation/theme.yaml +0 -2
  534. package/fixtures/nested-pages/site/pages/010-guides/pages/020-workflows/content.md +0 -11
  535. package/fixtures/nested-pages/site/pages/010-guides/pages/030-release-notes/content.md +0 -9
  536. package/fixtures/nested-pages/site/pages/010-guides/pages/040-configuration/content.md +0 -3
  537. package/fixtures/nested-pages/site/pages/010-guides/pages/050-content/content.md +0 -3
  538. package/fixtures/nested-pages/site/pages/010-guides/pages/060-themes/content.md +0 -3
  539. package/fixtures/nested-pages/site/pages/010-guides/pages/070-images/content.md +0 -3
  540. package/fixtures/nested-pages/site/pages/010-guides/pages/080-cards/content.md +0 -3
  541. package/fixtures/nested-pages/site/pages/010-guides/pages/090-notes/content.md +0 -3
  542. package/fixtures/nested-pages/site/pages/010-guides/pages/100-validation/content.md +0 -3
  543. package/fixtures/nested-pages/site/pages/010-guides/pages/110-synchronization/content.md +0 -3
  544. package/fixtures/nested-pages/site/pages/010-guides/pages/120-building/content.md +0 -3
  545. package/fixtures/nested-pages/site/pages/010-guides/pages/130-publishing/content.md +0 -3
  546. package/fixtures/nested-pages/site/pages/010-guides/pages/140-troubleshooting/content.md +0 -3
  547. package/fixtures/nested-pages/site/pages/010-guides/pages/150-migration/content.md +0 -3
  548. package/fixtures/nested-pages/site/pages/010-guides/pages/160-accessibility/content.md +0 -3
  549. package/fixtures/nested-pages/site/pages/010-guides/pages/170-performance/content.md +0 -3
  550. package/fixtures/nested-pages/site/pages/010-guides/pages/180-security/content.md +0 -3
  551. package/fixtures/nested-pages/site/pages/010-guides/pages/190-localization/content.md +0 -3
  552. package/fixtures/nested-pages/site/pages/010-guides/pages/200-upgrading/content.md +0 -3
  553. package/fixtures/nested-pages/site/pages/010-guides/pages/210-faq/content.md +0 -3
  554. package/fixtures/nested-pages/site/pages/010-guides/theme.yaml +0 -7
  555. package/fixtures/nested-pages/site/pages/020-reference/content.md +0 -10
  556. package/fixtures/nested-pages/site/pages/020-reference/pages/010-installation/content.md +0 -11
  557. package/fixtures/nested-pages/site/theme.yaml +0 -1
  558. package/scripts/build-pages.mjs +0 -69
  559. package/scripts/lib/example-sites.mjs +0 -49
  560. package/scripts/lib/frontmatter-yaml.mjs +0 -113
  561. package/scripts/lib/git-status.mjs +0 -7
  562. package/scripts/release.mjs +0 -153
  563. package/scripts/test-banner-visibility.mjs +0 -80
  564. package/scripts/test-ci-lockfile.mjs +0 -65
  565. package/scripts/test-cli-discovery.mjs +0 -124
  566. package/scripts/test-client-javascript.mjs +0 -225
  567. package/scripts/test-content-check.mjs +0 -621
  568. package/scripts/test-content-model-v2.mjs +0 -1693
  569. package/scripts/test-documentation.mjs +0 -189
  570. package/scripts/test-editor-language-service.mjs +0 -305
  571. package/scripts/test-engine-commands.mjs +0 -204
  572. package/scripts/test-examples.mjs +0 -53
  573. package/scripts/test-heading-ids.mjs +0 -68
  574. package/scripts/test-navigation-model.mjs +0 -63
  575. package/scripts/test-navigation-preview.mjs +0 -108
  576. package/scripts/test-navigation.mjs +0 -157
  577. package/scripts/test-nested-pages.mjs +0 -125
  578. package/scripts/test-package-check.mjs +0 -500
  579. package/scripts/test-page-model.mjs +0 -108
  580. package/scripts/test-project-config.mjs +0 -139
  581. package/scripts/test-schemas.mjs +0 -169
  582. package/scripts/test-site-public.mjs +0 -85
  583. package/scripts/test-theme-presets.mjs +0 -188
  584. package/src/components/SiteNotesScript.astro +0 -43
  585. package/starters/project/.github/workflows/deploy.yml +0 -64
  586. package/starters/project/README.md +0 -84
  587. package/starters/project/package-lock.json +0 -4296
  588. package/starters/project/package.json +0 -37
  589. package/starters/project/site/config.yaml +0 -1
  590. package/starters/project/site/pages/000-home/content.md +0 -119
  591. package/starters/project/site/pages/010-guide/content.md +0 -80
  592. package/starters/project/site/public/robots.txt +0 -2
  593. package/starters/project/site/sitewide-content.yaml +0 -3
  594. package/starters/project/site/theme.yaml +0 -1
  595. package/tsconfig.json +0 -5
@@ -0,0 +1,141 @@
1
+ const preferenceDefinitions = Object.freeze({
2
+ appearance: Object.freeze({
3
+ allowed: Object.freeze(['system', 'light', 'dark']),
4
+ cookieName: 'norna-color-mode',
5
+ }),
6
+ readingWidth: Object.freeze({
7
+ allowed: Object.freeze(['narrow', 'standard', 'wide']),
8
+ cookieName: 'norna-reading-width',
9
+ }),
10
+ focusReading: Object.freeze({
11
+ allowed: Object.freeze(['off', 'on']),
12
+ cookieName: 'norna-focus-reading',
13
+ }),
14
+ });
15
+
16
+ export const getReaderPreferencesScript = ({ controls, defaults, cookiePath }) => `(() => {
17
+ const root = document.documentElement;
18
+ const controls = ${JSON.stringify(controls)};
19
+ const defaults = ${JSON.stringify(defaults)};
20
+ const cookiePath = ${JSON.stringify(cookiePath)};
21
+ const definitions = ${JSON.stringify(preferenceDefinitions)};
22
+ const values = { ...defaults };
23
+ const readCookie = (name) => {
24
+ const prefix = encodeURIComponent(name) + '=';
25
+ const cookie = document.cookie.split('; ').find((part) => part.startsWith(prefix));
26
+ return cookie ? decodeURIComponent(cookie.slice(prefix.length)) : null;
27
+ };
28
+ const writeCookie = (name, value, maxAge = 31536000) => {
29
+ try {
30
+ const secure = location.protocol === 'https:' ? '; Secure' : '';
31
+ document.cookie = encodeURIComponent(name) + '=' + encodeURIComponent(value)
32
+ + '; Path=' + cookiePath + '; Max-Age=' + maxAge + '; SameSite=Lax' + secure;
33
+ } catch {}
34
+ };
35
+ const isAllowed = (name, value) => definitions[name].allowed.includes(value);
36
+ const captureReadingPosition = () => {
37
+ if (window.scrollY <= 1) return null;
38
+ const contentTop = document.querySelector('.site-top')?.getBoundingClientRect().bottom ?? 0;
39
+ const candidates = document.querySelectorAll([
40
+ '#main-content .section-header',
41
+ '#main-content .section-markdown > *',
42
+ '#main-content .image-stack',
43
+ '#main-content .image-carousel',
44
+ '#main-content .card-list',
45
+ ].join(', '));
46
+ const element = Array.from(candidates).find((candidate) => {
47
+ const rectangle = candidate.getBoundingClientRect();
48
+ return rectangle.height > 0 && rectangle.bottom > contentTop + 1;
49
+ });
50
+ return element ? { element, top: element.getBoundingClientRect().top } : null;
51
+ };
52
+ const restoreReadingPosition = (position) => {
53
+ if (!position) return;
54
+ requestAnimationFrame(() => {
55
+ const delta = position.element.getBoundingClientRect().top - position.top;
56
+ if (Math.abs(delta) < 0.5) return;
57
+ const scrollBehavior = root.style.scrollBehavior;
58
+ root.style.scrollBehavior = 'auto';
59
+ window.scrollBy(0, delta);
60
+ root.style.scrollBehavior = scrollBehavior;
61
+ });
62
+ };
63
+ const preserveReadingPosition = (change) => {
64
+ const position = captureReadingPosition();
65
+ change();
66
+ restoreReadingPosition(position);
67
+ };
68
+ const updateThemeColor = () => requestAnimationFrame(() => {
69
+ const themeColor = getComputedStyle(root).getPropertyValue('--color-page').trim();
70
+ if (themeColor) document.querySelectorAll('meta[name="theme-color"]').forEach((meta) => meta.content = themeColor);
71
+ });
72
+ const apply = (name, value, persist = false) => {
73
+ const nextValue = isAllowed(name, value) ? value : defaults[name];
74
+ values[name] = nextValue;
75
+ if (name === 'appearance') root.dataset.colorMode = nextValue;
76
+ if (name === 'readingWidth') root.dataset.readingWidth = nextValue;
77
+ if (name === 'focusReading') root.dataset.focusReading = nextValue;
78
+ if (persist) writeCookie(definitions[name].cookieName, nextValue);
79
+ if (name === 'appearance') updateThemeColor();
80
+ };
81
+ for (const name of Object.keys(definitions)) {
82
+ const saved = controls[name] ? readCookie(definitions[name].cookieName) : null;
83
+ apply(name, saved && isAllowed(name, saved) ? saved : defaults[name]);
84
+ }
85
+ root.dataset.readerPreferencesReady = 'true';
86
+ const syncControls = () => {
87
+ document.querySelectorAll('[data-reader-appearance]').forEach((input) => {
88
+ input.checked = input.value === values.appearance;
89
+ });
90
+ document.querySelectorAll('[data-reader-width]').forEach((input) => {
91
+ input.checked = input.value === values.readingWidth;
92
+ });
93
+ document.querySelectorAll('[data-reader-focus]').forEach((input) => {
94
+ input.checked = values.focusReading === 'on';
95
+ });
96
+ };
97
+ document.addEventListener('DOMContentLoaded', () => {
98
+ syncControls();
99
+ document.querySelectorAll('[data-reader-appearance]').forEach((input) => {
100
+ input.addEventListener('change', () => {
101
+ if (input.checked) apply('appearance', input.value, true);
102
+ });
103
+ });
104
+ document.querySelectorAll('[data-reader-width]').forEach((input) => {
105
+ input.addEventListener('change', () => {
106
+ if (input.checked) preserveReadingPosition(() => apply('readingWidth', input.value, true));
107
+ });
108
+ });
109
+ document.querySelectorAll('[data-reader-focus]').forEach((input) => {
110
+ input.addEventListener('change', () => preserveReadingPosition(() => {
111
+ apply('focusReading', input.checked ? 'on' : 'off', true);
112
+ }));
113
+ });
114
+ document.querySelectorAll('[data-reader-reset]').forEach((button) => {
115
+ button.addEventListener('click', () => {
116
+ preserveReadingPosition(() => {
117
+ for (const name of Object.keys(definitions)) {
118
+ writeCookie(definitions[name].cookieName, '', 0);
119
+ apply(name, defaults[name]);
120
+ }
121
+ syncControls();
122
+ });
123
+ });
124
+ });
125
+ document.querySelectorAll('[data-display-settings]').forEach((settings) => {
126
+ settings.addEventListener('keydown', (event) => {
127
+ if (event.key !== 'Escape') return;
128
+ settings.removeAttribute('open');
129
+ settings.querySelector('summary')?.focus();
130
+ });
131
+ });
132
+ });
133
+ document.addEventListener('click', (event) => {
134
+ document.querySelectorAll('[data-display-settings][open]').forEach((settings) => {
135
+ if (!settings.contains(event.target)) settings.removeAttribute('open');
136
+ });
137
+ });
138
+ matchMedia('(prefers-color-scheme: dark)').addEventListener('change', () => {
139
+ if (values.appearance === 'system') updateThemeColor();
140
+ });
141
+ })();`;
@@ -2,15 +2,7 @@ import { markdownToHtml } from 'satteri';
2
2
  import projectConfig from '../../scripts/lib/project-config.mjs';
3
3
  import {
4
4
  formatHeadingIdentifierIssue,
5
- getHeadingIdentifierIssues,
6
5
  } from '../../scripts/lib/heading-ids.mjs';
7
- import { getBodySections } from '../../scripts/lib/site-content.mjs';
8
- import {
9
- extractInlineNoteDiagnostics,
10
- extractNornaMarkdownBlocks,
11
- splitNornaMarkdownBlockMarkers,
12
- splitNornaRenderedCodeBlocks,
13
- } from '../../scripts/lib/norna-markdown-blocks.mjs';
14
6
  import { applyBasePathToHtml } from './basePath';
15
7
  import type { SitePage } from './sitePages';
16
8
 
@@ -32,18 +24,31 @@ type CardListLayout = 'image-top' | 'image-left' | 'image-right';
32
24
  type CardListFlow = 'grid' | 'stack';
33
25
  type CardListSize = 's' | 'm' | 'l' | 'xl';
34
26
  type CardListWidth = 'text' | 'narrow' | 'normal' | 'wide';
27
+ type ParsedImageBlock = {
28
+ type: 'image-stack' | 'image-carousel';
29
+ images: Array<{ image: string; alt?: string; caption?: string }>;
30
+ };
31
+ type ParsedCardListBlock = {
32
+ type: 'card-list';
33
+ layout: CardListLayout;
34
+ flow: CardListFlow;
35
+ size: CardListSize;
36
+ width?: CardListWidth;
37
+ cards: CardListItem[];
38
+ };
39
+ type ParsedNornaBlock = ParsedImageBlock | ParsedCardListBlock;
35
40
  type InlineNote = {
36
41
  markdown: string;
37
42
  number: number;
38
43
  id: string;
39
44
  referenceId: string;
45
+ html?: string;
40
46
  };
41
47
  type SectionContentBlock =
42
48
  | { type: 'html'; html: string }
43
49
  | { type: 'image-stack'; images: ManagedImage[] }
44
50
  | { type: 'image-carousel'; images: ManagedImage[] }
45
- | { type: 'card-list'; layout: CardListLayout; flow: CardListFlow; size: CardListSize; width: CardListWidth; cards: CardListItem[] }
46
- | { type: 'note'; html: string; number?: number; id?: string; referenceId?: string };
51
+ | { type: 'card-list'; layout: CardListLayout; flow: CardListFlow; size: CardListSize; width?: CardListWidth; cards: CardListItem[] };
47
52
  export type ResolvedSection = {
48
53
  id: string | null;
49
54
  title: string;
@@ -62,57 +67,9 @@ export type HeadingNavigation = SectionNavigation & {
62
67
  parentId: string | null;
63
68
  };
64
69
 
65
- const contentHeadingRegex = /<h([12])\b([^>]*)>([\s\S]*?)<\/h\1>/gi;
66
70
  const explicitHeadingIdRegex = /\s*\{#([a-z0-9-]+)\}\s*$/;
67
71
  const imageProvenanceCommentRegex = /<!--\s*norna-image-provenance:[\s\S]*?-->/gi;
68
72
 
69
- const stripTags = (html: string) => html.replace(/<[^>]*>/g, '');
70
-
71
- const decodeHtmlEntities = (value: string) =>
72
- value
73
- .replace(/&amp;/g, '&')
74
- .replace(/&lt;/g, '<')
75
- .replace(/&gt;/g, '>')
76
- .replace(/&quot;/g, '"')
77
- .replace(/&#39;/g, "'");
78
-
79
- const getHeadingTitle = (headingHtml: string) =>
80
- decodeHtmlEntities(stripTags(headingHtml)).replace(explicitHeadingIdRegex, '').trim();
81
-
82
- const getHeadingTitleHtml = (headingHtml: string) =>
83
- prepareContentHtml(headingHtml.replace(explicitHeadingIdRegex, '').trim());
84
-
85
- export const getHeadingNavigation = async (
86
- markdown: string,
87
- sourceLabel = 'Markdown',
88
- ): Promise<HeadingNavigation[]> => {
89
- const bodyStructure = await getBodySections(markdown);
90
- const issues = getHeadingIdentifierIssues(bodyStructure.headings);
91
- if (issues.length > 0) throw new Error(formatHeadingIdentifierIssue(issues[0], sourceLabel));
92
-
93
- let parentId: string | null = null;
94
- return bodyStructure.headings.flatMap((heading) => {
95
- if (heading.depth === 1 || !heading.id) return [];
96
- if (heading.depth === 2) parentId = heading.id;
97
-
98
- return [{
99
- depth: heading.depth,
100
- id: heading.id,
101
- parentId: heading.depth === 3 ? parentId : null,
102
- title: heading.title,
103
- }];
104
- });
105
- };
106
-
107
- export const getSectionNavigation = async (
108
- markdown: string,
109
- sourceLabel = 'Markdown',
110
- ): Promise<SectionNavigation[]> => (
111
- (await getHeadingNavigation(markdown, sourceLabel))
112
- .filter((heading) => heading.depth === 2)
113
- .map(({ id, title }) => ({ id, title }))
114
- );
115
-
116
73
  const stripImageProvenanceComments = (html: string) => html.replace(imageProvenanceCommentRegex, '');
117
74
 
118
75
  const prepareContentHtml = (html: string) =>
@@ -121,62 +78,6 @@ const prepareContentHtml = (html: string) =>
121
78
  stripImageProvenanceComments(html),
122
79
  );
123
80
 
124
- const htmlVoidElements = new Set([
125
- 'area', 'base', 'br', 'col', 'embed', 'hr', 'img', 'input', 'link',
126
- 'meta', 'param', 'source', 'track', 'wbr',
127
- ]);
128
-
129
- // Keep notes aligned with the Markdown block immediately before them instead of
130
- // aligning them with a whole run of paragraphs rendered as one HTML fragment.
131
- const splitHtmlIntoBlocks = (html: string) => {
132
- const tagRegex = /<!--[\s\S]*?-->|<\/?([a-z][\w:-]*)(?:\s[^<>]*?)?\/?>/gi;
133
- const blocks: string[] = [];
134
- let blockStart = -1;
135
- let depth = 0;
136
- let cursor = 0;
137
-
138
- for (const match of html.matchAll(tagRegex)) {
139
- const start = match.index ?? 0;
140
- const token = match[0] ?? '';
141
- const tagName = match[1]?.toLowerCase();
142
- if (!tagName) continue;
143
-
144
- const isClosing = /^<\//.test(token);
145
- const isSelfClosing = /\/\s*>$/.test(token) || htmlVoidElements.has(tagName);
146
-
147
- if (isClosing) {
148
- if (depth > 0) depth -= 1;
149
- if (depth === 0 && blockStart >= 0) {
150
- blocks.push(html.slice(blockStart, start + token.length));
151
- cursor = start + token.length;
152
- blockStart = -1;
153
- }
154
- continue;
155
- }
156
-
157
- if (depth === 0) {
158
- if (blockStart < 0) blockStart = start;
159
- if (isSelfClosing) {
160
- blocks.push(html.slice(blockStart, start + token.length));
161
- cursor = start + token.length;
162
- blockStart = -1;
163
- }
164
- }
165
-
166
- if (!isSelfClosing) depth += 1;
167
- }
168
-
169
- if (blockStart >= 0) {
170
- blocks.push(html.slice(blockStart).trim());
171
- cursor = html.length;
172
- }
173
-
174
- const prefix = html.slice(0, blocks.length > 0 ? html.indexOf(blocks[0]!) : html.length).trim();
175
- const suffix = html.slice(cursor).trim();
176
- return [prefix, ...blocks, suffix].filter(Boolean);
177
- };
178
-
179
- const inlineNoteMarkerRegex = /^\s*<norna-inline-note\s+data-note-index="(\d+)"\s*><\/norna-inline-note>\s*$/i;
180
81
  const noteDeclarationParagraphRegex = /<p>\s*\{note:\s*[\s\S]*?\}\s*<\/p>/gi;
181
82
  const htmlCodeRegionRegex = /<pre\b[\s\S]*?<\/pre>|<code\b[\s\S]*?<\/code>/gi;
182
83
 
@@ -201,32 +102,22 @@ const applyInlineNoteMarkup = (html: string, notes: InlineNote[]) => {
201
102
  if (!note) return '{note-ref}';
202
103
 
203
104
  referenceIndex += 1;
204
- return `\u2060<sup class="section-note-ref"><a id="${note.referenceId}" href="#${note.id}" aria-label="Note ${note.number}" aria-describedby="${note.id}" data-note-id="${note.id}">${note.number}</a></sup>`;
105
+ return [
106
+ '\u2060',
107
+ `<sup class="section-note-ref"><a id="${note.referenceId}" href="#${note.id}" aria-label="Note ${note.number}" aria-describedby="${note.id}">${note.number}</a></sup>`,
108
+ `<span class="section-note section-note-margin" id="${note.id}" aria-label="Note ${note.number}" role="note">`,
109
+ `<a class="section-note-number" href="#${note.referenceId}" aria-label="Note ${note.number}">${note.number}</a>`,
110
+ `<span class="section-note-content">${note.html ?? ''}</span>`,
111
+ '</span>',
112
+ ].join('');
205
113
  }));
206
114
 
207
- let noteIndex = 0;
208
- return withReferences.replace(noteDeclarationParagraphRegex, () => {
209
- const marker = `<norna-inline-note data-note-index="${noteIndex}"></norna-inline-note>`;
210
- noteIndex += 1;
211
- return marker;
212
- });
213
- };
214
-
215
- const getRawMarkdownSections = (bodySections: Awaited<ReturnType<typeof getBodySections>>['sections']) => {
216
- const sections = new Map<string, string>();
217
-
218
- for (const section of bodySections) {
219
- const id = section.isPageTitle ? '__page-title' : section.id;
220
- if (!id) continue;
221
- sections.set(id, section.text);
222
- }
223
-
224
- return sections;
115
+ return withReferences.replace(noteDeclarationParagraphRegex, '');
225
116
  };
226
117
 
227
118
  const applyH3HeadingIds = (
228
119
  html: string,
229
- headings: Awaited<ReturnType<typeof getBodySections>>['headings'],
120
+ headings: Array<{ id: string | null }>,
230
121
  ) => {
231
122
  let headingIndex = 0;
232
123
  const result = html.replace(/<h3\b([^>]*)>([\s\S]*?)<\/h3>/gi, (_match, attributes, headingHtml) => {
@@ -260,47 +151,89 @@ const renderInlineNoteMarkdown = async (markdown: string) => {
260
151
  throw new Error('Inline notes cannot contain images. Use a Norna image block with a caption instead.');
261
152
  }
262
153
 
263
- return prepareContentHtml(result.html);
154
+ const inlineHtml = result.html.trim();
155
+ const paragraph = inlineHtml.match(/^<p>([\s\S]*)<\/p>$/i);
156
+ if (!paragraph) {
157
+ throw new Error('Inline notes support inline Markdown only. Move headings, lists, and separate paragraphs into the page content.');
158
+ }
159
+
160
+ return paragraph[1] ?? '';
161
+ };
162
+
163
+ const renderHeadingTitleHtml = async (headingSource: string) => {
164
+ const headingMarkdown = headingSource
165
+ .replace(/^#{1,6}[ \t]+/, '')
166
+ .replace(explicitHeadingIdRegex, '')
167
+ .trim();
168
+ const result = await markdownToHtml(headingMarkdown, {
169
+ features: {
170
+ gfm: true,
171
+ smartPunctuation: true,
172
+ },
173
+ });
174
+ const paragraph = result.html.trim().match(/^<p>([\s\S]*)<\/p>$/i);
175
+ if (!paragraph) throw new Error('Markdown heading could not be rendered as inline content.');
176
+ return prepareContentHtml(paragraph[1] ?? '');
177
+ };
178
+
179
+ const splitRenderedRegions = (html: string, regionCount: number) => {
180
+ const markerRegex = /<norna-region\s+data-index="(\d+)"\s*><\/norna-region>/g;
181
+ const markers = Array.from(html.matchAll(markerRegex));
182
+ if (markers.length !== regionCount) {
183
+ throw new Error(`Rendered Markdown contains ${markers.length} page region markers, but ${regionCount} regions were parsed.`);
184
+ }
185
+
186
+ return markers.map((marker, position) => {
187
+ const index = Number.parseInt(marker[1] ?? '', 10);
188
+ if (index !== position) throw new Error(`Rendered page region ${position + 1} has unexpected index ${index}.`);
189
+ const start = (marker.index ?? 0) + marker[0].length;
190
+ const end = markers[position + 1]?.index ?? html.length;
191
+ return html.slice(start, end).trim();
192
+ });
193
+ };
194
+
195
+ const splitNornaBlockMarkers = (html: string, blocks: ParsedNornaBlock[]) => {
196
+ const result: Array<{ type: 'html'; html: string } | ParsedNornaBlock> = [];
197
+ const markerRegex = /<norna-block\s+data-index="(\d+)"\s*><\/norna-block>/g;
198
+ const seen = new Set<number>();
199
+ let cursor = 0;
200
+
201
+ for (const match of html.matchAll(markerRegex)) {
202
+ const start = match.index ?? 0;
203
+ if (start > cursor) result.push({ type: 'html', html: html.slice(cursor, start) });
204
+
205
+ const index = Number.parseInt(match[1] ?? '', 10);
206
+ const block = blocks[index];
207
+ if (!block) throw new Error(`Rendered Norna block ${index + 1} has no matching parsed block.`);
208
+ seen.add(index);
209
+ result.push(block);
210
+ cursor = start + match[0].length;
211
+ }
212
+
213
+ if (cursor < html.length) result.push({ type: 'html', html: html.slice(cursor) });
214
+ if (seen.size !== blocks.length) {
215
+ throw new Error(`Rendered Markdown contains ${seen.size} Norna block markers, but ${blocks.length} blocks were parsed.`);
216
+ }
217
+
218
+ return result.filter((block) => block.type !== 'html' || block.html.trim());
264
219
  };
265
220
 
266
221
  const resolveContentBlocks = async (
267
222
  html: string,
268
- rawMarkdown: string,
223
+ blocks: ParsedNornaBlock[],
269
224
  page: SitePage,
270
225
  inlineNotes: InlineNote[] = [],
271
226
  ) => {
272
- const rawBlocks = extractNornaMarkdownBlocks(rawMarkdown);
273
- const renderedHtml = applyInlineNoteMarkup(html, inlineNotes);
274
- const splitBlocks = rawBlocks.length > 0
275
- ? splitNornaRenderedCodeBlocks(renderedHtml, rawBlocks)
276
- : splitNornaMarkdownBlockMarkers(renderedHtml);
277
- const hasNotes = inlineNotes.length > 0;
278
- const contentBlocks = hasNotes
279
- ? splitBlocks.flatMap((block) => block.type === 'html'
280
- ? splitHtmlIntoBlocks(block.html).map((htmlBlock) => ({ type: 'html' as const, html: htmlBlock }))
281
- : [block])
282
- : splitBlocks;
227
+ const renderedNotes = await Promise.all(inlineNotes.map(async (note) => ({
228
+ ...note,
229
+ html: await renderInlineNoteMarkdown(note.markdown),
230
+ })));
231
+ const renderedHtml = applyInlineNoteMarkup(html, renderedNotes);
232
+ const splitBlocks = splitNornaBlockMarkers(renderedHtml, blocks);
283
233
  const resolvedBlocks: SectionContentBlock[] = [];
284
234
 
285
- for (const block of contentBlocks) {
235
+ for (const block of splitBlocks) {
286
236
  if (block.type === 'html') {
287
- const inlineNoteMarker = block.html.match(inlineNoteMarkerRegex);
288
- if (inlineNoteMarker) {
289
- const note = inlineNotes[Number(inlineNoteMarker[1])];
290
- if (!note) {
291
- throw new Error('Norna inline note markup could not be matched to its note text.');
292
- }
293
-
294
- resolvedBlocks.push({
295
- type: 'note',
296
- html: await renderInlineNoteMarkdown(note.markdown),
297
- number: note.number,
298
- id: note.id,
299
- referenceId: note.referenceId,
300
- });
301
- continue;
302
- }
303
-
304
237
  resolvedBlocks.push({ type: 'html', html: prepareContentHtml(block.html) });
305
238
  continue;
306
239
  }
@@ -334,46 +267,32 @@ const resolveContentBlocks = async (
334
267
 
335
268
  export const getSectionsContent = async (
336
269
  html: string,
337
- rawMarkdown: string,
338
270
  page: SitePage,
339
- sourceLabel = 'Markdown',
340
271
  ) => {
341
- const matches = Array.from(html.matchAll(contentHeadingRegex));
342
- const bodyStructure = await getBodySections(rawMarkdown);
343
- const headingIdentifierIssues = getHeadingIdentifierIssues(bodyStructure.headings);
272
+ const pageDocument = page.markdownDocument;
273
+ const sourceLabel = page.contentLabel;
274
+ const headingIdentifierIssues = pageDocument.headingIssues;
344
275
  if (headingIdentifierIssues.length > 0) {
345
276
  throw new Error(formatHeadingIdentifierIssue(headingIdentifierIssues[0], sourceLabel));
346
277
  }
347
- const rawSections = getRawMarkdownSections(bodyStructure.sections);
348
278
  const sections: ResolvedSection[] = [];
349
279
  const sectionIds = new Set<string>();
350
280
  let nextNoteNumber = 1;
351
- const pageHeadingCount = matches.filter((match) => match[1] === '1').length;
281
+ const pageHeadingCount = pageDocument.pageHeadings.length;
352
282
 
353
- if (pageHeadingCount !== 1 || matches[0]?.[1] !== '1') {
283
+ if (pageHeadingCount !== 1 || pageDocument.regions[0]?.kind !== 'page-intro') {
354
284
  throw new Error('Each Norna page must start with exactly one Markdown H1 page title, for example "# About".');
355
285
  }
286
+ const renderedRegions = splitRenderedRegions(html, pageDocument.regions.length);
356
287
 
357
- for (let index = 0; index < matches.length; index += 1) {
358
- const match = matches[index];
359
- const bodySection = bodyStructure.sections[index];
360
- const headingLevel = Number.parseInt(match[1] ?? '', 10) as 1 | 2;
361
- const headingHtml = match[3] ?? '';
362
- if (!bodySection || bodySection.level !== headingLevel) {
363
- throw new Error('Markdown H1/H2 headings could not be matched to the rendered page content.');
364
- }
288
+ for (let index = 0; index < renderedRegions.length; index += 1) {
289
+ const bodySection = pageDocument.regions[index];
290
+ if (!bodySection) throw new Error(`Parsed page region ${index + 1} is missing.`);
291
+ const headingLevel = bodySection.heading.depth as 1 | 2;
365
292
  const id = bodySection.id;
366
- const contentStart = (match.index ?? 0) + match[0].length;
367
- const nextMatch = matches[index + 1];
368
- const contentEnd = nextMatch?.index ?? html.length;
369
- const nextBodySection = bodyStructure.sections[index + 1];
370
- const h3Headings = bodyStructure.headings.filter((heading) => (
371
- heading.depth === 3
372
- && heading.index > bodySection.index
373
- && heading.index < (nextBodySection?.index ?? Number.POSITIVE_INFINITY)
374
- ));
375
- const content = applyH3HeadingIds(html.slice(contentStart, contentEnd).trim(), h3Headings);
376
- const title = getHeadingTitle(headingHtml);
293
+ const h3Headings = bodySection.headings.filter((heading) => heading.depth === 3);
294
+ const content = applyH3HeadingIds(renderedRegions[index] ?? '', h3Headings);
295
+ const title = bodySection.title;
377
296
 
378
297
  if (headingLevel === 2 && !id) throw new Error(`Section heading "${title}" cannot produce an automatic ASCII id.`);
379
298
 
@@ -382,15 +301,14 @@ export const getSectionsContent = async (
382
301
  }
383
302
 
384
303
  if (id) sectionIds.add(id);
385
- const rawSection = rawSections.get(id ?? '__page-title') ?? '';
386
- const inlineNoteDiagnostics = extractInlineNoteDiagnostics(rawSection, {
387
- label: 'Markdown section',
388
- });
389
- if (inlineNoteDiagnostics.errors.length > 0) {
390
- throw new Error(inlineNoteDiagnostics.errors[0].message);
304
+ if (bodySection.blockErrors.length > 0) {
305
+ throw new Error(bodySection.blockErrors[0].message);
306
+ }
307
+ if (bodySection.noteErrors.length > 0) {
308
+ throw new Error(bodySection.noteErrors[0].message);
391
309
  }
392
310
 
393
- const inlineNotes = inlineNoteDiagnostics.notes.map((note) => {
311
+ const inlineNotes = bodySection.notes.map((note) => {
394
312
  const number = nextNoteNumber;
395
313
  nextNoteNumber += 1;
396
314
  const pageKey = page.pageId || 'home';
@@ -406,9 +324,9 @@ export const getSectionsContent = async (
406
324
  sections.push({
407
325
  id,
408
326
  title,
409
- titleHtml: getHeadingTitleHtml(headingHtml),
327
+ titleHtml: await renderHeadingTitleHtml(bodySection.heading.source),
410
328
  headingLevel,
411
- contentBlocks: await resolveContentBlocks(content, rawSection, page, inlineNotes),
329
+ contentBlocks: await resolveContentBlocks(content, bodySection.blocks, page, inlineNotes),
412
330
  });
413
331
  }
414
332
 
@@ -1,36 +1,36 @@
1
1
  import type { HeadingNavigation, SectionNavigation } from './sectionContent';
2
- import type { SitePage } from './sitePages';
2
+ import type { SiteNode, SitePage } from './sitePages';
3
3
 
4
- export type PageNavigationEntry = {
5
- page: SitePage;
4
+ export type SiteNavigationEntry = {
5
+ node: SiteNode;
6
6
  headings: HeadingNavigation[];
7
7
  sections: SectionNavigation[];
8
8
  };
9
9
 
10
- export type PageNavigationNode = PageNavigationEntry & {
11
- children: PageNavigationNode[];
10
+ export type SiteNavigationNode = SiteNavigationEntry & {
11
+ children: SiteNavigationNode[];
12
12
  };
13
13
 
14
- export const getPageNavigationTree = (entries: PageNavigationEntry[]) => {
15
- const nodes = new Map<string, PageNavigationNode>();
16
- const roots: PageNavigationNode[] = [];
14
+ export const getSiteNavigationTree = (entries: SiteNavigationEntry[]) => {
15
+ const nodes = new Map<string, SiteNavigationNode>();
16
+ const roots: SiteNavigationNode[] = [];
17
17
 
18
18
  for (const entry of entries) {
19
- nodes.set(entry.page.pagePath, { ...entry, children: [] });
19
+ nodes.set(entry.node.pagePath, { ...entry, children: [] });
20
20
  }
21
21
 
22
22
  for (const entry of entries) {
23
- const node = nodes.get(entry.page.pagePath);
23
+ const node = nodes.get(entry.node.pagePath);
24
24
  if (!node) continue;
25
25
 
26
- if (entry.page.isHome || entry.page.parentPagePath === null) {
26
+ if (entry.node.isHome || entry.node.parentPagePath === null) {
27
27
  roots.push(node);
28
28
  continue;
29
29
  }
30
30
 
31
- const parent = nodes.get(entry.page.parentPagePath);
31
+ const parent = nodes.get(entry.node.parentPagePath);
32
32
  if (!parent) {
33
- throw new Error(`Page "${entry.page.pathname}" has no parent page "${entry.page.parentPagePath}".`);
33
+ throw new Error(`Site node "${entry.node.pagePath}" has no parent node "${entry.node.parentPagePath}".`);
34
34
  }
35
35
 
36
36
  parent.children.push(node);
@@ -39,11 +39,29 @@ export const getPageNavigationTree = (entries: PageNavigationEntry[]) => {
39
39
  return roots;
40
40
  };
41
41
 
42
- export const getListedPageNavigationTree = (entries: PageNavigationEntry[]) => {
43
- const filterListed = (nodes: PageNavigationNode[]): PageNavigationNode[] => nodes.flatMap((node) => {
44
- if (!node.page.isHome && !node.page.navigation.listed) return [];
45
- return [{ ...node, children: filterListed(node.children) }];
42
+ export const getListedSiteNavigationTree = (entries: SiteNavigationEntry[]) => {
43
+ const filterListed = (nodes: SiteNavigationNode[]): SiteNavigationNode[] => nodes.flatMap((node) => {
44
+ if (!node.node.isHome && !node.node.navigation.listed) return [];
45
+ const children = filterListed(node.children);
46
+ if (node.node.kind === 'category' && children.length === 0) return [];
47
+ return [{ ...node, children }];
46
48
  });
47
49
 
48
- return filterListed(getPageNavigationTree(entries));
50
+ return filterListed(getSiteNavigationTree(entries));
49
51
  };
52
+
53
+ export const getFirstPageInNavigationNode = (node: SiteNavigationNode): SitePage | null => {
54
+ if (node.node.kind === 'page') return node.node;
55
+
56
+ for (const child of node.children) {
57
+ const page = getFirstPageInNavigationNode(child);
58
+ if (page) return page;
59
+ }
60
+
61
+ return null;
62
+ };
63
+
64
+ export const flattenSiteNavigationTree = (nodes: SiteNavigationNode[]): SiteNavigationNode[] => nodes.flatMap((node) => [
65
+ node,
66
+ ...flattenSiteNavigationTree(node.children),
67
+ ]);