@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
@@ -1,5 +1,3 @@
1
- import { readFile } from 'node:fs/promises';
2
- import path from 'node:path';
3
1
  import {
4
2
  defaultTypography,
5
3
  resolveTypographyConfig,
@@ -8,25 +6,17 @@ import {
8
6
  typographyRhythms,
9
7
  } from './lib/typography.mjs';
10
8
  import {
11
- getBodySections,
12
9
  getContentFiles,
13
10
  readSiteFile,
14
11
  validateContentFrontmatterStructure,
15
12
  validateFrontmatterIndentation,
16
- validatePageThemeYamlStructure,
17
13
  } from './lib/site-content.mjs';
14
+ import { parsePageMarkdown } from './lib/page-markdown.mjs';
18
15
  import {
19
- siteContentLabel,
20
- siteContentPath,
21
- sitePagesDir,
22
- sitePagesLabel,
23
16
  siteThemeLabel,
24
- siteThemePath,
25
17
  } from './lib/site-paths.mjs';
26
- import { getPageDirectoryAncestors } from './lib/page-model.mjs';
27
18
  import { readThemeConfig } from './lib/theme-config.mjs';
28
19
  import { resolveThemeConfig } from './lib/theme-presets.mjs';
29
- import { parseYamlConfig } from './lib/yaml-config.mjs';
30
20
 
31
21
  const mode = process.argv[2] ?? 'show';
32
22
 
@@ -199,28 +189,6 @@ const readThemeTypography = async () => {
199
189
  return resolveAnnotatedTypographyConfig(themeTypographyConfig ?? defaultTypography, siteThemeLabel);
200
190
  };
201
191
 
202
- const readPageThemeTypography = async (contentFile, themeTypography) => {
203
- if (contentFile.isHome) return themeTypography;
204
-
205
- for (const pageDirectory of getPageDirectoryAncestors(contentFile.pageDirectory).reverse()) {
206
- const pageThemePath = path.join(sitePagesDir, pageDirectory, 'theme.yaml');
207
- const pageThemeFile = await readFile(pageThemePath, 'utf8').catch((error) => {
208
- if (error?.code === 'ENOENT') return null;
209
- throw error;
210
- });
211
- if (!pageThemeFile) continue;
212
- const pageThemeLabel = `${sitePagesLabel}/${pageDirectory}/theme.yaml`;
213
-
214
- const pageThemeConfig = resolveThemeConfig(parseYamlConfig(pageThemeFile, pageThemeLabel, {
215
- validateStructure: validatePageThemeYamlStructure,
216
- }), pageThemeLabel);
217
- const typographyConfig = pageThemeConfig.typography;
218
- return resolveAnnotatedTypographyConfig(typographyConfig ?? defaultTypography, pageThemeLabel);
219
- }
220
-
221
- return themeTypography;
222
- };
223
-
224
192
  const readPageTypography = async (contentFile, siteThemeTypography) => {
225
193
  const { frontmatter, body } = await readSiteFile(contentFile.contentPath, contentFile.contentLabel);
226
194
  const indentationIssues = [];
@@ -233,9 +201,8 @@ const readPageTypography = async (contentFile, siteThemeTypography) => {
233
201
  ].join('\n'));
234
202
  }
235
203
 
236
- const pageTypography = await readPageThemeTypography(contentFile, siteThemeTypography);
237
- const sections = (await getBodySections(body)).sections
238
- .filter((section) => section.id)
204
+ const pageTypography = siteThemeTypography;
205
+ const sections = (await parsePageMarkdown(body, { label: contentFile.contentLabel })).sections
239
206
  .map((section) => {
240
207
  return {
241
208
  id: section.id,
@@ -1,18 +1,8 @@
1
- import { execFile } from 'node:child_process';
2
1
  import { mkdir, rename, stat } from 'node:fs/promises';
3
2
  import { createInterface } from 'node:readline/promises';
4
3
  import { stdin as input, stdout as output } from 'node:process';
5
4
  import path from 'node:path';
6
- import { promisify } from 'node:util';
7
5
  import {
8
- extractInlineNoteDiagnostics,
9
- extractMarkdownImageReferences,
10
- extractNornaMarkdownBlockDiagnostics,
11
- getNornaBlockImageReferences,
12
- } from './lib/norna-markdown-blocks.mjs';
13
- import {
14
- getBodySections,
15
- getContentFiles,
16
6
  getImageCandidatesByName,
17
7
  getDeprecatedInlineStyleReferences,
18
8
  readSiteFile,
@@ -22,16 +12,14 @@ import {
22
12
  validateFrontmatterIndentation,
23
13
  validateThemeYamlStructure,
24
14
  } from './lib/site-content.mjs';
25
- import { getHeadingIdentifierIssues } from './lib/heading-ids.mjs';
15
+ import { getSiteStructure } from './lib/site-structure.mjs';
26
16
  import { readImageDimensions } from './lib/image-dimensions.mjs';
17
+ import { parsePageMarkdown } from './lib/page-markdown.mjs';
27
18
  import {
28
19
  siteThemeLabel,
29
20
  siteThemePath,
30
- siteProjectRoot,
31
21
  } from './lib/site-paths.mjs';
32
22
 
33
- const execFileAsync = promisify(execFile);
34
-
35
23
  const args = new Set(process.argv.slice(2));
36
24
  const shouldWrite = args.has('--write');
37
25
  const shouldCheck = args.has('--check') || !shouldWrite;
@@ -46,7 +34,7 @@ const addIssue = ({ severity, message, fix, sectionId, sectionLabel }) => {
46
34
 
47
35
  const hasErrors = () => issues.some((issue) => issue.severity === 'error');
48
36
 
49
- const formatSectionLabel = (contentFile, section) => `${contentFile.contentLabel} [${section.id ?? section.heading}]`;
37
+ const formatSectionLabel = (contentFile, section) => `${contentFile.contentLabel} [${section.id ?? section.title}]`;
50
38
 
51
39
  const addContentIssue = (contentFile, issue) => addIssue({
52
40
  ...issue,
@@ -56,11 +44,18 @@ const addContentIssue = (contentFile, issue) => addIssue({
56
44
 
57
45
  const addSectionIssue = (contentFile, section, issue) => addIssue({
58
46
  ...issue,
59
- sectionId: issue.sectionId ?? `${contentFile.contentLabel}:${section.id ?? section.heading}`,
47
+ sectionId: issue.sectionId ?? `${contentFile.contentLabel}:${section.id ?? section.title}`,
60
48
  sectionLabel: issue.sectionLabel ?? formatSectionLabel(contentFile, section),
61
49
  });
62
50
 
63
- const promptForWrite = async () => {
51
+ const getMovePlanLines = (moves) => [
52
+ 'Planned image moves:',
53
+ ...moves.map((move) => `- ${getCandidateLabel({ contentFile: move.sourceContentFile, imagePath: move.from })} -> ${getExpectedImageLabel(move.contentFile, move.imageName)}`),
54
+ ];
55
+
56
+ const promptForWrite = async (moves) => {
57
+ console.log(getMovePlanLines(moves).join('\n'));
58
+
64
59
  if (skipPrompt) return true;
65
60
  if (!process.stdin.isTTY) return false;
66
61
 
@@ -182,9 +177,7 @@ const getGlobalImageCandidates = (globalImageCandidatesByName, imageName, expect
182
177
 
183
178
  const getReferenceLabel = (contentFile, section) => `${contentFile.contentLabel} [${section.id ?? 'page title'}]`;
184
179
 
185
- const getRootLabel = (contentFile) => contentFile.isHome
186
- ? contentFile.imagesLabel
187
- : contentFile.imagesLabel.replace(/\/images$/, '');
180
+ const getRootLabel = (contentFile) => contentFile.imagesLabel.replace(/\/images$/, '');
188
181
 
189
182
  const getCandidateLabel = ({ contentFile, imagePath }) =>
190
183
  `${contentFile.imagesLabel}/${toPosixPath(path.relative(contentFile.imagesDir, imagePath))}`;
@@ -205,33 +198,6 @@ const addGlobalImageCandidate = (globalImageCandidatesByName, imageName, candida
205
198
  globalImageCandidatesByName.get(imageName).push(candidate);
206
199
  };
207
200
 
208
- const assertCleanGitForCrossRootSync = async (moves) => {
209
- if (!moves.some((move) => move.crossRoot)) return;
210
-
211
- let stdout = '';
212
- try {
213
- ({ stdout } = await execFileAsync('git', ['status', '--short'], {
214
- cwd: siteProjectRoot,
215
- maxBuffer: 1024 * 1024,
216
- }));
217
- } catch (error) {
218
- addIssue({
219
- severity: 'error',
220
- message: 'Cross-page content sync requires a clean git working tree, but git status could not be checked.',
221
- fix: 'Run content:sync inside a Git worktree, or move cross-page image files manually.',
222
- });
223
- return;
224
- }
225
-
226
- if (!stdout.trim()) return;
227
-
228
- addIssue({
229
- severity: 'error',
230
- message: 'Cross-page content sync requires a clean git working tree before moving files between page image roots.',
231
- fix: `Commit or stash your current changes, then run content:sync again. Current changes:\n${stdout.trim()}`,
232
- });
233
- };
234
-
235
201
  const addConflictingMoveIssues = () => {
236
202
  const movesBySource = new Map();
237
203
  const movesByDestination = new Map();
@@ -334,7 +300,6 @@ const validateImageReference = async (
334
300
  contentFile,
335
301
  sourceContentFile: sourceCandidate.contentFile,
336
302
  section,
337
- crossRoot: sourceCandidate.contentFile !== contentFile,
338
303
  });
339
304
  }
340
305
  referencedImagePaths.add(sourcePath);
@@ -345,7 +310,7 @@ const validateImageReference = async (
345
310
  message: `Image "${imageName}" is used here but is located in ${getCandidateLabel(sourceCandidate)}.`,
346
311
  fix: sourceCandidate.contentFile === contentFile
347
312
  ? 'Run norna content:sync to move it directly into the current page image root.'
348
- : `Run norna content:sync to move it from ${getRootLabel(sourceCandidate.contentFile)} to ${getRootLabel(contentFile)}. Cross-page sync requires a clean git working tree when files are moved.`,
313
+ : `Run norna content:sync to move it from ${getRootLabel(sourceCandidate.contentFile)} to ${getRootLabel(contentFile)}.`,
349
314
  });
350
315
  }
351
316
 
@@ -402,7 +367,16 @@ try {
402
367
  }
403
368
  }
404
369
 
405
- const contentFiles = await getContentFiles();
370
+ const siteStructure = await getSiteStructure();
371
+ const contentFiles = siteStructure.contentFiles;
372
+ for (const warning of siteStructure.warnings) {
373
+ addIssue({
374
+ severity: 'warning',
375
+ message: warning.message,
376
+ sectionId: warning.label,
377
+ sectionLabel: warning.label,
378
+ });
379
+ }
406
380
  const allImageFiles = [];
407
381
  const contentFileContexts = [];
408
382
  const globalImageCandidatesByName = new Map();
@@ -414,8 +388,16 @@ for (const contentFile of contentFiles) {
414
388
  validateFrontmatterIndentation(frontmatter, addIssue);
415
389
  validateContentFrontmatterStructure(frontmatter, addIssue);
416
390
 
417
- const { headings, pageHeadings, prelude, sections } = await getBodySections(body);
418
- const headingIdentifierIssues = getHeadingIdentifierIssues(headings);
391
+ const page = await parsePageMarkdown(body, {
392
+ label: contentFile.contentLabel,
393
+ lineOffset: bodyLineOffset,
394
+ });
395
+ const {
396
+ headingIssues: headingIdentifierIssues,
397
+ pageHeadings,
398
+ prelude,
399
+ regions: sections,
400
+ } = page;
419
401
  const invalidHeadingLines = new Set();
420
402
  for (const issue of headingIdentifierIssues) {
421
403
  invalidHeadingLines.add(issue.heading.line);
@@ -459,10 +441,10 @@ for (const contentFile of contentFiles) {
459
441
  });
460
442
  }
461
443
 
462
- if (sections[0] && !sections[0].isPageTitle) {
444
+ if (sections[0] && sections[0].kind !== 'page-intro') {
463
445
  addContentIssue(contentFile, {
464
446
  severity: 'error',
465
- message: `The first content heading is "${sections[0].heading}", but a Norna page must start with its H1 title.`,
447
+ message: `The first content heading is "${sections[0].title}", but a Norna page must start with its H1 title.`,
466
448
  fix: 'Add the page title first, for example "# About".',
467
449
  });
468
450
  }
@@ -476,18 +458,18 @@ for (const contentFile of contentFiles) {
476
458
  }
477
459
 
478
460
  for (const section of sections) {
479
- if (section.isPageTitle) {
461
+ if (section.kind === 'page-intro') {
480
462
  if (
481
463
  pageHeadings.length === 1
482
464
  && sections[0] === section
483
- && !invalidHeadingLines.has(section.line)
465
+ && !invalidHeadingLines.has(section.bodyLine)
484
466
  ) {
485
467
  validSections.add(section);
486
468
  }
487
469
  continue;
488
470
  }
489
471
 
490
- if (invalidHeadingLines.has(section.line) || !section.id) continue;
472
+ if (invalidHeadingLines.has(section.bodyLine) || !section.id) continue;
491
473
 
492
474
  if (sectionsById.has(section.id)) {
493
475
  addSectionIssue(contentFile, section, {
@@ -505,24 +487,17 @@ for (const contentFile of contentFiles) {
505
487
  for (const section of sections) {
506
488
  if (!validSections.has(section)) continue;
507
489
 
508
- const blockResults = extractNornaMarkdownBlockDiagnostics(section.text, {
509
- label: contentFile.contentLabel,
510
- lineOffset: bodyLineOffset + section.line - 1,
511
- });
490
+ const blockResults = { blocks: section.blocks, errors: section.blockErrors };
512
491
  blockResultsBySection.set(section, blockResults);
513
492
 
514
- const inlineNoteResults = extractInlineNoteDiagnostics(section.text, {
515
- label: contentFile.contentLabel,
516
- lineOffset: bodyLineOffset + section.line - 1,
517
- });
518
- for (const error of inlineNoteResults.errors) {
493
+ for (const error of section.noteErrors) {
519
494
  addSectionIssue(contentFile, section, {
520
495
  severity: 'error',
521
496
  message: error.message,
522
497
  });
523
498
  }
524
499
 
525
- for (const reference of getNornaBlockImageReferences(blockResults.blocks)) {
500
+ for (const reference of section.managedImages) {
526
501
  const expectedPath = getExpectedImagePath(contentFile, reference.image);
527
502
  addExpectedReference(globalExpectedReferencesByPath, expectedPath, { contentFile, section, reference });
528
503
  }
@@ -557,8 +532,7 @@ for (const context of contentFileContexts) {
557
532
  for (const section of sections) {
558
533
  if (!validSections.has(section)) continue;
559
534
 
560
- const markdownImages = extractMarkdownImageReferences(section.text);
561
- for (const reference of markdownImages) {
535
+ for (const reference of section.markdownImages) {
562
536
  addSectionIssue(contentFile, section, {
563
537
  severity: 'warning',
564
538
  message: `Markdown image "${reference.target}" references a local image that is not managed by Norna.`,
@@ -585,7 +559,7 @@ for (const context of contentFileContexts) {
585
559
  }
586
560
 
587
561
  const sourcePathsByImage = new Map();
588
- for (const reference of getNornaBlockImageReferences(blocks)) {
562
+ for (const reference of section.managedImages) {
589
563
  const sourcePath = await validateImageReference(
590
564
  contentFile,
591
565
  section,
@@ -611,10 +585,6 @@ const unreferencedImages = allImageFiles
611
585
 
612
586
  addConflictingMoveIssues();
613
587
 
614
- if (shouldWrite) {
615
- await assertCleanGitForCrossRootSync(imageMoves);
616
- }
617
-
618
588
  if (hasErrors()) {
619
589
  printReport(shouldWrite ? 'Content sync failed.' : 'Content check failed.', unreferencedImages);
620
590
  process.exit(1);
@@ -633,14 +603,53 @@ if (imageMoves.length === 0) {
633
603
  process.exit(0);
634
604
  }
635
605
 
636
- const canWrite = await promptForWrite();
606
+ const canWrite = await promptForWrite(imageMoves);
637
607
  if (!canWrite) {
638
608
  console.log('Aborted. No file was changed.');
639
609
  process.exit(1);
640
610
  }
641
611
 
642
- for (const move of imageMoves) {
643
- await mkdir(path.dirname(move.to), { recursive: true });
644
- await rename(move.from, move.to);
645
- console.log(`Moved image "${move.imageName}" to ${move.contentFile.imagesLabel}/.`);
612
+ const completedMoves = [];
613
+ for (const [index, move] of imageMoves.entries()) {
614
+ try {
615
+ await mkdir(path.dirname(move.to), { recursive: true });
616
+ await rename(move.from, move.to);
617
+ completedMoves.push(move);
618
+ console.log(`Moved image "${move.imageName}" to ${move.contentFile.imagesLabel}/.`);
619
+ } catch (error) {
620
+ const sourceLabel = getCandidateLabel({ contentFile: move.sourceContentFile, imagePath: move.from });
621
+ const destinationLabel = getExpectedImageLabel(move.contentFile, move.imageName);
622
+ const remainingMoves = imageMoves.slice(index);
623
+ const lines = [
624
+ '',
625
+ `Content sync stopped after ${completedMoves.length} of ${imageMoves.length} image moves.`,
626
+ ];
627
+
628
+ if (error?.code === 'EXDEV') {
629
+ lines.push(
630
+ `Cannot move "${move.imageName}" because the source and destination are on different filesystems.`,
631
+ `Move it manually from ${sourceLabel} to ${destinationLabel}.`,
632
+ );
633
+ } else {
634
+ lines.push(
635
+ `Could not move "${move.imageName}" from ${sourceLabel} to ${destinationLabel}.`,
636
+ `Filesystem error${error?.code ? ` (${error.code})` : ''}: ${error?.message ?? String(error)}`,
637
+ );
638
+ }
639
+
640
+ if (completedMoves.length > 0) {
641
+ lines.push('', 'Completed moves:', ...getMovePlanLines(completedMoves).slice(1));
642
+ }
643
+
644
+ lines.push(
645
+ '',
646
+ 'Remaining moves:',
647
+ ...getMovePlanLines(remainingMoves).slice(1),
648
+ '',
649
+ 'Fix the reported filesystem problem, then run content:sync again. Already completed moves will be kept.',
650
+ );
651
+
652
+ console.error(lines.join('\n'));
653
+ process.exit(1);
654
+ }
646
655
  }
@@ -0,0 +1,107 @@
1
+ ---
2
+ import projectConfig from '../../scripts/lib/project-config.mjs';
3
+
4
+ type Appearance = 'system' | 'light' | 'dark';
5
+ type ReadingWidth = 'narrow' | 'standard' | 'wide';
6
+
7
+ interface Props {
8
+ controls: {
9
+ appearance: boolean;
10
+ readingWidth: boolean;
11
+ focusReading: boolean;
12
+ };
13
+ defaults: {
14
+ appearance: Appearance;
15
+ readingWidth: ReadingWidth;
16
+ focusReading: 'off' | 'on';
17
+ };
18
+ }
19
+
20
+ const { controls, defaults } = Astro.props;
21
+ const labels = projectConfig.locale.labels;
22
+ const appearanceOptions = [
23
+ { value: 'system', label: labels.colorModeSystem },
24
+ { value: 'light', label: labels.colorModeLight },
25
+ { value: 'dark', label: labels.colorModeDark },
26
+ ] as const;
27
+ const widthOptions = [
28
+ { value: 'narrow', label: labels.readingWidthNarrow },
29
+ { value: 'standard', label: labels.readingWidthStandard },
30
+ { value: 'wide', label: labels.readingWidthWide },
31
+ ] as const;
32
+ ---
33
+
34
+ <details class="display-settings" data-display-settings>
35
+ <summary aria-label={labels.displaySettings}>
36
+ <svg class="display-settings-trigger-icon" aria-hidden="true" viewBox="0 0 24 24">
37
+ <path d="M4 21v-7"></path>
38
+ <path d="M4 10V3"></path>
39
+ <path d="M12 21v-9"></path>
40
+ <path d="M12 8V3"></path>
41
+ <path d="M20 21v-5"></path>
42
+ <path d="M20 12V3"></path>
43
+ <path d="M1 14h6"></path>
44
+ <path d="M9 8h6"></path>
45
+ <path d="M17 16h6"></path>
46
+ </svg>
47
+ <span class="display-settings-focus-status" aria-hidden="true">{labels.focusReading}</span>
48
+ </summary>
49
+ <form class="display-settings-panel">
50
+ <p class="display-settings-title">{labels.displaySettings}</p>
51
+
52
+ {controls.appearance && (
53
+ <fieldset>
54
+ <legend>{labels.colorMode}</legend>
55
+ <div class="display-settings-segmented">
56
+ {appearanceOptions.map((option) => (
57
+ <label>
58
+ <input
59
+ type="radio"
60
+ name="appearance"
61
+ value={option.value}
62
+ checked={defaults.appearance === option.value}
63
+ data-reader-appearance
64
+ />
65
+ <span>{option.label}</span>
66
+ </label>
67
+ ))}
68
+ </div>
69
+ </fieldset>
70
+ )}
71
+
72
+ {controls.readingWidth && (
73
+ <fieldset>
74
+ <legend>{labels.readingWidth}</legend>
75
+ <div class="display-settings-segmented">
76
+ {widthOptions.map((option) => (
77
+ <label>
78
+ <input
79
+ type="radio"
80
+ name="reading-width"
81
+ value={option.value}
82
+ checked={defaults.readingWidth === option.value}
83
+ data-reader-width
84
+ />
85
+ <span>{option.label}</span>
86
+ </label>
87
+ ))}
88
+ </div>
89
+ </fieldset>
90
+ )}
91
+
92
+ {controls.focusReading && (
93
+ <label class="display-settings-toggle">
94
+ <input
95
+ type="checkbox"
96
+ checked={defaults.focusReading === 'on'}
97
+ data-reader-focus
98
+ />
99
+ <span>{labels.focusReading}</span>
100
+ </label>
101
+ )}
102
+
103
+ <button class="display-settings-reset" type="button" data-reader-reset>
104
+ {labels.resetDisplaySettings}
105
+ </button>
106
+ </form>
107
+ </details>
@@ -17,14 +17,28 @@ interface Props {
17
17
  desktop: number;
18
18
  mobile: number;
19
19
  };
20
+ maxAvailableHeightPercent: {
21
+ desktop: number;
22
+ mobile: number;
23
+ };
20
24
  priorityFirstImage?: boolean;
21
25
  }
22
26
 
23
- const { title, images, maxAvailableWidthPercent, priorityFirstImage = false } = Astro.props;
27
+ const {
28
+ title,
29
+ images,
30
+ maxAvailableWidthPercent,
31
+ maxAvailableHeightPercent,
32
+ priorityFirstImage = false,
33
+ } = Astro.props;
24
34
  const managedImageSizes = getManagedImageSizes(maxAvailableWidthPercent);
25
35
  const carouselAspectRatio = getCarouselAspectRatio(images);
26
36
  const carouselStyle = carouselAspectRatio
27
- ? `--image-carousel-aspect-ratio: ${carouselAspectRatio}`
37
+ ? [
38
+ `--image-carousel-aspect-ratio: ${carouselAspectRatio}`,
39
+ `--image-carousel-width-from-height-desktop: ${carouselAspectRatio * maxAvailableHeightPercent.desktop}svh`,
40
+ `--image-carousel-width-from-height-mobile: ${carouselAspectRatio * maxAvailableHeightPercent.mobile}svh`,
41
+ ].join('; ')
28
42
  : undefined;
29
43
  ---
30
44
 
@@ -35,7 +49,7 @@ const carouselStyle = carouselAspectRatio
35
49
  tabindex="0"
36
50
  role="group"
37
51
  aria-roledescription="carousel"
38
- aria-label={`${title}, bildkarusell`}
52
+ aria-label={`${title}, ${projectConfig.locale.labels.imageCarousel}`}
39
53
  style={carouselStyle}
40
54
  >
41
55
  <div class="image-carousel-stage">
@@ -64,19 +78,23 @@ const carouselStyle = carouselAspectRatio
64
78
  class="image-carousel-button image-carousel-button-previous"
65
79
  type="button"
66
80
  data-carousel-previous
67
- aria-label="Föregående bild"
68
- title="Föregående bild"
81
+ aria-label={projectConfig.locale.labels.previousImage}
82
+ title={projectConfig.locale.labels.previousImage}
69
83
  >
70
- <span aria-hidden="true">‹</span>
84
+ <svg aria-hidden="true" viewBox="0 0 24 24">
85
+ <path d="m15 18-6-6 6-6"></path>
86
+ </svg>
71
87
  </button>
72
88
  <button
73
89
  class="image-carousel-button image-carousel-button-next"
74
90
  type="button"
75
91
  data-carousel-next
76
- aria-label="Nästa bild"
77
- title="Nästa bild"
92
+ aria-label={projectConfig.locale.labels.nextImage}
93
+ title={projectConfig.locale.labels.nextImage}
78
94
  >
79
- <span aria-hidden="true">›</span>
95
+ <svg aria-hidden="true" viewBox="0 0 24 24">
96
+ <path d="m9 18 6-6-6-6"></path>
97
+ </svg>
80
98
  </button>
81
99
  <output class="image-carousel-position" data-carousel-position aria-live="polite">
82
100
  1 / {images.length}
@@ -132,6 +150,9 @@ const carouselStyle = carouselAspectRatio
132
150
  containScroll: false,
133
151
  loop: true,
134
152
  });
153
+ const reducedMotion = window.matchMedia('(prefers-reduced-motion: reduce)');
154
+ const scrollPrevious = () => embla.scrollPrev(reducedMotion.matches);
155
+ const scrollNext = () => embla.scrollNext(reducedMotion.matches);
135
156
 
136
157
  const update = () => {
137
158
  const activeIndex = embla.selectedScrollSnap();
@@ -152,11 +173,11 @@ const carouselStyle = carouselAspectRatio
152
173
 
153
174
  previous.addEventListener('click', () => {
154
175
  showControls();
155
- embla.scrollPrev();
176
+ scrollPrevious();
156
177
  });
157
178
  next.addEventListener('click', () => {
158
179
  showControls();
159
- embla.scrollNext();
180
+ scrollNext();
160
181
  });
161
182
  carousel.addEventListener('focusin', showControls);
162
183
  carousel.addEventListener('pointerdown', showControls);
@@ -164,12 +185,12 @@ const carouselStyle = carouselAspectRatio
164
185
  if (event.key === 'ArrowLeft') {
165
186
  event.preventDefault();
166
187
  showControls();
167
- embla.scrollPrev();
188
+ scrollPrevious();
168
189
  }
169
190
  if (event.key === 'ArrowRight') {
170
191
  event.preventDefault();
171
192
  showControls();
172
- embla.scrollNext();
193
+ scrollNext();
173
194
  }
174
195
  });
175
196
  embla.on('select', () => {