@janga/norna 0.7.17 → 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 (533) hide show
  1. package/README.md +32 -13
  2. package/astro.config.mjs +22 -0
  3. package/bin/norna-cli.mjs +7 -1
  4. package/package.json +46 -12
  5. package/schemas/category.schema.json +20 -0
  6. package/schemas/config.schema.json +55 -4
  7. package/schemas/content-frontmatter.schema.json +5 -5
  8. package/schemas/manifest.json +4 -2
  9. package/schemas/page-theme.schema.json +192 -0
  10. package/schemas/sitewide-content.schema.json +18 -18
  11. package/schemas/theme.schema.json +364 -226
  12. package/scripts/add-site-node.mjs +251 -0
  13. package/scripts/check-config.mjs +12 -3
  14. package/scripts/deploy-site.mjs +6 -9
  15. package/scripts/generate-images.mjs +18 -29
  16. package/scripts/generate-schemas.mjs +7 -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 -191
  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/page-model.mjs +26 -7
  27. package/scripts/lib/presentation-contract.mjs +266 -0
  28. package/scripts/lib/presentation-palette-metadata.mjs +51 -0
  29. package/scripts/lib/presentation.mjs +548 -93
  30. package/scripts/lib/project-config.mjs +73 -16
  31. package/scripts/lib/schema-definitions.mjs +89 -21
  32. package/scripts/lib/schema-editor-metadata.mjs +166 -33
  33. package/scripts/lib/schema-value-definitions.mjs +32 -4
  34. package/scripts/lib/site-content.mjs +33 -223
  35. package/scripts/lib/site-conventions.mjs +1 -0
  36. package/scripts/lib/site-paths.mjs +11 -6
  37. package/scripts/lib/site-structure.mjs +189 -0
  38. package/scripts/lib/theme-config.mjs +3 -2
  39. package/scripts/lib/theme-presets.mjs +105 -101
  40. package/scripts/lib/theme-profiles.mjs +221 -0
  41. package/scripts/lib/typography.mjs +220 -35
  42. package/scripts/lib/yaml-config.mjs +46 -6
  43. package/scripts/lib/yaml-indentation.mjs +86 -0
  44. package/scripts/show-typography.mjs +3 -36
  45. package/scripts/sync-content-sections.mjs +88 -79
  46. package/src/components/DisplaySettings.astro +107 -0
  47. package/src/components/ImageCarousel.astro +34 -13
  48. package/src/components/NavigationPageTree.astro +154 -34
  49. package/src/components/PageContentsLinks.astro +40 -0
  50. package/src/components/SectionNavigationScript.astro +68 -7
  51. package/src/components/SiteBreadcrumbs.astro +24 -18
  52. package/src/components/SiteNavigation.astro +130 -46
  53. package/src/components/SitePage.astro +65 -55
  54. package/src/components/SiteSection.astro +37 -198
  55. package/src/components/SiteTreeNavigation.astro +36 -0
  56. package/src/components/TreeNavigationScript.astro +83 -0
  57. package/src/content.config.ts +2 -8
  58. package/src/layouts/BaseLayout.astro +52 -2
  59. package/src/lib/generatedImages.ts +0 -7
  60. package/src/lib/pageThemes.ts +11 -9
  61. package/src/lib/readerPreferencesScript.mjs +141 -0
  62. package/src/lib/sectionContent.ts +120 -206
  63. package/src/lib/siteNavigation.ts +38 -19
  64. package/src/lib/sitePages.ts +115 -33
  65. package/src/pages/[...slug].astro +2 -2
  66. package/src/pages/index.astro +2 -1
  67. package/src/styles/global.css +1110 -279
  68. package/starters/basic/README.md +8 -8
  69. package/starters/basic/site/theme.yaml +1 -105
  70. package/docs/README.md +0 -135
  71. package/docs/assets/norna-dog-shelter.jpg +0 -0
  72. package/docs/commands.md +0 -189
  73. package/docs/configuration.md +0 -119
  74. package/docs/content.md +0 -342
  75. package/docs/design/command-organization.md +0 -414
  76. package/docs/design/navigation-and-theme-plan.md +0 -115
  77. package/docs/design/norna-diagram-design.md +0 -159
  78. package/docs/design/site-examples-structure.md +0 -115
  79. package/docs/engine-development.md +0 -218
  80. package/docs/getting-started.md +0 -206
  81. package/docs/how-to/embedded-site.md +0 -35
  82. package/docs/images-and-metadata.md +0 -186
  83. package/docs/local-development.md +0 -82
  84. package/docs/pages.md +0 -134
  85. package/docs/public-files.md +0 -118
  86. package/docs/publishing.md +0 -117
  87. package/docs/requirements.md +0 -54
  88. package/docs/site-files.md +0 -145
  89. package/docs/sitewide-content.md +0 -73
  90. package/docs/theme.md +0 -271
  91. package/docs/typography.md +0 -180
  92. package/examples/README.md +0 -43
  93. package/examples/complete-sites/dog-shelter-multi-page/.astro/collections/site.schema.json +0 -35
  94. package/examples/complete-sites/dog-shelter-multi-page/.astro/collections/sitewide.schema.json +0 -97
  95. package/examples/complete-sites/dog-shelter-multi-page/.astro/collections/theme.schema.json +0 -852
  96. package/examples/complete-sites/dog-shelter-multi-page/.astro/content-assets.mjs +0 -4
  97. package/examples/complete-sites/dog-shelter-multi-page/.astro/content-modules.mjs +0 -1
  98. package/examples/complete-sites/dog-shelter-multi-page/.astro/content.d.ts +0 -183
  99. package/examples/complete-sites/dog-shelter-multi-page/.astro/data-store.json +0 -1
  100. package/examples/complete-sites/dog-shelter-multi-page/.astro/dev-local.json +0 -8
  101. package/examples/complete-sites/dog-shelter-multi-page/.astro/dev.json +0 -13
  102. package/examples/complete-sites/dog-shelter-multi-page/.astro/dev.log +0 -36
  103. package/examples/complete-sites/dog-shelter-multi-page/.astro/settings.json +0 -5
  104. package/examples/complete-sites/dog-shelter-multi-page/.astro/types.d.ts +0 -2
  105. package/examples/complete-sites/dog-shelter-multi-page/README.md +0 -24
  106. package/examples/complete-sites/dog-shelter-multi-page/node_modules/.vite/deps/_metadata.json +0 -74
  107. package/examples/complete-sites/dog-shelter-multi-page/node_modules/.vite/deps/astro-B3JHJyiv.js +0 -434
  108. package/examples/complete-sites/dog-shelter-multi-page/node_modules/.vite/deps/astro-B3JHJyiv.js.map +0 -1
  109. package/examples/complete-sites/dog-shelter-multi-page/node_modules/.vite/deps/astro_n_aria-query.js +0 -6390
  110. package/examples/complete-sites/dog-shelter-multi-page/node_modules/.vite/deps/astro_n_aria-query.js.map +0 -1
  111. package/examples/complete-sites/dog-shelter-multi-page/node_modules/.vite/deps/astro_n_axobject-query.js +0 -2702
  112. package/examples/complete-sites/dog-shelter-multi-page/node_modules/.vite/deps/astro_n_axobject-query.js.map +0 -1
  113. package/examples/complete-sites/dog-shelter-multi-page/node_modules/.vite/deps/astro_n_html-escaper.js +0 -65
  114. package/examples/complete-sites/dog-shelter-multi-page/node_modules/.vite/deps/astro_n_html-escaper.js.map +0 -1
  115. package/examples/complete-sites/dog-shelter-multi-page/node_modules/.vite/deps/astro_runtime_client_dev-toolbar_entrypoint__js.js +0 -455
  116. package/examples/complete-sites/dog-shelter-multi-page/node_modules/.vite/deps/astro_runtime_client_dev-toolbar_entrypoint__js.js.map +0 -1
  117. package/examples/complete-sites/dog-shelter-multi-page/node_modules/.vite/deps/audit-C3SVr7dT.js +0 -1534
  118. package/examples/complete-sites/dog-shelter-multi-page/node_modules/.vite/deps/audit-C3SVr7dT.js.map +0 -1
  119. package/examples/complete-sites/dog-shelter-multi-page/node_modules/.vite/deps/highlight-BLtvqtzO.js +0 -48
  120. package/examples/complete-sites/dog-shelter-multi-page/node_modules/.vite/deps/highlight-BLtvqtzO.js.map +0 -1
  121. package/examples/complete-sites/dog-shelter-multi-page/node_modules/.vite/deps/icons-C92i61-2.js +0 -42
  122. package/examples/complete-sites/dog-shelter-multi-page/node_modules/.vite/deps/icons-C92i61-2.js.map +0 -1
  123. package/examples/complete-sites/dog-shelter-multi-page/node_modules/.vite/deps/package.json +0 -3
  124. package/examples/complete-sites/dog-shelter-multi-page/node_modules/.vite/deps/rolldown-runtime-BvCyGRYZ.js +0 -4
  125. package/examples/complete-sites/dog-shelter-multi-page/node_modules/.vite/deps/settings-v5GgKks_.js +0 -190
  126. package/examples/complete-sites/dog-shelter-multi-page/node_modules/.vite/deps/settings-v5GgKks_.js.map +0 -1
  127. package/examples/complete-sites/dog-shelter-multi-page/node_modules/.vite/deps/toolbar-BFvJVp26.js +0 -458
  128. package/examples/complete-sites/dog-shelter-multi-page/node_modules/.vite/deps/toolbar-BFvJVp26.js.map +0 -1
  129. package/examples/complete-sites/dog-shelter-multi-page/node_modules/.vite/deps/ui-library-Cd35oAvo.js +0 -1016
  130. package/examples/complete-sites/dog-shelter-multi-page/node_modules/.vite/deps/ui-library-Cd35oAvo.js.map +0 -1
  131. package/examples/complete-sites/dog-shelter-multi-page/node_modules/.vite/deps/window-vo3A6TMn.js +0 -32
  132. package/examples/complete-sites/dog-shelter-multi-page/node_modules/.vite/deps/window-vo3A6TMn.js.map +0 -1
  133. package/examples/complete-sites/dog-shelter-multi-page/node_modules/.vite/deps/xray-DwhzGckb.js +0 -111
  134. package/examples/complete-sites/dog-shelter-multi-page/node_modules/.vite/deps/xray-DwhzGckb.js.map +0 -1
  135. package/examples/complete-sites/dog-shelter-multi-page/site/.norna/generated-images.json +0 -98
  136. package/examples/complete-sites/dog-shelter-multi-page/site/config.yaml +0 -1
  137. package/examples/complete-sites/dog-shelter-multi-page/site/content.md +0 -23
  138. package/examples/complete-sites/dog-shelter-multi-page/site/images/shelter-dog.jpg +0 -0
  139. package/examples/complete-sites/dog-shelter-multi-page/site/pages/010-dogs/content.md +0 -21
  140. package/examples/complete-sites/dog-shelter-multi-page/site/pages/010-dogs/images/rex.jpg +0 -0
  141. package/examples/complete-sites/dog-shelter-multi-page/site/pages/010-dogs/images/rover.jpg +0 -0
  142. package/examples/complete-sites/dog-shelter-multi-page/site/pages/020-adopt/content.md +0 -22
  143. package/examples/complete-sites/dog-shelter-multi-page/site/pages/020-adopt/images/adoption-dog.jpg +0 -0
  144. package/examples/complete-sites/dog-shelter-multi-page/site/public/favicon.svg +0 -10
  145. package/examples/complete-sites/dog-shelter-multi-page/site/public/logo.svg +0 -9
  146. package/examples/complete-sites/dog-shelter-multi-page/site/public/robots.txt +0 -2
  147. package/examples/complete-sites/dog-shelter-multi-page/site/sitewide-content.yaml +0 -4
  148. package/examples/complete-sites/dog-shelter-multi-page/site/theme.yaml +0 -1
  149. package/examples/complete-sites/dog-shelter-single-page/.astro/collections/site.schema.json +0 -35
  150. package/examples/complete-sites/dog-shelter-single-page/.astro/collections/sitewide.schema.json +0 -97
  151. package/examples/complete-sites/dog-shelter-single-page/.astro/collections/theme.schema.json +0 -852
  152. package/examples/complete-sites/dog-shelter-single-page/.astro/content-assets.mjs +0 -4
  153. package/examples/complete-sites/dog-shelter-single-page/.astro/content-modules.mjs +0 -1
  154. package/examples/complete-sites/dog-shelter-single-page/.astro/content.d.ts +0 -183
  155. package/examples/complete-sites/dog-shelter-single-page/.astro/data-store.json +0 -1
  156. package/examples/complete-sites/dog-shelter-single-page/.astro/dev-local.json +0 -8
  157. package/examples/complete-sites/dog-shelter-single-page/.astro/dev.json +0 -13
  158. package/examples/complete-sites/dog-shelter-single-page/.astro/dev.log +0 -18
  159. package/examples/complete-sites/dog-shelter-single-page/.astro/settings.json +0 -5
  160. package/examples/complete-sites/dog-shelter-single-page/.astro/types.d.ts +0 -2
  161. package/examples/complete-sites/dog-shelter-single-page/README.md +0 -24
  162. package/examples/complete-sites/dog-shelter-single-page/node_modules/.vite/deps/_metadata.json +0 -74
  163. package/examples/complete-sites/dog-shelter-single-page/node_modules/.vite/deps/astro-B3JHJyiv.js +0 -434
  164. package/examples/complete-sites/dog-shelter-single-page/node_modules/.vite/deps/astro-B3JHJyiv.js.map +0 -1
  165. package/examples/complete-sites/dog-shelter-single-page/node_modules/.vite/deps/astro_n_aria-query.js +0 -6390
  166. package/examples/complete-sites/dog-shelter-single-page/node_modules/.vite/deps/astro_n_aria-query.js.map +0 -1
  167. package/examples/complete-sites/dog-shelter-single-page/node_modules/.vite/deps/astro_n_axobject-query.js +0 -2702
  168. package/examples/complete-sites/dog-shelter-single-page/node_modules/.vite/deps/astro_n_axobject-query.js.map +0 -1
  169. package/examples/complete-sites/dog-shelter-single-page/node_modules/.vite/deps/astro_n_html-escaper.js +0 -65
  170. package/examples/complete-sites/dog-shelter-single-page/node_modules/.vite/deps/astro_n_html-escaper.js.map +0 -1
  171. package/examples/complete-sites/dog-shelter-single-page/node_modules/.vite/deps/astro_runtime_client_dev-toolbar_entrypoint__js.js +0 -455
  172. package/examples/complete-sites/dog-shelter-single-page/node_modules/.vite/deps/astro_runtime_client_dev-toolbar_entrypoint__js.js.map +0 -1
  173. package/examples/complete-sites/dog-shelter-single-page/node_modules/.vite/deps/audit-C3SVr7dT.js +0 -1534
  174. package/examples/complete-sites/dog-shelter-single-page/node_modules/.vite/deps/audit-C3SVr7dT.js.map +0 -1
  175. package/examples/complete-sites/dog-shelter-single-page/node_modules/.vite/deps/highlight-BLtvqtzO.js +0 -48
  176. package/examples/complete-sites/dog-shelter-single-page/node_modules/.vite/deps/highlight-BLtvqtzO.js.map +0 -1
  177. package/examples/complete-sites/dog-shelter-single-page/node_modules/.vite/deps/icons-C92i61-2.js +0 -42
  178. package/examples/complete-sites/dog-shelter-single-page/node_modules/.vite/deps/icons-C92i61-2.js.map +0 -1
  179. package/examples/complete-sites/dog-shelter-single-page/node_modules/.vite/deps/package.json +0 -3
  180. package/examples/complete-sites/dog-shelter-single-page/node_modules/.vite/deps/rolldown-runtime-BvCyGRYZ.js +0 -4
  181. package/examples/complete-sites/dog-shelter-single-page/node_modules/.vite/deps/settings-v5GgKks_.js +0 -190
  182. package/examples/complete-sites/dog-shelter-single-page/node_modules/.vite/deps/settings-v5GgKks_.js.map +0 -1
  183. package/examples/complete-sites/dog-shelter-single-page/node_modules/.vite/deps/toolbar-BFvJVp26.js +0 -458
  184. package/examples/complete-sites/dog-shelter-single-page/node_modules/.vite/deps/toolbar-BFvJVp26.js.map +0 -1
  185. package/examples/complete-sites/dog-shelter-single-page/node_modules/.vite/deps/ui-library-Cd35oAvo.js +0 -1016
  186. package/examples/complete-sites/dog-shelter-single-page/node_modules/.vite/deps/ui-library-Cd35oAvo.js.map +0 -1
  187. package/examples/complete-sites/dog-shelter-single-page/node_modules/.vite/deps/window-vo3A6TMn.js +0 -32
  188. package/examples/complete-sites/dog-shelter-single-page/node_modules/.vite/deps/window-vo3A6TMn.js.map +0 -1
  189. package/examples/complete-sites/dog-shelter-single-page/node_modules/.vite/deps/xray-DwhzGckb.js +0 -111
  190. package/examples/complete-sites/dog-shelter-single-page/node_modules/.vite/deps/xray-DwhzGckb.js.map +0 -1
  191. package/examples/complete-sites/dog-shelter-single-page/site/.norna/generated-images.json +0 -50
  192. package/examples/complete-sites/dog-shelter-single-page/site/config.yaml +0 -1
  193. package/examples/complete-sites/dog-shelter-single-page/site/content.md +0 -37
  194. package/examples/complete-sites/dog-shelter-single-page/site/images/foster-dog.jpg +0 -0
  195. package/examples/complete-sites/dog-shelter-single-page/site/images/rescue-dog.jpg +0 -0
  196. package/examples/complete-sites/dog-shelter-single-page/site/public/favicon.svg +0 -10
  197. package/examples/complete-sites/dog-shelter-single-page/site/public/logo.svg +0 -9
  198. package/examples/complete-sites/dog-shelter-single-page/site/public/robots.txt +0 -2
  199. package/examples/complete-sites/dog-shelter-single-page/site/sitewide-content.yaml +0 -4
  200. package/examples/complete-sites/dog-shelter-single-page/site/theme.yaml +0 -1
  201. package/examples/feature-demos/media-and-surfaces/.astro/collections/site.schema.json +0 -35
  202. package/examples/feature-demos/media-and-surfaces/.astro/collections/sitewide.schema.json +0 -97
  203. package/examples/feature-demos/media-and-surfaces/.astro/collections/theme.schema.json +0 -852
  204. package/examples/feature-demos/media-and-surfaces/.astro/content-assets.mjs +0 -4
  205. package/examples/feature-demos/media-and-surfaces/.astro/content-modules.mjs +0 -1
  206. package/examples/feature-demos/media-and-surfaces/.astro/content.d.ts +0 -183
  207. package/examples/feature-demos/media-and-surfaces/.astro/data-store.json +0 -1
  208. package/examples/feature-demos/media-and-surfaces/.astro/dev.log +0 -14
  209. package/examples/feature-demos/media-and-surfaces/.astro/settings.json +0 -5
  210. package/examples/feature-demos/media-and-surfaces/.astro/types.d.ts +0 -2
  211. package/examples/feature-demos/media-and-surfaces/README.md +0 -21
  212. package/examples/feature-demos/media-and-surfaces/node_modules/.vite/deps/_metadata.json +0 -80
  213. package/examples/feature-demos/media-and-surfaces/node_modules/.vite/deps/astro-B3JHJyiv.js +0 -434
  214. package/examples/feature-demos/media-and-surfaces/node_modules/.vite/deps/astro-B3JHJyiv.js.map +0 -1
  215. package/examples/feature-demos/media-and-surfaces/node_modules/.vite/deps/astro_n_aria-query.js +0 -6390
  216. package/examples/feature-demos/media-and-surfaces/node_modules/.vite/deps/astro_n_aria-query.js.map +0 -1
  217. package/examples/feature-demos/media-and-surfaces/node_modules/.vite/deps/astro_n_axobject-query.js +0 -2702
  218. package/examples/feature-demos/media-and-surfaces/node_modules/.vite/deps/astro_n_axobject-query.js.map +0 -1
  219. package/examples/feature-demos/media-and-surfaces/node_modules/.vite/deps/astro_n_html-escaper.js +0 -65
  220. package/examples/feature-demos/media-and-surfaces/node_modules/.vite/deps/astro_n_html-escaper.js.map +0 -1
  221. package/examples/feature-demos/media-and-surfaces/node_modules/.vite/deps/astro_runtime_client_dev-toolbar_entrypoint__js.js +0 -455
  222. package/examples/feature-demos/media-and-surfaces/node_modules/.vite/deps/astro_runtime_client_dev-toolbar_entrypoint__js.js.map +0 -1
  223. package/examples/feature-demos/media-and-surfaces/node_modules/.vite/deps/audit-C3SVr7dT.js +0 -1534
  224. package/examples/feature-demos/media-and-surfaces/node_modules/.vite/deps/audit-C3SVr7dT.js.map +0 -1
  225. package/examples/feature-demos/media-and-surfaces/node_modules/.vite/deps/embla-carousel.js +0 -1389
  226. package/examples/feature-demos/media-and-surfaces/node_modules/.vite/deps/embla-carousel.js.map +0 -1
  227. package/examples/feature-demos/media-and-surfaces/node_modules/.vite/deps/highlight-BLtvqtzO.js +0 -48
  228. package/examples/feature-demos/media-and-surfaces/node_modules/.vite/deps/highlight-BLtvqtzO.js.map +0 -1
  229. package/examples/feature-demos/media-and-surfaces/node_modules/.vite/deps/icons-C92i61-2.js +0 -42
  230. package/examples/feature-demos/media-and-surfaces/node_modules/.vite/deps/icons-C92i61-2.js.map +0 -1
  231. package/examples/feature-demos/media-and-surfaces/node_modules/.vite/deps/package.json +0 -3
  232. package/examples/feature-demos/media-and-surfaces/node_modules/.vite/deps/rolldown-runtime-BvCyGRYZ.js +0 -4
  233. package/examples/feature-demos/media-and-surfaces/node_modules/.vite/deps/settings-v5GgKks_.js +0 -190
  234. package/examples/feature-demos/media-and-surfaces/node_modules/.vite/deps/settings-v5GgKks_.js.map +0 -1
  235. package/examples/feature-demos/media-and-surfaces/node_modules/.vite/deps/toolbar-BFvJVp26.js +0 -458
  236. package/examples/feature-demos/media-and-surfaces/node_modules/.vite/deps/toolbar-BFvJVp26.js.map +0 -1
  237. package/examples/feature-demos/media-and-surfaces/node_modules/.vite/deps/ui-library-Cd35oAvo.js +0 -1016
  238. package/examples/feature-demos/media-and-surfaces/node_modules/.vite/deps/ui-library-Cd35oAvo.js.map +0 -1
  239. package/examples/feature-demos/media-and-surfaces/node_modules/.vite/deps/window-vo3A6TMn.js +0 -32
  240. package/examples/feature-demos/media-and-surfaces/node_modules/.vite/deps/window-vo3A6TMn.js.map +0 -1
  241. package/examples/feature-demos/media-and-surfaces/node_modules/.vite/deps/xray-DwhzGckb.js +0 -111
  242. package/examples/feature-demos/media-and-surfaces/node_modules/.vite/deps/xray-DwhzGckb.js.map +0 -1
  243. package/examples/feature-demos/media-and-surfaces/site/.norna/generated-images.json +0 -66
  244. package/examples/feature-demos/media-and-surfaces/site/config.yaml +0 -1
  245. package/examples/feature-demos/media-and-surfaces/site/content.md +0 -15
  246. package/examples/feature-demos/media-and-surfaces/site/pages/010-media/content.md +0 -71
  247. package/examples/feature-demos/media-and-surfaces/site/pages/010-media/images/card-carousel.svg +0 -11
  248. package/examples/feature-demos/media-and-surfaces/site/pages/010-media/images/card-stack.svg +0 -9
  249. package/examples/feature-demos/media-and-surfaces/site/pages/010-media/images/card-surfaces.svg +0 -8
  250. package/examples/feature-demos/media-and-surfaces/site/pages/010-media/images/carousel-one.svg +0 -8
  251. package/examples/feature-demos/media-and-surfaces/site/pages/010-media/images/carousel-three.svg +0 -13
  252. package/examples/feature-demos/media-and-surfaces/site/pages/010-media/images/carousel-two.svg +0 -8
  253. package/examples/feature-demos/media-and-surfaces/site/pages/010-media/images/stack-one.svg +0 -8
  254. package/examples/feature-demos/media-and-surfaces/site/pages/010-media/images/stack-two.svg +0 -9
  255. package/examples/feature-demos/media-and-surfaces/site/pages/020-surfaces/content.md +0 -41
  256. package/examples/feature-demos/media-and-surfaces/site/pages/020-surfaces/theme.yaml +0 -3
  257. package/examples/feature-demos/media-and-surfaces/site/public/robots.txt +0 -2
  258. package/examples/feature-demos/media-and-surfaces/site/sitewide-content.yaml +0 -2
  259. package/examples/feature-demos/media-and-surfaces/site/theme.yaml +0 -1
  260. package/examples/feature-demos/sitewide-content/.astro/collections/site.schema.json +0 -59
  261. package/examples/feature-demos/sitewide-content/.astro/collections/sitewide.schema.json +0 -138
  262. package/examples/feature-demos/sitewide-content/.astro/collections/theme.schema.json +0 -755
  263. package/examples/feature-demos/sitewide-content/.astro/content-assets.mjs +0 -1
  264. package/examples/feature-demos/sitewide-content/.astro/content-modules.mjs +0 -1
  265. package/examples/feature-demos/sitewide-content/.astro/content.d.ts +0 -183
  266. package/examples/feature-demos/sitewide-content/.astro/data-store.json +0 -1
  267. package/examples/feature-demos/sitewide-content/.astro/dev.json +0 -13
  268. package/examples/feature-demos/sitewide-content/.astro/dev.log +0 -18
  269. package/examples/feature-demos/sitewide-content/.astro/settings.json +0 -5
  270. package/examples/feature-demos/sitewide-content/.astro/types.d.ts +0 -2
  271. package/examples/feature-demos/sitewide-content/README.md +0 -26
  272. package/examples/feature-demos/sitewide-content/node_modules/.vite/deps/_metadata.json +0 -74
  273. package/examples/feature-demos/sitewide-content/node_modules/.vite/deps/astro-B3JHJyiv.js +0 -434
  274. package/examples/feature-demos/sitewide-content/node_modules/.vite/deps/astro-B3JHJyiv.js.map +0 -1
  275. package/examples/feature-demos/sitewide-content/node_modules/.vite/deps/astro_n_aria-query.js +0 -6390
  276. package/examples/feature-demos/sitewide-content/node_modules/.vite/deps/astro_n_aria-query.js.map +0 -1
  277. package/examples/feature-demos/sitewide-content/node_modules/.vite/deps/astro_n_axobject-query.js +0 -2702
  278. package/examples/feature-demos/sitewide-content/node_modules/.vite/deps/astro_n_axobject-query.js.map +0 -1
  279. package/examples/feature-demos/sitewide-content/node_modules/.vite/deps/astro_n_html-escaper.js +0 -65
  280. package/examples/feature-demos/sitewide-content/node_modules/.vite/deps/astro_n_html-escaper.js.map +0 -1
  281. package/examples/feature-demos/sitewide-content/node_modules/.vite/deps/astro_runtime_client_dev-toolbar_entrypoint__js.js +0 -455
  282. package/examples/feature-demos/sitewide-content/node_modules/.vite/deps/astro_runtime_client_dev-toolbar_entrypoint__js.js.map +0 -1
  283. package/examples/feature-demos/sitewide-content/node_modules/.vite/deps/audit-C3SVr7dT.js +0 -1534
  284. package/examples/feature-demos/sitewide-content/node_modules/.vite/deps/audit-C3SVr7dT.js.map +0 -1
  285. package/examples/feature-demos/sitewide-content/node_modules/.vite/deps/highlight-BLtvqtzO.js +0 -48
  286. package/examples/feature-demos/sitewide-content/node_modules/.vite/deps/highlight-BLtvqtzO.js.map +0 -1
  287. package/examples/feature-demos/sitewide-content/node_modules/.vite/deps/icons-C92i61-2.js +0 -42
  288. package/examples/feature-demos/sitewide-content/node_modules/.vite/deps/icons-C92i61-2.js.map +0 -1
  289. package/examples/feature-demos/sitewide-content/node_modules/.vite/deps/package.json +0 -3
  290. package/examples/feature-demos/sitewide-content/node_modules/.vite/deps/rolldown-runtime-BvCyGRYZ.js +0 -4
  291. package/examples/feature-demos/sitewide-content/node_modules/.vite/deps/settings-v5GgKks_.js +0 -190
  292. package/examples/feature-demos/sitewide-content/node_modules/.vite/deps/settings-v5GgKks_.js.map +0 -1
  293. package/examples/feature-demos/sitewide-content/node_modules/.vite/deps/toolbar-BFvJVp26.js +0 -458
  294. package/examples/feature-demos/sitewide-content/node_modules/.vite/deps/toolbar-BFvJVp26.js.map +0 -1
  295. package/examples/feature-demos/sitewide-content/node_modules/.vite/deps/ui-library-Cd35oAvo.js +0 -1016
  296. package/examples/feature-demos/sitewide-content/node_modules/.vite/deps/ui-library-Cd35oAvo.js.map +0 -1
  297. package/examples/feature-demos/sitewide-content/node_modules/.vite/deps/window-vo3A6TMn.js +0 -32
  298. package/examples/feature-demos/sitewide-content/node_modules/.vite/deps/window-vo3A6TMn.js.map +0 -1
  299. package/examples/feature-demos/sitewide-content/node_modules/.vite/deps/xray-DwhzGckb.js +0 -111
  300. package/examples/feature-demos/sitewide-content/node_modules/.vite/deps/xray-DwhzGckb.js.map +0 -1
  301. package/examples/feature-demos/sitewide-content/site/.norna/generated-images.json +0 -1
  302. package/examples/feature-demos/sitewide-content/site/config.yaml +0 -1
  303. package/examples/feature-demos/sitewide-content/site/content.md +0 -17
  304. package/examples/feature-demos/sitewide-content/site/pages/010-logo-and-navigation/content.md +0 -17
  305. package/examples/feature-demos/sitewide-content/site/pages/020-notices/content.md +0 -23
  306. package/examples/feature-demos/sitewide-content/site/pages/030-footer/content.md +0 -18
  307. package/examples/feature-demos/sitewide-content/site/public/logo.svg +0 -6
  308. package/examples/feature-demos/sitewide-content/site/public/robots.txt +0 -2
  309. package/examples/feature-demos/sitewide-content/site/sitewide-content.yaml +0 -14
  310. package/examples/feature-demos/sitewide-content/site/theme.yaml +0 -1
  311. package/examples/feature-demos/theme-presets/.astro/collections/routeTheme.schema.json +0 -746
  312. package/examples/feature-demos/theme-presets/.astro/collections/site.schema.json +0 -59
  313. package/examples/feature-demos/theme-presets/.astro/collections/sitewide.schema.json +0 -138
  314. package/examples/feature-demos/theme-presets/.astro/collections/theme.schema.json +0 -755
  315. package/examples/feature-demos/theme-presets/.astro/content-assets.mjs +0 -4
  316. package/examples/feature-demos/theme-presets/.astro/content-modules.mjs +0 -1
  317. package/examples/feature-demos/theme-presets/.astro/content.d.ts +0 -183
  318. package/examples/feature-demos/theme-presets/.astro/data-store.json +0 -1
  319. package/examples/feature-demos/theme-presets/.astro/dev-local.json +0 -8
  320. package/examples/feature-demos/theme-presets/.astro/dev.json +0 -15
  321. package/examples/feature-demos/theme-presets/.astro/dev.log +0 -164
  322. package/examples/feature-demos/theme-presets/.astro/settings.json +0 -5
  323. package/examples/feature-demos/theme-presets/.astro/types.d.ts +0 -2
  324. package/examples/feature-demos/theme-presets/README.md +0 -18
  325. package/examples/feature-demos/theme-presets/node_modules/.vite/deps/_metadata.json +0 -80
  326. package/examples/feature-demos/theme-presets/node_modules/.vite/deps/astro-D_GIpJIE.js +0 -434
  327. package/examples/feature-demos/theme-presets/node_modules/.vite/deps/astro-D_GIpJIE.js.map +0 -1
  328. package/examples/feature-demos/theme-presets/node_modules/.vite/deps/astro_n_aria-query.js +0 -6390
  329. package/examples/feature-demos/theme-presets/node_modules/.vite/deps/astro_n_aria-query.js.map +0 -1
  330. package/examples/feature-demos/theme-presets/node_modules/.vite/deps/astro_n_axobject-query.js +0 -2702
  331. package/examples/feature-demos/theme-presets/node_modules/.vite/deps/astro_n_axobject-query.js.map +0 -1
  332. package/examples/feature-demos/theme-presets/node_modules/.vite/deps/astro_n_html-escaper.js +0 -65
  333. package/examples/feature-demos/theme-presets/node_modules/.vite/deps/astro_n_html-escaper.js.map +0 -1
  334. package/examples/feature-demos/theme-presets/node_modules/.vite/deps/astro_runtime_client_dev-toolbar_entrypoint__js.js +0 -455
  335. package/examples/feature-demos/theme-presets/node_modules/.vite/deps/astro_runtime_client_dev-toolbar_entrypoint__js.js.map +0 -1
  336. package/examples/feature-demos/theme-presets/node_modules/.vite/deps/audit-DM9Hkl5B.js +0 -1534
  337. package/examples/feature-demos/theme-presets/node_modules/.vite/deps/audit-DM9Hkl5B.js.map +0 -1
  338. package/examples/feature-demos/theme-presets/node_modules/.vite/deps/embla-carousel.js +0 -1389
  339. package/examples/feature-demos/theme-presets/node_modules/.vite/deps/embla-carousel.js.map +0 -1
  340. package/examples/feature-demos/theme-presets/node_modules/.vite/deps/highlight-DnZ1ULOL.js +0 -48
  341. package/examples/feature-demos/theme-presets/node_modules/.vite/deps/highlight-DnZ1ULOL.js.map +0 -1
  342. package/examples/feature-demos/theme-presets/node_modules/.vite/deps/icons-RyebKi45.js +0 -42
  343. package/examples/feature-demos/theme-presets/node_modules/.vite/deps/icons-RyebKi45.js.map +0 -1
  344. package/examples/feature-demos/theme-presets/node_modules/.vite/deps/package.json +0 -3
  345. package/examples/feature-demos/theme-presets/node_modules/.vite/deps/rolldown-runtime-BvCyGRYZ.js +0 -4
  346. package/examples/feature-demos/theme-presets/node_modules/.vite/deps/settings-DaU-gNnK.js +0 -190
  347. package/examples/feature-demos/theme-presets/node_modules/.vite/deps/settings-DaU-gNnK.js.map +0 -1
  348. package/examples/feature-demos/theme-presets/node_modules/.vite/deps/toolbar-63PA619H.js +0 -458
  349. package/examples/feature-demos/theme-presets/node_modules/.vite/deps/toolbar-63PA619H.js.map +0 -1
  350. package/examples/feature-demos/theme-presets/node_modules/.vite/deps/ui-library--bkcNSYz.js +0 -1016
  351. package/examples/feature-demos/theme-presets/node_modules/.vite/deps/ui-library--bkcNSYz.js.map +0 -1
  352. package/examples/feature-demos/theme-presets/node_modules/.vite/deps/window-jPkpKVcy.js +0 -32
  353. package/examples/feature-demos/theme-presets/node_modules/.vite/deps/window-jPkpKVcy.js.map +0 -1
  354. package/examples/feature-demos/theme-presets/node_modules/.vite/deps/xray-BXCHpEJP.js +0 -111
  355. package/examples/feature-demos/theme-presets/node_modules/.vite/deps/xray-BXCHpEJP.js.map +0 -1
  356. package/examples/feature-demos/theme-presets/site/.norna/generated-images.json +0 -290
  357. package/examples/feature-demos/theme-presets/site/config.yaml +0 -1
  358. package/examples/feature-demos/theme-presets/site/content.md +0 -14
  359. package/examples/feature-demos/theme-presets/site/pages/010-portfolio/content.md +0 -31
  360. package/examples/feature-demos/theme-presets/site/pages/010-portfolio/images/puppy-portrait.jpg +0 -0
  361. package/examples/feature-demos/theme-presets/site/pages/010-portfolio/images/shepherd-portrait.jpg +0 -0
  362. package/examples/feature-demos/theme-presets/site/pages/010-portfolio/images/white-puppy.jpg +0 -0
  363. package/examples/feature-demos/theme-presets/site/pages/010-portfolio/theme.yaml +0 -1
  364. package/examples/feature-demos/theme-presets/site/pages/020-documentation/content.md +0 -30
  365. package/examples/feature-demos/theme-presets/site/pages/020-documentation/images/black-schnauzer.jpg +0 -0
  366. package/examples/feature-demos/theme-presets/site/pages/020-documentation/images/retriever-portrait.jpg +0 -0
  367. package/examples/feature-demos/theme-presets/site/pages/020-documentation/images/schnauzer-portrait.jpg +0 -0
  368. package/examples/feature-demos/theme-presets/site/pages/020-documentation/theme.yaml +0 -1
  369. package/examples/feature-demos/theme-presets/site/pages/030-project/content.md +0 -31
  370. package/examples/feature-demos/theme-presets/site/pages/030-project/images/boxer-portrait.jpg +0 -0
  371. package/examples/feature-demos/theme-presets/site/pages/030-project/images/grass-puppy.jpg +0 -0
  372. package/examples/feature-demos/theme-presets/site/pages/030-project/images/grey-street-dog.jpg +0 -0
  373. package/examples/feature-demos/theme-presets/site/pages/030-project/theme.yaml +0 -1
  374. package/examples/feature-demos/theme-presets/site/pages/040-statement/content.md +0 -31
  375. package/examples/feature-demos/theme-presets/site/pages/040-statement/images/black-pedigree.jpg +0 -0
  376. package/examples/feature-demos/theme-presets/site/pages/040-statement/images/sheepdog-grass.jpg +0 -0
  377. package/examples/feature-demos/theme-presets/site/pages/040-statement/images/sheepdog-wide.jpg +0 -0
  378. package/examples/feature-demos/theme-presets/site/pages/040-statement/theme.yaml +0 -1
  379. package/examples/feature-demos/theme-presets/site/public/robots.txt +0 -2
  380. package/examples/feature-demos/theme-presets/site/sitewide-content.yaml +0 -3
  381. package/examples/feature-demos/theme-presets/site/theme.yaml +0 -1
  382. package/fixtures/basic/site/.norna/generated-images.json +0 -1
  383. package/fixtures/basic/site/config.yaml +0 -1
  384. package/fixtures/basic/site/content.md +0 -14
  385. package/fixtures/basic/site/public/robots.txt +0 -2
  386. package/fixtures/basic/site/sitewide-content.yaml +0 -3
  387. package/fixtures/basic/site/theme.yaml +0 -8
  388. package/fixtures/content-model-v2/.astro/collections/site.schema.json +0 -776
  389. package/fixtures/content-model-v2/.astro/collections/theme.schema.json +0 -668
  390. package/fixtures/content-model-v2/.astro/content-assets.mjs +0 -4
  391. package/fixtures/content-model-v2/.astro/content-modules.mjs +0 -1
  392. package/fixtures/content-model-v2/.astro/content.d.ts +0 -175
  393. package/fixtures/content-model-v2/.astro/data-store.json +0 -1
  394. package/fixtures/content-model-v2/.astro/dev-local.json +0 -8
  395. package/fixtures/content-model-v2/.astro/dev.json +0 -13
  396. package/fixtures/content-model-v2/.astro/dev.log +0 -231
  397. package/fixtures/content-model-v2/.astro/settings.json +0 -5
  398. package/fixtures/content-model-v2/.astro/types.d.ts +0 -2
  399. package/fixtures/content-model-v2/dist/_astro/GalleryGrid.astro_astro_type_script_index_0_lang.B0kxDyGz.js +0 -1
  400. package/fixtures/content-model-v2/dist/_astro/SitePage.BbfZub4g.css +0 -1
  401. package/fixtures/content-model-v2/dist/guide/index.html +0 -3
  402. package/fixtures/content-model-v2/dist/images/generated/intro/detail-27930b14-480.webp +0 -0
  403. package/fixtures/content-model-v2/dist/images/generated/intro/detail-27930b14-768.webp +0 -0
  404. package/fixtures/content-model-v2/dist/images/generated/intro/detail-27930b14-971.webp +0 -0
  405. package/fixtures/content-model-v2/dist/images/generated/intro/duplicate-49c98f6c-480.webp +0 -0
  406. package/fixtures/content-model-v2/dist/images/generated/intro/duplicate-49c98f6c-768.webp +0 -0
  407. package/fixtures/content-model-v2/dist/images/generated/intro/duplicate-49c98f6c-971.webp +0 -0
  408. package/fixtures/content-model-v2/dist/images/generated/intro/hero-6d588a83-480.webp +0 -0
  409. package/fixtures/content-model-v2/dist/images/generated/intro/hero-6d588a83-768.webp +0 -0
  410. package/fixtures/content-model-v2/dist/images/generated/intro/hero-6d588a83-971.webp +0 -0
  411. package/fixtures/content-model-v2/dist/images/generated/plain/image-3770d763-1080.webp +0 -0
  412. package/fixtures/content-model-v2/dist/images/generated/plain/image-3770d763-1440.webp +0 -0
  413. package/fixtures/content-model-v2/dist/images/generated/plain/image-3770d763-1600.webp +0 -0
  414. package/fixtures/content-model-v2/dist/images/generated/plain/image-3770d763-480.webp +0 -0
  415. package/fixtures/content-model-v2/dist/images/generated/plain/image-3770d763-768.webp +0 -0
  416. package/fixtures/content-model-v2/dist/images/generated/routes/010-guide/images/intro/duplicate-5cf614d2-480.webp +0 -0
  417. package/fixtures/content-model-v2/dist/images/generated/routes/010-guide/images/intro/duplicate-5cf614d2-768.webp +0 -0
  418. package/fixtures/content-model-v2/dist/images/generated/routes/010-guide/images/intro/duplicate-5cf614d2-960.webp +0 -0
  419. package/fixtures/content-model-v2/dist/images/generated/timed/slide-one-3770d763-1080.webp +0 -0
  420. package/fixtures/content-model-v2/dist/images/generated/timed/slide-one-3770d763-1440.webp +0 -0
  421. package/fixtures/content-model-v2/dist/images/generated/timed/slide-one-3770d763-1600.webp +0 -0
  422. package/fixtures/content-model-v2/dist/images/generated/timed/slide-one-3770d763-480.webp +0 -0
  423. package/fixtures/content-model-v2/dist/images/generated/timed/slide-one-3770d763-768.webp +0 -0
  424. package/fixtures/content-model-v2/dist/images/generated/timed/slide-three-5bdec65e-1080.webp +0 -0
  425. package/fixtures/content-model-v2/dist/images/generated/timed/slide-three-5bdec65e-1440.webp +0 -0
  426. package/fixtures/content-model-v2/dist/images/generated/timed/slide-three-5bdec65e-1600.webp +0 -0
  427. package/fixtures/content-model-v2/dist/images/generated/timed/slide-three-5bdec65e-480.webp +0 -0
  428. package/fixtures/content-model-v2/dist/images/generated/timed/slide-three-5bdec65e-768.webp +0 -0
  429. package/fixtures/content-model-v2/dist/images/generated/timed/slide-two-26c08aee-1080.webp +0 -0
  430. package/fixtures/content-model-v2/dist/images/generated/timed/slide-two-26c08aee-1440.webp +0 -0
  431. package/fixtures/content-model-v2/dist/images/generated/timed/slide-two-26c08aee-1600.webp +0 -0
  432. package/fixtures/content-model-v2/dist/images/generated/timed/slide-two-26c08aee-480.webp +0 -0
  433. package/fixtures/content-model-v2/dist/images/generated/timed/slide-two-26c08aee-768.webp +0 -0
  434. package/fixtures/content-model-v2/dist/index.html +0 -8
  435. package/fixtures/content-model-v2/node_modules/.vite/deps/_metadata.json +0 -80
  436. package/fixtures/content-model-v2/node_modules/.vite/deps/astro-D_GIpJIE.js +0 -434
  437. package/fixtures/content-model-v2/node_modules/.vite/deps/astro-D_GIpJIE.js.map +0 -1
  438. package/fixtures/content-model-v2/node_modules/.vite/deps/astro_n_aria-query.js +0 -6390
  439. package/fixtures/content-model-v2/node_modules/.vite/deps/astro_n_aria-query.js.map +0 -1
  440. package/fixtures/content-model-v2/node_modules/.vite/deps/astro_n_axobject-query.js +0 -2702
  441. package/fixtures/content-model-v2/node_modules/.vite/deps/astro_n_axobject-query.js.map +0 -1
  442. package/fixtures/content-model-v2/node_modules/.vite/deps/astro_n_html-escaper.js +0 -65
  443. package/fixtures/content-model-v2/node_modules/.vite/deps/astro_n_html-escaper.js.map +0 -1
  444. package/fixtures/content-model-v2/node_modules/.vite/deps/astro_runtime_client_dev-toolbar_entrypoint__js.js +0 -455
  445. package/fixtures/content-model-v2/node_modules/.vite/deps/astro_runtime_client_dev-toolbar_entrypoint__js.js.map +0 -1
  446. package/fixtures/content-model-v2/node_modules/.vite/deps/audit-DM9Hkl5B.js +0 -1534
  447. package/fixtures/content-model-v2/node_modules/.vite/deps/audit-DM9Hkl5B.js.map +0 -1
  448. package/fixtures/content-model-v2/node_modules/.vite/deps/embla-carousel.js +0 -1389
  449. package/fixtures/content-model-v2/node_modules/.vite/deps/embla-carousel.js.map +0 -1
  450. package/fixtures/content-model-v2/node_modules/.vite/deps/highlight-DnZ1ULOL.js +0 -48
  451. package/fixtures/content-model-v2/node_modules/.vite/deps/highlight-DnZ1ULOL.js.map +0 -1
  452. package/fixtures/content-model-v2/node_modules/.vite/deps/icons-RyebKi45.js +0 -42
  453. package/fixtures/content-model-v2/node_modules/.vite/deps/icons-RyebKi45.js.map +0 -1
  454. package/fixtures/content-model-v2/node_modules/.vite/deps/package.json +0 -3
  455. package/fixtures/content-model-v2/node_modules/.vite/deps/rolldown-runtime-BvCyGRYZ.js +0 -4
  456. package/fixtures/content-model-v2/node_modules/.vite/deps/settings-DaU-gNnK.js +0 -190
  457. package/fixtures/content-model-v2/node_modules/.vite/deps/settings-DaU-gNnK.js.map +0 -1
  458. package/fixtures/content-model-v2/node_modules/.vite/deps/toolbar-63PA619H.js +0 -458
  459. package/fixtures/content-model-v2/node_modules/.vite/deps/toolbar-63PA619H.js.map +0 -1
  460. package/fixtures/content-model-v2/node_modules/.vite/deps/ui-library--bkcNSYz.js +0 -1016
  461. package/fixtures/content-model-v2/node_modules/.vite/deps/ui-library--bkcNSYz.js.map +0 -1
  462. package/fixtures/content-model-v2/node_modules/.vite/deps/window-jPkpKVcy.js +0 -32
  463. package/fixtures/content-model-v2/node_modules/.vite/deps/window-jPkpKVcy.js.map +0 -1
  464. package/fixtures/content-model-v2/node_modules/.vite/deps/xray-BXCHpEJP.js +0 -111
  465. package/fixtures/content-model-v2/node_modules/.vite/deps/xray-BXCHpEJP.js.map +0 -1
  466. package/fixtures/content-model-v2/site/.norna/generated-images.json +0 -210
  467. package/fixtures/content-model-v2/site/config.yaml +0 -1
  468. package/fixtures/content-model-v2/site/content.md +0 -79
  469. package/fixtures/content-model-v2/site/images/adopt.svg +0 -9
  470. package/fixtures/content-model-v2/site/images/detail.jpg +0 -0
  471. package/fixtures/content-model-v2/site/images/duplicate.jpg +0 -0
  472. package/fixtures/content-model-v2/site/images/foster.svg +0 -12
  473. package/fixtures/content-model-v2/site/images/hero.jpg +0 -0
  474. package/fixtures/content-model-v2/site/images/image.jpg +0 -0
  475. package/fixtures/content-model-v2/site/images/slide-one.jpg +0 -0
  476. package/fixtures/content-model-v2/site/images/slide-three.jpg +0 -0
  477. package/fixtures/content-model-v2/site/images/slide-two.jpg +0 -0
  478. package/fixtures/content-model-v2/site/pages/010-guide/content.md +0 -18
  479. package/fixtures/content-model-v2/site/pages/010-guide/images/duplicate.jpg +0 -0
  480. package/fixtures/content-model-v2/site/theme.yaml +0 -4
  481. package/fixtures/nested-pages/site/.norna/generated-images.json +0 -10
  482. package/fixtures/nested-pages/site/config.yaml +0 -1
  483. package/fixtures/nested-pages/site/content.md +0 -15
  484. package/fixtures/nested-pages/site/pages/010-guides/content.md +0 -15
  485. package/fixtures/nested-pages/site/pages/010-guides/pages/010-installation/content.md +0 -21
  486. package/fixtures/nested-pages/site/pages/010-guides/pages/010-installation/images/diagram.svg +0 -21
  487. package/fixtures/nested-pages/site/pages/010-guides/pages/010-installation/pages/010-macos/content.md +0 -14
  488. package/fixtures/nested-pages/site/pages/010-guides/pages/020-workflows/content.md +0 -11
  489. package/fixtures/nested-pages/site/pages/010-guides/theme.yaml +0 -3
  490. package/fixtures/nested-pages/site/pages/020-reference/content.md +0 -10
  491. package/fixtures/nested-pages/site/pages/020-reference/pages/010-installation/content.md +0 -11
  492. package/fixtures/nested-pages/site/theme.yaml +0 -3
  493. package/scripts/build-pages.mjs +0 -69
  494. package/scripts/lib/example-sites.mjs +0 -37
  495. package/scripts/lib/frontmatter-yaml.mjs +0 -113
  496. package/scripts/lib/git-status.mjs +0 -7
  497. package/scripts/release.mjs +0 -153
  498. package/scripts/test-banner-visibility.mjs +0 -80
  499. package/scripts/test-ci-lockfile.mjs +0 -65
  500. package/scripts/test-cli-discovery.mjs +0 -124
  501. package/scripts/test-client-javascript.mjs +0 -218
  502. package/scripts/test-content-check.mjs +0 -621
  503. package/scripts/test-content-model-v2.mjs +0 -1629
  504. package/scripts/test-documentation.mjs +0 -187
  505. package/scripts/test-editor-language-service.mjs +0 -302
  506. package/scripts/test-engine-commands.mjs +0 -204
  507. package/scripts/test-examples.mjs +0 -24
  508. package/scripts/test-heading-ids.mjs +0 -68
  509. package/scripts/test-navigation-model.mjs +0 -63
  510. package/scripts/test-navigation-preview.mjs +0 -108
  511. package/scripts/test-navigation.mjs +0 -148
  512. package/scripts/test-nested-pages.mjs +0 -110
  513. package/scripts/test-package-check.mjs +0 -531
  514. package/scripts/test-page-model.mjs +0 -80
  515. package/scripts/test-project-config.mjs +0 -144
  516. package/scripts/test-schemas.mjs +0 -154
  517. package/scripts/test-site-public.mjs +0 -85
  518. package/scripts/test-theme-presets.mjs +0 -182
  519. package/src/components/SiteNotesScript.astro +0 -43
  520. package/starters/basic/site/images/.gitkeep +0 -1
  521. package/starters/project/.github/workflows/deploy.yml +0 -64
  522. package/starters/project/README.md +0 -84
  523. package/starters/project/package-lock.json +0 -4296
  524. package/starters/project/package.json +0 -37
  525. package/starters/project/site/config.yaml +0 -1
  526. package/starters/project/site/content.md +0 -119
  527. package/starters/project/site/pages/010-guide/content.md +0 -80
  528. package/starters/project/site/public/robots.txt +0 -2
  529. package/starters/project/site/sitewide-content.yaml +0 -3
  530. package/starters/project/site/theme.yaml +0 -31
  531. package/tsconfig.json +0 -5
  532. /package/starters/basic/site/{content.md → pages/000-home/content.md} +0 -0
  533. /package/{fixtures/basic/site → starters/basic/site/pages/000-home}/images/.gitkeep +0 -0
@@ -0,0 +1 @@
1
+ export const homePageDirectory = '000-home';
@@ -1,10 +1,12 @@
1
1
  import { existsSync } from 'node:fs';
2
2
  import path from 'node:path';
3
3
  import { fileURLToPath } from 'node:url';
4
+ import { homePageDirectory } from './site-conventions.mjs';
4
5
 
5
6
  const siteDirectoryEnvName = 'NORNA_SITE_DIR';
6
7
  const invocationRootEnvName = 'NORNA_INVOCATION_ROOT';
7
8
  const defaultSiteDirectory = 'site';
9
+ export { homePageDirectory };
8
10
 
9
11
  const currentFile = fileURLToPath(import.meta.url);
10
12
  const currentDirectory = path.dirname(currentFile);
@@ -23,7 +25,10 @@ export const invocationRoot = configuredInvocationRoot
23
25
  const hasSiteFilesInDirectory = (siteDir) => {
24
26
  return (
25
27
  existsSync(path.join(siteDir, 'config.yaml'))
26
- && existsSync(path.join(siteDir, 'content.md'))
28
+ && (
29
+ existsSync(path.join(siteDir, 'pages', homePageDirectory, 'content.md'))
30
+ || existsSync(path.join(siteDir, 'content.md'))
31
+ )
27
32
  );
28
33
  };
29
34
 
@@ -95,7 +100,6 @@ const resolveSitePaths = () => {
95
100
  const resolvedSitePaths = resolveSitePaths();
96
101
 
97
102
  export const siteProjectRoot = resolvedSitePaths.siteProjectRoot;
98
- export const root = siteProjectRoot;
99
103
  export const siteDirectory = resolvedSitePaths.siteDirectory;
100
104
 
101
105
  if (!siteDirectory) {
@@ -116,21 +120,22 @@ const getPathLabel = (filePath) => {
116
120
  export const siteDir = resolvedSitePaths.siteDir;
117
121
  export const siteConfigPath = path.join(siteDir, 'config.yaml');
118
122
  export const siteThemePath = path.join(siteDir, 'theme.yaml');
119
- export const siteContentPath = path.join(siteDir, 'content.md');
120
123
  export const sitewideContentPath = path.join(siteDir, 'sitewide-content.yaml');
121
- export const siteImagesDir = path.join(siteDir, 'images');
122
124
  export const sitePagesDir = path.join(siteDir, 'pages');
125
+ export const siteHomePageDir = path.join(sitePagesDir, homePageDirectory);
126
+ export const siteContentPath = path.join(siteHomePageDir, 'content.md');
127
+ export const siteImagesDir = path.join(siteHomePageDir, 'images');
123
128
  export const sitePublicDir = path.join(siteDir, 'public');
124
129
  export const siteStateDir = path.join(siteDir, '.norna');
125
130
  export const astroPublicDir = path.join(siteStateDir, 'public');
126
131
  export const astroDistDir = path.join(siteProjectRoot, 'dist');
127
- export const astroCacheDir = path.join(siteProjectRoot, '.astro');
132
+ export const astroRootDir = siteStateDir;
133
+ export const astroCacheDir = path.join(astroRootDir, '.astro');
128
134
  export const generatedImagesDir = path.join(astroPublicDir, 'images', 'generated');
129
135
  export const originalImagesDir = path.join(astroPublicDir, 'images', 'original');
130
136
  export const generatedImagesManifestPath = path.join(siteStateDir, 'generated-images.json');
131
137
 
132
138
  export const engineRootLabel = getPathLabel(engineRoot);
133
- export const invocationRootLabel = getPathLabel(invocationRoot);
134
139
  export const siteProjectRootLabel = getPathLabel(siteProjectRoot);
135
140
  export const siteDirLabel = getPathLabel(siteDir);
136
141
  export const siteConfigLabel = getPathLabel(siteConfigPath);
@@ -0,0 +1,189 @@
1
+ import { access, readdir, readFile } from 'node:fs/promises';
2
+ import path from 'node:path';
3
+ import { categorySchema } from './schema-definitions.mjs';
4
+ import { parsePageDirectoryPath } from './page-model.mjs';
5
+ import {
6
+ homePageDirectory,
7
+ siteContentLabel,
8
+ siteDir,
9
+ siteDirLabel,
10
+ sitePagesDir,
11
+ sitePagesLabel,
12
+ } from './site-paths.mjs';
13
+ import { parseYamlConfig } from './yaml-config.mjs';
14
+
15
+ const fileExists = async (filePath) => access(filePath).then(() => true, () => false);
16
+
17
+ const readDirectory = async (directory) => readdir(directory, { withFileTypes: true }).catch((error) => {
18
+ if (error?.code === 'ENOENT') return [];
19
+ throw error;
20
+ });
21
+
22
+ const compareNodeMetadata = (left, right) => (
23
+ left.pageOrder - right.pageOrder
24
+ || left.pageId.localeCompare(right.pageId, 'en')
25
+ );
26
+
27
+ const assertLegacyStructureIsAbsent = async () => {
28
+ const legacyContentPath = path.join(siteDir, 'content.md');
29
+ const legacyImagesPath = path.join(siteDir, 'images');
30
+ const legacyPaths = [];
31
+ if (await fileExists(legacyContentPath)) legacyPaths.push(`${siteDirLabel}/content.md`);
32
+ if (await fileExists(legacyImagesPath)) legacyPaths.push(`${siteDirLabel}/images`);
33
+ if (legacyPaths.length > 0) {
34
+ throw new Error([
35
+ `The old root-page structure is no longer supported: ${legacyPaths.join(', ')}.`,
36
+ `Move the homepage content to ${sitePagesLabel}/${homePageDirectory}/content.md and its images to ${sitePagesLabel}/${homePageDirectory}/images/.`,
37
+ ].join('\n'));
38
+ }
39
+
40
+ if (await fileExists(path.join(siteDir, 'routes'))) {
41
+ throw new Error(`${siteDirLabel}/routes is no longer supported. Rename it to ${sitePagesLabel} and use NNN-page-id directory names.`);
42
+ }
43
+ };
44
+
45
+ const assertUniqueSiblings = (nodes, pagesLabel) => {
46
+ const byId = new Map();
47
+ const byOrder = new Map();
48
+
49
+ for (const node of nodes) {
50
+ const existingId = byId.get(node.pageId);
51
+ if (existingId) {
52
+ throw new Error([
53
+ `${pagesLabel} contains duplicate sibling id "${node.pageId}".`,
54
+ `- ${existingId.nodeLabel}`,
55
+ `- ${node.nodeLabel}`,
56
+ ].join('\n'));
57
+ }
58
+ byId.set(node.pageId, node);
59
+
60
+ const existingOrder = byOrder.get(node.pageOrder);
61
+ if (existingOrder) {
62
+ throw new Error([
63
+ `${pagesLabel} contains duplicate sibling order "${String(node.pageOrder).padStart(3, '0')}".`,
64
+ `- ${existingOrder.nodeLabel}`,
65
+ `- ${node.nodeLabel}`,
66
+ ].join('\n'));
67
+ }
68
+ byOrder.set(node.pageOrder, node);
69
+ }
70
+ };
71
+
72
+ const readCategory = async (categoryPath, categorySourceLabel) => {
73
+ const source = await readFile(categoryPath, 'utf8');
74
+ return parseYamlConfig(source, categorySourceLabel, { schema: categorySchema });
75
+ };
76
+
77
+ export const getSiteStructure = async () => {
78
+ await assertLegacyStructureIsAbsent();
79
+
80
+ const nodes = [];
81
+ const warnings = [];
82
+
83
+ const collectNodes = async (pagesDir, pagesLabel, parentNodeDirectory = '') => {
84
+ const entries = (await readDirectory(pagesDir))
85
+ .filter((entry) => entry.isDirectory())
86
+ .sort((left, right) => left.name.localeCompare(right.name, 'en'));
87
+ const siblingNodes = [];
88
+
89
+ for (const entry of entries) {
90
+ const pageDirectory = parentNodeDirectory
91
+ ? `${parentNodeDirectory}/pages/${entry.name}`
92
+ : entry.name;
93
+ const nodeLabel = `${pagesLabel}/${entry.name}`;
94
+ const nodeDir = path.join(pagesDir, entry.name);
95
+ const contentPath = path.join(nodeDir, 'content.md');
96
+ const categoryPath = path.join(nodeDir, 'category.yaml');
97
+ const [hasContent, hasCategory] = await Promise.all([
98
+ fileExists(contentPath),
99
+ fileExists(categoryPath),
100
+ ]);
101
+ const metadata = parsePageDirectoryPath(pageDirectory, nodeLabel);
102
+
103
+ if (hasContent === hasCategory) {
104
+ const problem = hasContent
105
+ ? 'contains both content.md and category.yaml'
106
+ : 'contains neither content.md nor category.yaml';
107
+ throw new Error(`${nodeLabel} ${problem}. Keep exactly one: content.md for a page, or category.yaml for a navigation category.`);
108
+ }
109
+
110
+ const isHome = pageDirectory === homePageDirectory;
111
+ if (isHome && hasCategory) {
112
+ throw new Error(`${nodeLabel}/category.yaml is invalid. The homepage must be a page with content.md.`);
113
+ }
114
+
115
+ const node = {
116
+ ...metadata,
117
+ isHome,
118
+ kind: hasCategory ? 'category' : 'page',
119
+ nodeDir,
120
+ nodeLabel,
121
+ pagePath: isHome ? '' : metadata.pagePath,
122
+ parentPagePath: isHome ? null : metadata.parentPagePath,
123
+ };
124
+
125
+ if (hasCategory) {
126
+ if (await fileExists(path.join(nodeDir, 'images'))) {
127
+ throw new Error(`${nodeLabel} is a navigation category and cannot contain images/. Use content.md when the collection needs editorial content or images.`);
128
+ }
129
+ const category = await readCategory(categoryPath, `${nodeLabel}/category.yaml`);
130
+ Object.assign(node, {
131
+ categorySourceLabel: `${nodeLabel}/category.yaml`,
132
+ categoryPath,
133
+ label: category.label,
134
+ });
135
+ } else {
136
+ Object.assign(node, {
137
+ contentLabel: `${nodeLabel}/content.md`,
138
+ contentPath,
139
+ imagesDir: path.join(nodeDir, 'images'),
140
+ imagesLabel: `${nodeLabel}/images`,
141
+ });
142
+ }
143
+
144
+ siblingNodes.push(node);
145
+ }
146
+
147
+ assertUniqueSiblings(siblingNodes, pagesLabel);
148
+
149
+ for (const node of siblingNodes.sort(compareNodeMetadata)) {
150
+ nodes.push(node);
151
+ const childPagesDir = path.join(node.nodeDir, 'pages');
152
+ const childDirectories = (await readDirectory(childPagesDir)).filter((entry) => entry.isDirectory());
153
+
154
+ if (node.isHome && childDirectories.length > 0) {
155
+ throw new Error([
156
+ `${node.nodeLabel} is the homepage and cannot contain child pages.`,
157
+ `Move these page directories beside ${homePageDirectory} under ${sitePagesLabel}/, or below another non-home page:`,
158
+ ...childDirectories.map(({ name }) => `- ${node.nodeLabel}/pages/${name}`),
159
+ ].join('\n'));
160
+ }
161
+
162
+ if (node.kind === 'category' && childDirectories.length === 0) {
163
+ warnings.push({
164
+ code: 'empty-category',
165
+ label: node.categorySourceLabel,
166
+ message: `${node.categorySourceLabel} defines an empty navigation category. Add at least one child page under ${node.nodeLabel}/pages/.`,
167
+ });
168
+ }
169
+
170
+ if (!node.isHome && childDirectories.length > 0) {
171
+ await collectNodes(childPagesDir, `${node.nodeLabel}/pages`, node.pageDirectory);
172
+ }
173
+ }
174
+ };
175
+
176
+ await collectNodes(sitePagesDir, sitePagesLabel);
177
+ if (!nodes.some(({ isHome }) => isHome)) {
178
+ throw new Error(`Homepage content is missing. Create ${siteContentLabel}.`);
179
+ }
180
+
181
+ return {
182
+ categories: nodes.filter(({ kind }) => kind === 'category'),
183
+ contentFiles: nodes.filter(({ kind }) => kind === 'page'),
184
+ nodes,
185
+ warnings,
186
+ };
187
+ };
188
+
189
+ export const getContentFiles = async () => (await getSiteStructure()).contentFiles;
@@ -12,6 +12,7 @@ import {
12
12
  } from './site-paths.mjs';
13
13
  import { resolveThemePresentation } from './presentation.mjs';
14
14
  import { resolveThemeConfig } from './theme-presets.mjs';
15
+ import { pageThemeSchema, themeVisualSchema } from './schema-definitions.mjs';
15
16
  import { parseYamlConfig } from './yaml-config.mjs';
16
17
 
17
18
  export const readThemeConfig = async () => {
@@ -23,6 +24,7 @@ export const readThemeConfig = async () => {
23
24
  throw error;
24
25
  });
25
26
  const config = parseYamlConfig(themeFile, siteThemeLabel, {
27
+ schema: themeVisualSchema,
26
28
  validateStructure: validateThemeYamlStructure,
27
29
  });
28
30
  resolveThemeConfig(config, siteThemeLabel);
@@ -64,10 +66,9 @@ export const validatePageThemeFiles = async () => {
64
66
  for (const file of files) {
65
67
  const source = await readFile(file.path, 'utf8');
66
68
  const config = parseYamlConfig(source, file.label, {
69
+ schema: pageThemeSchema,
67
70
  validateStructure: validatePageThemeYamlStructure,
68
71
  });
69
- resolveThemeConfig(config, file.label);
70
- resolveThemePresentation(config, file.label);
71
72
 
72
73
  configs.push({ ...file, config });
73
74
  }
@@ -1,97 +1,47 @@
1
- import { mergeDeep } from './typography.mjs';
1
+ import { freezeDeep, mergeDeep } from './object.mjs';
2
+ import { presentationPaletteNames } from './presentation-palette-metadata.mjs';
3
+ import { resolveThemeProfileRecipe } from './theme-profiles.mjs';
2
4
 
3
- const themePresetConfigurations = Object.freeze({
5
+ export const themePresetRecipes = Object.freeze({
4
6
  portfolio: Object.freeze({
5
- navigation: { mode: 'automatic' },
6
- layout: {
7
- density: 'normal',
8
- pageWidth: '1240px',
9
- gutter: {
10
- desktop: 'clamp(1.25rem, 4vw, 3rem)',
11
- mobile: '1rem',
12
- },
13
- },
14
- images: {
15
- width: '1000px',
16
- maxAvailableWidthPercent: { desktop: 100, mobile: 100 },
17
- maxAvailableHeightPercent: { desktop: 78, mobile: 68 },
18
- },
19
- typography: {
20
- fontFamily: "'Helvetica Neue', Arial, sans-serif",
21
- profile: 'restrained',
22
- rhythm: 'normal',
23
- },
24
- palette: 'dark',
25
- sectionSurfaces: ['base'],
7
+ color: 'near-monochrome-dark',
8
+ typography: 'restrained-sans',
9
+ rhythm: 'balanced',
10
+ geometry: 'image-led',
11
+ media: 'prominent',
12
+ blocks: 'wide-cards',
13
+ corners: 'square',
14
+ surfaces: 'uniform',
26
15
  }),
27
16
  documentation: Object.freeze({
28
- navigation: { mode: 'automatic' },
29
- layout: {
30
- density: 'compact',
31
- pageWidth: '1240px',
32
- gutter: {
33
- desktop: 'clamp(1.25rem, 4vw, 3rem)',
34
- mobile: '1rem',
35
- },
36
- },
37
- images: {
38
- width: '920px',
39
- maxAvailableWidthPercent: { desktop: 100, mobile: 100 },
40
- maxAvailableHeightPercent: { desktop: 74, mobile: 68 },
41
- },
42
- typography: {
43
- fontFamily: "Georgia, 'Times New Roman', serif",
44
- profile: 'reading',
45
- rhythm: 'compact',
46
- },
47
- palette: 'paper',
48
- sectionSurfaces: ['base', 'soft'],
17
+ color: 'warm-paper-adaptive',
18
+ typography: 'editorial-reading',
19
+ rhythm: 'compact',
20
+ geometry: 'focused-reading',
21
+ media: 'supporting',
22
+ blocks: 'reading-column-cards',
23
+ corners: 'rounded',
24
+ surfaces: 'alternating',
49
25
  }),
50
26
  project: Object.freeze({
51
- navigation: { mode: 'automatic' },
52
- layout: {
53
- density: 'compact',
54
- pageWidth: '1120px',
55
- gutter: {
56
- desktop: 'clamp(1.25rem, 4vw, 3rem)',
57
- mobile: '1rem',
58
- },
59
- },
60
- images: {
61
- width: '840px',
62
- maxAvailableWidthPercent: { desktop: 100, mobile: 100 },
63
- maxAvailableHeightPercent: { desktop: 70, mobile: 62 },
64
- },
65
- typography: {
66
- fontFamily: "system-ui, -apple-system, BlinkMacSystemFont, 'Segoe UI', sans-serif",
67
- profile: 'reading',
68
- rhythm: 'compact',
69
- },
70
- palette: 'light',
71
- sectionSurfaces: ['base', 'soft'],
27
+ color: 'near-monochrome-adaptive',
28
+ typography: 'system-reading',
29
+ rhythm: 'compact',
30
+ geometry: 'balanced-site',
31
+ media: 'balanced',
32
+ blocks: 'balanced-cards',
33
+ corners: 'rounded',
34
+ surfaces: 'alternating',
72
35
  }),
73
36
  statement: Object.freeze({
74
- navigation: { mode: 'automatic' },
75
- layout: {
76
- density: 'airy',
77
- pageWidth: '1280px',
78
- gutter: {
79
- desktop: 'clamp(1.5rem, 5vw, 4rem)',
80
- mobile: '1rem',
81
- },
82
- },
83
- images: {
84
- width: '1080px',
85
- maxAvailableWidthPercent: { desktop: 100, mobile: 100 },
86
- maxAvailableHeightPercent: { desktop: 80, mobile: 70 },
87
- },
88
- typography: {
89
- fontFamily: "'Trebuchet MS', 'Helvetica Neue', Arial, sans-serif",
90
- profile: 'statement',
91
- rhythm: 'airy',
92
- },
93
- palette: 'paper',
94
- sectionSurfaces: ['base', 'emphasis'],
37
+ color: 'warm-paper-adaptive',
38
+ typography: 'expressive-sans',
39
+ rhythm: 'expansive',
40
+ geometry: 'expansive-statement',
41
+ media: 'immersive',
42
+ blocks: 'wide-cards',
43
+ corners: 'square',
44
+ surfaces: 'accented',
95
45
  }),
96
46
  });
97
47
 
@@ -99,29 +49,42 @@ export const themePresetDefinitions = Object.freeze({
99
49
  portfolio: Object.freeze({
100
50
  title: 'Portfolio',
101
51
  description: 'For portfolios and image-led sites, with restrained typography and generous space for images.',
102
- theme: themePresetConfigurations.portfolio,
52
+ recipe: themePresetRecipes.portfolio,
53
+ readerControls: Object.freeze({ colorMode: true }),
103
54
  }),
104
55
  documentation: Object.freeze({
105
56
  title: 'Documentation',
106
57
  description: 'For guides and reference material, with reading-focused typography and compact spacing.',
107
- theme: themePresetConfigurations.documentation,
58
+ recipe: themePresetRecipes.documentation,
59
+ readerControls: Object.freeze({ colorMode: true, focusReading: true }),
108
60
  }),
109
61
  project: Object.freeze({
110
62
  title: 'Project',
111
63
  description: 'For project and product sites that balance explanation, code, cards, and images.',
112
- theme: themePresetConfigurations.project,
64
+ recipe: themePresetRecipes.project,
65
+ readerControls: Object.freeze({ colorMode: true, focusReading: true }),
113
66
  }),
114
67
  statement: Object.freeze({
115
68
  title: 'Statement',
116
69
  description: 'For short, expressive sites, with larger typography, airy spacing, and stronger section emphasis.',
117
- theme: themePresetConfigurations.statement,
70
+ recipe: themePresetRecipes.statement,
71
+ readerControls: Object.freeze({ colorMode: true }),
118
72
  }),
119
73
  });
120
74
 
121
75
  export const themePresetNames = Object.freeze(Object.keys(themePresetDefinitions));
122
76
 
123
77
  export const themePresets = Object.freeze(Object.fromEntries(
124
- themePresetNames.map((name) => [name, themePresetDefinitions[name].theme]),
78
+ themePresetNames.map((name) => [
79
+ name,
80
+ freezeDeep({
81
+ ...resolveThemeProfileRecipe(
82
+ themePresetDefinitions[name].recipe,
83
+ `${name} theme preset`,
84
+ ),
85
+ readerControls: themePresetDefinitions[name].readerControls,
86
+ }),
87
+ ]),
125
88
  ));
126
89
 
127
90
  export const getThemePresetMetadata = (presetName) => {
@@ -158,6 +121,30 @@ export const resolveThemeConfig = (theme = {}, sourceLabel = 'theme.yaml') => {
158
121
  };
159
122
  };
160
123
 
124
+ const mergePageThemePart = (base, override, keys) => Object.fromEntries(keys
125
+ .filter((key) => override?.[key] !== undefined || base?.[key] !== undefined)
126
+ .map((key) => [key, override?.[key] ?? base?.[key]]));
127
+
128
+ export const mergePageThemeConfig = (base = {}, override = {}) => ({
129
+ ...base,
130
+ layout: {
131
+ ...(base.layout ?? {}),
132
+ ...mergePageThemePart(base.layout, override.layout, ['contentSpacing', 'textWidth']),
133
+ },
134
+ images: {
135
+ ...(base.images ?? {}),
136
+ ...mergePageThemePart(base.images, override.images, [
137
+ 'width',
138
+ 'maxAvailableWidthPercent',
139
+ 'maxAvailableHeightPercent',
140
+ ]),
141
+ },
142
+ sections: {
143
+ ...(base.sections ?? {}),
144
+ ...mergePageThemePart(base.sections, override.sections, ['backgroundPattern']),
145
+ },
146
+ });
147
+
161
148
  const quote = (value) => JSON.stringify(value);
162
149
  const responsiveValueLines = (label, value, indent = 2) => {
163
150
  const prefix = ' '.repeat(indent);
@@ -171,7 +158,7 @@ const responsiveValueLines = (label, value, indent = 2) => {
171
158
  export const renderThemePresetReference = (presetName, sourceLabel = 'theme.yaml') => {
172
159
  const preset = getThemePreset(presetName, sourceLabel);
173
160
  const metadata = getThemePresetMetadata(presetName);
174
- const { navigation, layout, images, typography, palette, sectionSurfaces } = preset;
161
+ const { colorMode, readerControls, corners, layout, images, blocks, typography, palette, sections } = preset;
175
162
 
176
163
  return [
177
164
  `# Original values for Norna's "${presetName}" theme preset.`,
@@ -181,13 +168,23 @@ export const renderThemePresetReference = (presetName, sourceLabel = 'theme.yaml
181
168
  `# Available theme presets: ${themePresetNames.join(', ')}.`,
182
169
  `preset: ${presetName}`,
183
170
  '',
184
- 'navigation:',
185
- ' # Alternatives: automatic, sections, top, tree.',
186
- ` mode: ${navigation.mode}`,
171
+ '# Initial appearance. System follows the visitor\'s operating-system preference.',
172
+ 'colorMode:',
173
+ ` default: ${colorMode.default}`,
174
+ '',
175
+ '# Optional reader controls shown with the always-available reading-width choice.',
176
+ 'readerControls:',
177
+ ` colorMode: ${readerControls.colorMode === true}`,
178
+ ` focusReading: ${readerControls.focusReading === true}`,
179
+ '',
180
+ '# Alternatives: square, rounded.',
181
+ `corners: ${corners}`,
187
182
  '',
188
183
  'layout:',
189
- ' # Alternatives: compact, normal, airy.',
190
- ` density: ${layout.density}`,
184
+ ' # Alternatives: compact, normal, spacious.',
185
+ ` contentSpacing: ${layout.contentSpacing}`,
186
+ ' # Alternatives: narrow, normal, wide.',
187
+ ` textWidth: ${layout.textWidth}`,
191
188
  ' # Any positive CSS length, including px, rem, em, %, or clamp(...).',
192
189
  ` pageWidth: ${layout.pageWidth}`,
193
190
  ' gutter:',
@@ -203,6 +200,12 @@ export const renderThemePresetReference = (presetName, sourceLabel = 'theme.yaml
203
200
  ...responsiveValueLines('maxAvailableWidthPercent', images.maxAvailableWidthPercent),
204
201
  ...responsiveValueLines('maxAvailableHeightPercent', images.maxAvailableHeightPercent),
205
202
  '',
203
+ 'blocks:',
204
+ ' cardList:',
205
+ ' # Alternatives: text, narrow, normal, wide.',
206
+ ' # A width written in a norna-card-list block overrides this default.',
207
+ ` width: ${blocks.cardList.width}`,
208
+ '',
206
209
  'typography:',
207
210
  ' # Any valid CSS font-family stack without semicolons.',
208
211
  ` fontFamily: ${quote(typography.fontFamily)}`,
@@ -217,11 +220,12 @@ export const renderThemePresetReference = (presetName, sourceLabel = 'theme.yaml
217
220
  ' # h2:',
218
221
  ' # size: large # small, medium, large, or xlarge',
219
222
  '',
220
- '# Alternatives: dark, light, paper.',
223
+ `# Alternatives: ${presentationPaletteNames.join(', ')}.`,
221
224
  `palette: ${palette}`,
222
- '# One value keeps every section on the same surface; multiple values cycle.',
223
- '# Use one to three unique values from: base, soft, emphasis.',
224
- `sectionSurfaces: [${sectionSurfaces.join(', ')}]`,
225
+ 'sections:',
226
+ ' # Alternatives: uniform, alternating, accented.',
227
+ ' # Alternating and accented are full-width and unavailable with tree navigation.',
228
+ ` backgroundPattern: ${sections.backgroundPattern}`,
225
229
  '',
226
230
  ].join('\n');
227
231
  };