@janga/norna 0.7.16 → 0.7.17

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 (200) hide show
  1. package/README.md +6 -6
  2. package/astro.config.mjs +35 -3
  3. package/docs/README.md +10 -10
  4. package/docs/commands.md +2 -2
  5. package/docs/content.md +82 -102
  6. package/docs/design/navigation-and-theme-plan.md +115 -0
  7. package/docs/design/norna-diagram-design.md +9 -9
  8. package/docs/design/site-examples-structure.md +9 -9
  9. package/docs/engine-development.md +9 -9
  10. package/docs/getting-started.md +20 -15
  11. package/docs/images-and-metadata.md +10 -9
  12. package/docs/pages.md +134 -0
  13. package/docs/public-files.md +49 -36
  14. package/docs/publishing.md +19 -3
  15. package/docs/site-files.md +29 -28
  16. package/docs/sitewide-content.md +20 -36
  17. package/docs/theme.md +20 -20
  18. package/docs/typography.md +10 -10
  19. package/examples/README.md +2 -2
  20. package/examples/complete-sites/dog-shelter-multi-page/.astro/collections/site.schema.json +17 -41
  21. package/examples/complete-sites/dog-shelter-multi-page/.astro/collections/sitewide.schema.json +26 -67
  22. package/examples/complete-sites/dog-shelter-multi-page/.astro/collections/theme.schema.json +185 -88
  23. package/examples/complete-sites/dog-shelter-multi-page/.astro/data-store.json +1 -1
  24. package/examples/complete-sites/dog-shelter-multi-page/.astro/dev-local.json +4 -4
  25. package/examples/complete-sites/dog-shelter-multi-page/.astro/dev.json +5 -5
  26. package/examples/complete-sites/dog-shelter-multi-page/.astro/dev.log +33 -23
  27. package/examples/complete-sites/dog-shelter-multi-page/README.md +1 -1
  28. package/examples/complete-sites/dog-shelter-multi-page/node_modules/.vite/deps/_metadata.json +8 -8
  29. package/examples/complete-sites/dog-shelter-multi-page/site/.norna/generated-images.json +20 -20
  30. package/examples/complete-sites/dog-shelter-multi-page/site/content.md +3 -4
  31. package/examples/complete-sites/dog-shelter-multi-page/site/{routes → pages}/010-dogs/content.md +3 -4
  32. package/examples/complete-sites/dog-shelter-multi-page/site/{routes → pages}/020-adopt/content.md +3 -4
  33. package/examples/complete-sites/dog-shelter-multi-page/site/sitewide-content.yaml +2 -4
  34. package/examples/complete-sites/dog-shelter-single-page/.astro/collections/site.schema.json +17 -41
  35. package/examples/complete-sites/dog-shelter-single-page/.astro/collections/sitewide.schema.json +26 -67
  36. package/examples/complete-sites/dog-shelter-single-page/.astro/collections/theme.schema.json +185 -88
  37. package/examples/complete-sites/dog-shelter-single-page/.astro/data-store.json +1 -1
  38. package/examples/complete-sites/dog-shelter-single-page/.astro/dev-local.json +8 -0
  39. package/examples/complete-sites/dog-shelter-single-page/.astro/dev.json +5 -5
  40. package/examples/complete-sites/dog-shelter-single-page/.astro/dev.log +16 -12
  41. package/examples/complete-sites/dog-shelter-single-page/README.md +1 -1
  42. package/examples/complete-sites/dog-shelter-single-page/node_modules/.vite/deps/_metadata.json +8 -8
  43. package/examples/complete-sites/dog-shelter-single-page/site/.norna/generated-images.json +12 -12
  44. package/examples/complete-sites/dog-shelter-single-page/site/content.md +5 -2
  45. package/examples/complete-sites/dog-shelter-single-page/site/sitewide-content.yaml +2 -4
  46. package/examples/feature-demos/media-and-surfaces/.astro/collections/site.schema.json +17 -41
  47. package/examples/feature-demos/media-and-surfaces/.astro/collections/sitewide.schema.json +26 -67
  48. package/examples/feature-demos/media-and-surfaces/.astro/collections/theme.schema.json +185 -88
  49. package/examples/feature-demos/media-and-surfaces/.astro/data-store.json +1 -1
  50. package/examples/feature-demos/media-and-surfaces/.astro/dev.log +4 -14
  51. package/examples/feature-demos/media-and-surfaces/README.md +2 -2
  52. package/examples/feature-demos/media-and-surfaces/node_modules/.vite/deps/_metadata.json +9 -9
  53. package/examples/feature-demos/media-and-surfaces/site/.norna/generated-images.json +16 -16
  54. package/examples/feature-demos/media-and-surfaces/site/content.md +4 -7
  55. package/examples/feature-demos/media-and-surfaces/site/{routes → pages}/010-media/content.md +6 -5
  56. package/examples/feature-demos/media-and-surfaces/site/{routes → pages}/020-surfaces/content.md +7 -6
  57. package/examples/feature-demos/media-and-surfaces/site/sitewide-content.yaml +0 -2
  58. package/examples/feature-demos/sitewide-content/README.md +3 -3
  59. package/examples/feature-demos/sitewide-content/site/content.md +8 -7
  60. package/examples/feature-demos/sitewide-content/site/pages/010-logo-and-navigation/content.md +17 -0
  61. package/examples/feature-demos/sitewide-content/site/{routes → pages}/020-notices/content.md +7 -6
  62. package/examples/feature-demos/sitewide-content/site/{routes → pages}/030-footer/content.md +6 -5
  63. package/examples/feature-demos/sitewide-content/site/sitewide-content.yaml +4 -13
  64. package/examples/feature-demos/theme-presets/README.md +1 -1
  65. package/examples/feature-demos/theme-presets/site/.norna/generated-images.json +60 -60
  66. package/examples/feature-demos/theme-presets/site/content.md +4 -7
  67. package/examples/feature-demos/theme-presets/site/{routes → pages}/010-portfolio/content.md +4 -7
  68. package/examples/feature-demos/theme-presets/site/{routes → pages}/020-documentation/content.md +4 -7
  69. package/examples/feature-demos/theme-presets/site/{routes → pages}/030-project/content.md +4 -7
  70. package/examples/feature-demos/theme-presets/site/{routes → pages}/040-statement/content.md +4 -7
  71. package/examples/feature-demos/theme-presets/site/sitewide-content.yaml +1 -10
  72. package/fixtures/basic/site/content.md +5 -6
  73. package/fixtures/basic/site/sitewide-content.yaml +1 -8
  74. package/fixtures/content-model-v2/site/content.md +11 -13
  75. package/fixtures/content-model-v2/site/pages/010-guide/content.md +18 -0
  76. package/fixtures/nested-pages/site/.norna/generated-images.json +10 -0
  77. package/fixtures/nested-pages/site/config.yaml +1 -0
  78. package/fixtures/nested-pages/site/content.md +15 -0
  79. package/fixtures/nested-pages/site/pages/010-guides/content.md +15 -0
  80. package/fixtures/nested-pages/site/pages/010-guides/pages/010-installation/content.md +21 -0
  81. package/fixtures/nested-pages/site/pages/010-guides/pages/010-installation/images/diagram.svg +21 -0
  82. package/fixtures/nested-pages/site/pages/010-guides/pages/010-installation/pages/010-macos/content.md +14 -0
  83. package/fixtures/nested-pages/site/pages/010-guides/pages/020-workflows/content.md +11 -0
  84. package/fixtures/nested-pages/site/pages/010-guides/theme.yaml +3 -0
  85. package/fixtures/nested-pages/site/pages/020-reference/content.md +10 -0
  86. package/fixtures/nested-pages/site/pages/020-reference/pages/010-installation/content.md +11 -0
  87. package/fixtures/nested-pages/site/theme.yaml +3 -0
  88. package/package.json +7 -4
  89. package/schemas/config.schema.json +5 -5
  90. package/schemas/content-frontmatter.schema.json +28 -63
  91. package/schemas/manifest.json +1 -0
  92. package/schemas/sitewide-content.schema.json +58 -132
  93. package/schemas/theme.schema.json +396 -86
  94. package/scripts/check-config.mjs +6 -5
  95. package/scripts/deploy-site.mjs +6 -8
  96. package/scripts/doctor.mjs +2 -2
  97. package/scripts/generate-images.mjs +11 -18
  98. package/scripts/generate-schemas.mjs +3 -217
  99. package/scripts/lib/base-path-redirect.mjs +9 -0
  100. package/scripts/lib/editor-language-service.mjs +126 -66
  101. package/scripts/lib/heading-ids.mjs +161 -0
  102. package/scripts/lib/navigation-model.mjs +51 -0
  103. package/scripts/lib/norna-markdown-blocks.mjs +3 -4
  104. package/scripts/lib/page-model.mjs +83 -0
  105. package/scripts/lib/project-config.mjs +28 -0
  106. package/scripts/lib/schema-definitions.mjs +41 -46
  107. package/scripts/lib/schema-editor-metadata.mjs +475 -0
  108. package/scripts/lib/schema-value-definitions.mjs +6 -6
  109. package/scripts/lib/site-content.mjs +124 -87
  110. package/scripts/lib/site-paths.mjs +2 -2
  111. package/scripts/lib/theme-config.mjs +9 -16
  112. package/scripts/lib/theme-presets.mjs +9 -1
  113. package/scripts/release.mjs +1 -1
  114. package/scripts/show-typography.mjs +26 -20
  115. package/scripts/sync-content-sections.mjs +106 -65
  116. package/scripts/{test-temporary-visibility.mjs → test-banner-visibility.mjs} +7 -24
  117. package/scripts/test-client-javascript.mjs +39 -42
  118. package/scripts/test-content-check.mjs +138 -54
  119. package/scripts/test-content-model-v2.mjs +445 -228
  120. package/scripts/test-documentation.mjs +6 -1
  121. package/scripts/test-editor-language-service.mjs +168 -24
  122. package/scripts/test-engine-commands.mjs +2 -1
  123. package/scripts/test-heading-ids.mjs +68 -0
  124. package/scripts/test-navigation-model.mjs +63 -0
  125. package/scripts/test-nested-pages.mjs +110 -0
  126. package/scripts/test-package-check.mjs +31 -40
  127. package/scripts/test-page-model.mjs +80 -0
  128. package/scripts/test-project-config.mjs +25 -1
  129. package/scripts/test-schemas.mjs +66 -14
  130. package/scripts/test-theme-presets.mjs +33 -24
  131. package/src/components/NavigationPageTree.astro +68 -0
  132. package/src/components/SectionNavigationScript.astro +110 -5
  133. package/src/components/SiteBreadcrumbs.astro +29 -0
  134. package/src/components/SiteNavigation.astro +65 -69
  135. package/src/components/SitePage.astro +70 -46
  136. package/src/components/SiteSection.astro +27 -20
  137. package/src/content.config.ts +9 -5
  138. package/src/layouts/BaseLayout.astro +11 -20
  139. package/src/lib/pageThemes.ts +42 -0
  140. package/src/lib/sectionContent.ts +109 -106
  141. package/src/lib/siteNavigation.ts +48 -0
  142. package/src/lib/sitePages.ts +85 -38
  143. package/src/pages/{[slug].astro → [...slug].astro} +2 -2
  144. package/src/styles/global.css +373 -55
  145. package/starters/basic/README.md +5 -7
  146. package/starters/basic/site/content.md +7 -4
  147. package/starters/basic/site/sitewide-content.yaml +1 -10
  148. package/starters/project/README.md +8 -8
  149. package/starters/project/site/content.md +5 -4
  150. package/starters/project/site/{routes → pages}/010-guide/content.md +5 -4
  151. package/starters/project/site/sitewide-content.yaml +1 -10
  152. package/docs/routes.md +0 -121
  153. package/examples/feature-demos/sitewide-content/site/routes/010-identity/content.md +0 -20
  154. package/fixtures/content-model-v2/site/routes/010-guide/content.md +0 -17
  155. package/scripts/lib/route-model.mjs +0 -17
  156. package/scripts/test-route-model.mjs +0 -32
  157. package/src/lib/routeThemes.ts +0 -41
  158. /package/examples/complete-sites/dog-shelter-multi-page/site/images/{intro/shelter-dog.jpg → shelter-dog.jpg} +0 -0
  159. /package/examples/complete-sites/dog-shelter-multi-page/site/{routes/010-dogs/images/dogs → pages/010-dogs/images}/rex.jpg +0 -0
  160. /package/examples/complete-sites/dog-shelter-multi-page/site/{routes/010-dogs/images/dogs → pages/010-dogs/images}/rover.jpg +0 -0
  161. /package/examples/complete-sites/dog-shelter-multi-page/site/{routes/020-adopt/images/adopt → pages/020-adopt/images}/adoption-dog.jpg +0 -0
  162. /package/examples/complete-sites/dog-shelter-single-page/site/images/{you-can-help/foster-dog.jpg → foster-dog.jpg} +0 -0
  163. /package/examples/complete-sites/dog-shelter-single-page/site/images/{what-we-do/rescue-dog.jpg → rescue-dog.jpg} +0 -0
  164. /package/examples/feature-demos/media-and-surfaces/site/{routes/010-media/images/cards → pages/010-media/images}/card-carousel.svg +0 -0
  165. /package/examples/feature-demos/media-and-surfaces/site/{routes/010-media/images/cards → pages/010-media/images}/card-stack.svg +0 -0
  166. /package/examples/feature-demos/media-and-surfaces/site/{routes/010-media/images/cards → pages/010-media/images}/card-surfaces.svg +0 -0
  167. /package/examples/feature-demos/media-and-surfaces/site/{routes/010-media/images/carousel → pages/010-media/images}/carousel-one.svg +0 -0
  168. /package/examples/feature-demos/media-and-surfaces/site/{routes/010-media/images/carousel → pages/010-media/images}/carousel-three.svg +0 -0
  169. /package/examples/feature-demos/media-and-surfaces/site/{routes/010-media/images/carousel → pages/010-media/images}/carousel-two.svg +0 -0
  170. /package/examples/feature-demos/media-and-surfaces/site/{routes/010-media/images/stack → pages/010-media/images}/stack-one.svg +0 -0
  171. /package/examples/feature-demos/media-and-surfaces/site/{routes/010-media/images/stack → pages/010-media/images}/stack-two.svg +0 -0
  172. /package/examples/feature-demos/media-and-surfaces/site/{routes → pages}/020-surfaces/theme.yaml +0 -0
  173. /package/examples/feature-demos/theme-presets/site/{routes/010-portfolio/images/portfolio → pages/010-portfolio/images}/puppy-portrait.jpg +0 -0
  174. /package/examples/feature-demos/theme-presets/site/{routes/010-portfolio/images/portfolio → pages/010-portfolio/images}/shepherd-portrait.jpg +0 -0
  175. /package/examples/feature-demos/theme-presets/site/{routes/010-portfolio/images/portfolio → pages/010-portfolio/images}/white-puppy.jpg +0 -0
  176. /package/examples/feature-demos/theme-presets/site/{routes → pages}/010-portfolio/theme.yaml +0 -0
  177. /package/examples/feature-demos/theme-presets/site/{routes/020-documentation/images/documentation → pages/020-documentation/images}/black-schnauzer.jpg +0 -0
  178. /package/examples/feature-demos/theme-presets/site/{routes/020-documentation/images/documentation → pages/020-documentation/images}/retriever-portrait.jpg +0 -0
  179. /package/examples/feature-demos/theme-presets/site/{routes/020-documentation/images/documentation → pages/020-documentation/images}/schnauzer-portrait.jpg +0 -0
  180. /package/examples/feature-demos/theme-presets/site/{routes → pages}/020-documentation/theme.yaml +0 -0
  181. /package/examples/feature-demos/theme-presets/site/{routes/030-project/images/project → pages/030-project/images}/boxer-portrait.jpg +0 -0
  182. /package/examples/feature-demos/theme-presets/site/{routes/030-project/images/project → pages/030-project/images}/grass-puppy.jpg +0 -0
  183. /package/examples/feature-demos/theme-presets/site/{routes/030-project/images/project → pages/030-project/images}/grey-street-dog.jpg +0 -0
  184. /package/examples/feature-demos/theme-presets/site/{routes → pages}/030-project/theme.yaml +0 -0
  185. /package/examples/feature-demos/theme-presets/site/{routes/040-statement/images/statement → pages/040-statement/images}/black-pedigree.jpg +0 -0
  186. /package/examples/feature-demos/theme-presets/site/{routes/040-statement/images/statement → pages/040-statement/images}/sheepdog-grass.jpg +0 -0
  187. /package/examples/feature-demos/theme-presets/site/{routes/040-statement/images/statement → pages/040-statement/images}/sheepdog-wide.jpg +0 -0
  188. /package/examples/feature-demos/theme-presets/site/{routes → pages}/040-statement/theme.yaml +0 -0
  189. /package/fixtures/basic/site/images/{work/.gitkeep → .gitkeep} +0 -0
  190. /package/fixtures/content-model-v2/site/images/{card-section/adopt.svg → adopt.svg} +0 -0
  191. /package/fixtures/content-model-v2/site/images/{intro/detail.jpg → detail.jpg} +0 -0
  192. /package/fixtures/content-model-v2/site/images/{intro/duplicate.jpg → duplicate.jpg} +0 -0
  193. /package/fixtures/content-model-v2/site/images/{card-section/foster.svg → foster.svg} +0 -0
  194. /package/fixtures/content-model-v2/site/images/{intro/hero.jpg → hero.jpg} +0 -0
  195. /package/fixtures/content-model-v2/site/images/{plain/image.jpg → image.jpg} +0 -0
  196. /package/fixtures/content-model-v2/site/images/{timed/slide-one.jpg → slide-one.jpg} +0 -0
  197. /package/fixtures/content-model-v2/site/images/{timed/slide-three.jpg → slide-three.jpg} +0 -0
  198. /package/fixtures/content-model-v2/site/images/{timed/slide-two.jpg → slide-two.jpg} +0 -0
  199. /package/fixtures/content-model-v2/site/{routes/010-guide/images/intro → pages/010-guide/images}/duplicate.jpg +0 -0
  200. /package/starters/basic/site/images/{work/.gitkeep → .gitkeep} +0 -0
@@ -26,7 +26,7 @@ site repository. It should not be a showcase for every feature.
26
26
 
27
27
  An example site is a runnable site that demonstrates one or more features.
28
28
 
29
- Examples can be richer than the starter. They may show routes, navigation,
29
+ Examples can be richer than the starter. They may show pages, navigation,
30
30
  complete theme presets, image stacks, image carousels, cards, notes, surfaces,
31
31
  and site-specific configuration choices.
32
32
 
@@ -35,8 +35,8 @@ and site-specific configuration choices.
35
35
  A documentation site is a runnable `norna` site that explains the product
36
36
  visually.
37
37
 
38
- It can use images, diagrams, screenshots, and route pages to explain concepts
39
- such as file structure, presentation inheritance, route navigation, and image
38
+ It can use images, diagrams, screenshots, and additional pages to explain concepts
39
+ such as file structure, presentation inheritance, site navigation, and image
40
40
  handling.
41
41
 
42
42
  ### Reference Documentation
@@ -73,22 +73,22 @@ examples/
73
73
  `complete-sites/` contains coherent sites that show how Norna files work
74
74
  together in a realistic project:
75
75
 
76
- - `dog-shelter-single-page/`: sections and managed images without routes.
77
- - `dog-shelter-multi-page/`: ordered routes with route-local content and
76
+ - `dog-shelter-single-page/`: sections and managed images without additional pages.
77
+ - `dog-shelter-multi-page/`: ordered pages with page-local content and
78
78
  images.
79
79
 
80
80
  `feature-demos/` contains focused visual test benches:
81
81
 
82
- - `theme-presets/`: one route per complete built-in theme preset, without
82
+ - `theme-presets/`: one page per complete built-in theme preset, without
83
83
  overrides.
84
84
  - `media-and-surfaces/`: image and card blocks, notes, palettes and section
85
85
  surfaces. This is also the broad demo-build and navigation-test target.
86
- - `sitewide-content/`: convention-based identity, navigation, banner stacks,
87
- dismissal and footer content shared across routes.
86
+ - `sitewide-content/`: convention-based logo handling, navigation, banner stacks,
87
+ dismissal and footer content shared across pages.
88
88
 
89
89
  The repository Pages workflow builds all examples and publishes them
90
90
  under `/norna/examples/`. The HTML documentation links to those rendered sites
91
- from its Examples route.
91
+ from its Examples page.
92
92
 
93
93
  The repository-local `site/` directory is reserved for the documentation site.
94
94
  `docs/` should remain for reference documentation. It should link to the
@@ -185,25 +185,25 @@ and commit their updated `package-lock.json`.
185
185
 
186
186
  ## Rendering Notes
187
187
 
188
- The renderer builds the homepage at `/` and optional first-level routes from
189
- `site/routes/<NNN-route-id>/content.md`.
188
+ The renderer builds the homepage at `/` and optional first-level pages from
189
+ `site/pages/<NNN-page-id>/content.md`.
190
190
 
191
191
  Navigation has two separate levels:
192
192
 
193
- - Site navigation moves between pages and routes. It uses normal page URLs and
194
- browser history.
195
- - Page navigation moves between sections on the current page. It uses real
193
+ - Site navigation moves between the homepage and additional pages. It uses
194
+ normal page URLs and browser history.
195
+ - Section navigation moves between sections on the current page. It uses real
196
196
  `href="#section-id"` links so anchors work without JavaScript.
197
197
 
198
198
  The current navigation model is deliberately scoped to single-page and small
199
- multi-page sites. That scope may change as route support matures. For now,
200
- single-page sites should rely on page navigation only; small route-based sites
201
- may combine site navigation and page navigation; larger information
199
+ multi-page sites. That scope may change as navigation support matures. For now,
200
+ single-page sites should rely on section navigation only; small multi-page sites
201
+ may combine site navigation and section navigation; larger information
202
202
  architectures should not be forced into the sticky-navigation model without a
203
203
  separate design decision.
204
204
 
205
205
  The JavaScript enhancement keeps the URL hash as the source of truth for active
206
- page-navigation state. A section-link click pushes one hash entry into browser
206
+ section-navigation state. A section-link click pushes one hash entry into browser
207
207
  history, back/forward moves between hash entries, and returning to the same page
208
208
  without a hash restores the first section as active. The enhancement does not
209
209
  derive active section state from free manual scrolling.
@@ -73,46 +73,51 @@ Replace `site/content.md` with:
73
73
 
74
74
  ```md
75
75
  ---
76
- title: My first Norna site
77
- description: A website built from plain files.
76
+ page:
77
+ description: A website built from plain files.
78
78
  ---
79
79
 
80
- ## Welcome {#welcome}
80
+ # My first Norna site
81
81
 
82
82
  This page is written in Markdown. Norna provides its layout and navigation.
83
83
 
84
+ ## Welcome {#welcome}
85
+
86
+ This is the first section.
87
+
84
88
  ## Next {#next}
85
89
 
86
90
  Edit this file while the development server is running and the browser updates.
87
91
  ```
88
92
 
89
- Each `##` heading is a page section. Its explicit `{#section-id}` gives the
90
- section a stable identity and is required by Norna.
93
+ The single `#` heading is the page title. Each `##` heading is a page section.
94
+ Its explicit `{#section-id}` gives the section a stable identity and is
95
+ required by Norna.
91
96
 
92
97
  ### Checkpoint: Content And Navigation Update
93
98
 
94
99
  Return to the browser. The page should now contain `Welcome` and `Next`, and
95
- the single-page navigation should link to those two sections. You should not
100
+ the section navigation should link to those two sections. You should not
96
101
  need to restart the server.
97
102
 
98
- ## 3. Set The Shared Identity
103
+ ## 3. Set Shared Content
99
104
 
100
105
  Replace `site/sitewide-content.yaml` with:
101
106
 
102
107
  ```yaml
103
- navigation:
104
- label: My first Norna site
105
108
  footer:
106
109
  copyrightMessage: My first Norna site.
107
110
  ```
108
111
 
109
- The navigation label and footer are site-wide content rather than page
110
- sections. If you add routes later, they inherit these values.
112
+ The footer is site-wide content rather than a page section. If you add pages
113
+ later, they share it. The homepage H1 you set in the previous step already
114
+ names the homepage in navigation and becomes the alternative text if you add a
115
+ conventional navigation logo.
111
116
 
112
- ### Checkpoint: The Identity Is Shared
117
+ ### Checkpoint: The Footer Is Shared
113
118
 
114
- The navigation should now display `My first Norna site`. The footer should show
115
- the new message.
119
+ The navigation should use `My first Norna site` from `content.md`. The footer
120
+ should show the new message.
116
121
 
117
122
  ## 4. Choose A Complete Theme
118
123
 
@@ -158,7 +163,7 @@ build.
158
163
  ## What To Do Next
159
164
 
160
165
  - [Add and manage images](content.md#norna-blocks)
161
- - [Add another page](routes.md)
166
+ - [Add another page](pages.md)
162
167
  - [Inspect and adjust the theme](theme.md)
163
168
  - [Configure the public URL](configuration.md)
164
169
  - [Publish with GitHub Pages](publishing.md)
@@ -12,13 +12,13 @@ Norna-managed local images are referenced from Markdown with
12
12
  Homepage source images live under:
13
13
 
14
14
  ```text
15
- site/images/<section-id>/
15
+ site/images/
16
16
  ```
17
17
 
18
- Route source images live under:
18
+ Page source images live under:
19
19
 
20
20
  ```text
21
- site/routes/<NNN-route-id>/images/<section-id>/
21
+ site/pages/<NNN-page-id>/images/
22
22
  ```
23
23
 
24
24
  Supported source extensions:
@@ -52,11 +52,12 @@ prompt: Short prompt or editing note.
52
52
  -->
53
53
  ```
54
54
 
55
- Filenames do not have to be globally unique for the site to be valid.
56
- Automatic sync only moves misplaced files when the filename identifies exactly
57
- one source candidate across the site's page and route image roots, and when the
58
- move will not break another reference. If the move crosses page or route image
59
- roots, `content:sync` requires a clean Git working tree before writing.
55
+ Each filename identifies one managed source image within its page. The same
56
+ filename may be used by another page. Automatic sync only moves misplaced
57
+ files when the filename identifies exactly one source candidate across all
58
+ page image roots, and when the move will not break another reference. If the
59
+ move crosses page image roots, `content:sync` requires a clean Git working tree
60
+ before writing.
60
61
 
61
62
  ## Markdown Images
62
63
 
@@ -139,7 +140,7 @@ copyright metadata.
139
140
  Generated WebP files are created with ImageMagick using `-strip`, so embedded
140
141
  metadata is not a publication mechanism for generated variants. Keep licensing,
141
142
  credits, copyright notices, alt text, and captions in site-owned files such as
142
- `site/content.md`, route content files, `COPYRIGHT.md`, or other site
143
+ `site/content.md`, page content files, `COPYRIGHT.md`, or other site
143
144
  documentation.
144
145
 
145
146
  If a site wants embedded metadata in original source files, that process is
package/docs/pages.md ADDED
@@ -0,0 +1,134 @@
1
+ # Pages
2
+
3
+ `site/content.md` is the homepage and builds to `/`. Optional additional pages live
4
+ under `site/pages/<NNN-page-id>/content.md` and build to first-level
5
+ URLs.
6
+
7
+ Pages use the same H1 title, optional frontmatter, Norna-managed blocks, and
8
+ Markdown section model as the homepage. See [Content](content.md) for the page
9
+ and section model.
10
+
11
+ Page directories can contain page content, page-local images, and
12
+ an optional page-local `theme.yaml`. The page theme replaces the root visual
13
+ theme for that page and can select any complete top-level theme preset. Page
14
+ directories cannot contain `config.yaml` or `sitewide-content.yaml`; technical
15
+ configuration and shared logo, banner, and footer settings remain at the
16
+ selected site's top level.
17
+
18
+ ## Page Directory Format
19
+
20
+ Page directories must use:
21
+
22
+ ```text
23
+ NNN-page-id
24
+ ```
25
+
26
+ `NNN` is a three-digit presentation order from `001` through `999`.
27
+ `page-id` becomes the page id and URL segment.
28
+
29
+ Valid examples:
30
+
31
+ ```text
32
+ 010-getting-started
33
+ 020-concepts
34
+ 120-api-reference
35
+ ```
36
+
37
+ Invalid examples:
38
+
39
+ ```text
40
+ 10-about
41
+ 000-home
42
+ 010_About
43
+ 010-About
44
+ 010-about-
45
+ 010-about--team
46
+ ```
47
+
48
+ The page id may contain only lowercase `a-z`, numbers, and single hyphens
49
+ between alphanumeric groups. The numeric prefix is not part of the page id or
50
+ URL.
51
+
52
+ Renaming `030-contact/` to `015-contact/` changes navigation order but keeps
53
+ the page id `contact` and URL `/contact/`.
54
+
55
+ ## Page File
56
+
57
+ Add a first-level page by creating:
58
+
59
+ ```text
60
+ site/pages/010-about/content.md
61
+ ```
62
+
63
+ Minimal additional page:
64
+
65
+ ```md
66
+ ---
67
+ page:
68
+ description: About this site.
69
+ ---
70
+
71
+ # About
72
+
73
+ Introductory text.
74
+
75
+ ## Team {#team}
76
+
77
+ Text...
78
+ ```
79
+
80
+ The example above builds to `/about/`.
81
+
82
+ ## Navigation
83
+
84
+ Site navigation uses each page's Markdown H1 as its visible label and the
85
+ page-directory prefix as its order. In a multi-page site, the homepage is the
86
+ first navigation item and uses its own H1. An optional logo is a separate home
87
+ link; it does not replace the homepage item or own a section menu.
88
+
89
+ `navigation` has one optional field:
90
+
91
+ - `listed`: boolean. Defaults to `true`. Set it to `false` to keep the page
92
+ public while excluding it from site navigation.
93
+
94
+ ```yaml
95
+ navigation:
96
+ listed: false
97
+ ```
98
+
99
+ Page order comes from the directory prefix.
100
+ The homepage is always listed before additional pages.
101
+
102
+ Current site navigation is intended for small sites. This guidance may change
103
+ as navigation support matures, but the present model is:
104
+
105
+ - A single-page site should normally use only section navigation.
106
+ - A small multi-page site may use site navigation between pages plus section
107
+ navigation on the current page.
108
+ - If a site needs many pages, deeply nested pages, or several navigation
109
+ levels, it has probably outgrown the current sticky-navigation model and may
110
+ need a different site structure or navigation system.
111
+
112
+ ## Page Images
113
+
114
+ Page images live under the physical page directory:
115
+
116
+ ```text
117
+ site/pages/010-about/images/image.jpg
118
+ ```
119
+
120
+ Image references in page content still use only the filename:
121
+
122
+ ````md
123
+ ```norna-image-stack
124
+ - image: image.jpg
125
+ alt: Intro image.
126
+ ```
127
+ ````
128
+
129
+ All managed images used by the page share this one `images/` directory. Run
130
+ `norna content:check` to find missing or misplaced images and
131
+ `norna content:sync` to move unambiguous files into the expected page image
132
+ root. `content:sync` can move images between page image roots when the filename
133
+ is unambiguous across the site and the move will not break another reference;
134
+ these cross-page writes require a clean Git working tree.
@@ -11,62 +11,72 @@ convention.
11
11
 
12
12
  ## Navigation Logo
13
13
 
14
- Put exactly one navigation logo directly in `site/public/`. Its filename must
15
- be exactly one of:
14
+ To add a navigation logo, place exactly one supported logo file directly in
15
+ `site/public/`:
16
16
 
17
17
  - `logo.svg`
18
18
  - `logo.png`
19
19
  - `logo.jpg`
20
20
  - `logo.jpeg`
21
21
 
22
- Use lowercase letters and match the complete filename exactly. This is required
23
- for portability between case-sensitive and case-insensitive file systems.
22
+ Norna discovers the logo from its filename, so you do not configure a path or
23
+ enable it separately. Use the exact lowercase filename to keep the site
24
+ portable between case-sensitive and case-insensitive file systems.
24
25
 
25
- Norna discovers and displays the file automatically. No configuration path or
26
- enable switch is needed. Only one supported logo file may exist.
26
+ The logo links to the homepage. Its alternative text comes from the homepage
27
+ Markdown H1 in `site/content.md`; no separate site name or logo alt text is
28
+ configured.
27
29
 
28
- The shared navigation label is configured separately:
30
+ Configure top-level `logo` in `site/sitewide-content.yaml` only when you need
31
+ to override the displayed height:
29
32
 
30
33
  ```yaml
31
- navigation:
32
- label: Example Site
34
+ logo:
35
+ height: 2rem
33
36
  ```
34
37
 
35
- Without a logo, `label` is shown as navigation text. With a logo, it becomes the
36
- image alternative text. If `label` is omitted, Norna uses the homepage title.
37
-
38
- Add the optional `logo` object only to override the displayed height:
39
-
40
- ```yaml
41
- navigation:
42
- label: Example Site
43
- logo:
44
- height: 2rem
45
- ```
46
-
47
- The width follows the logo's intrinsic aspect ratio. `navigation.logo` does not
48
- enable the logo or select a file.
38
+ The width follows the image's intrinsic aspect ratio. `logo` does
39
+ not enable the logo or select a file.
49
40
 
50
41
  `norna config:check` fails when it finds multiple supported logo files, or when
51
- `navigation.logo` is configured but no logo file exists. A site without a logo
52
- uses its text label; the check reports this fallback as a warning.
53
-
54
- ## Logos And Favicons
42
+ `logo` is configured but no logo file exists. A site without a logo uses its
43
+ ordinary page-title navigation; the check reports the missing logo as a
44
+ warning.
55
45
 
56
- A navigation logo is visible inside the website. A favicon identifies the site
57
- in browser tabs, bookmarks, and similar browser UI. They are independent and
58
- may coexist.
46
+ ## Browser Icons
59
47
 
60
- Norna recognizes these browser-icon filenames directly under `site/public/`:
48
+ To add browser icons, place one or more supported files directly in
49
+ `site/public/`:
61
50
 
62
51
  - `favicon.svg`
63
52
  - `favicon.ico`
64
53
  - `favicon.png`
65
54
  - `apple-touch-icon.png`
66
55
 
67
- These filenames must also match exactly and use lowercase letters. More than
68
- one format may be present. Norna emits links for every supported file and lets
69
- the browser choose the appropriate one.
56
+ Norna discovers these files from their filenames, so you do not configure paths
57
+ or enable them separately. Use the exact lowercase filenames to keep the site
58
+ portable between case-sensitive and case-insensitive file systems.
59
+
60
+ You may include several supported browser-icon files. Norna links every file it
61
+ finds and lets the browser select the appropriate format.
62
+
63
+ Browser icons are separate from the navigation logo. The logo appears inside
64
+ the website, while browser icons identify it in tabs, bookmarks, and similar
65
+ browser interfaces.
66
+
67
+ ## GitHub Pages Custom Domain
68
+
69
+ To use a custom domain with GitHub Pages, place a file named exactly `CNAME`
70
+ directly in `site/public/`. Write the domain name in the file without a protocol
71
+ or path:
72
+
73
+ ```text
74
+ www.example.com
75
+ ```
76
+
77
+ Norna does not discover or interpret `CNAME`; it copies the file to the root of
78
+ the generated website. GitHub Pages gives the filename its meaning. The public
79
+ `url` in `site/config.yaml` should use the same domain.
70
80
 
71
81
  ## Other Static Files
72
82
 
@@ -75,12 +85,16 @@ Other names are not restricted. For example:
75
85
  ```text
76
86
  site/public/
77
87
  |-- robots.txt
78
- |-- CNAME
79
88
  |-- verification.html
80
89
  `-- downloads/
81
90
  `-- project-overview.pdf
82
91
  ```
83
92
 
93
+ Except for the navigation logo and browser icons documented above, Norna does
94
+ not attach meaning to filenames or inspect their contents. It copies them
95
+ unchanged. Browsers, crawlers, hosting services, and verification providers may
96
+ still require their own exact filenames and locations.
97
+
84
98
  Norna preserves subdirectories while copying these files. A source file such
85
99
  as `site/public/downloads/project-overview.pdf` is published at
86
100
  `/downloads/project-overview.pdf`, prefixed with the site's configured base path
@@ -102,4 +116,3 @@ validated, synced, processed, and captioned. See
102
116
  `norna site:public` copies source files from `site/public/` to
103
117
  `site/.norna/public/`. The latter directory is generated build-preparation
104
118
  output and must not be edited or versioned.
105
-
@@ -9,7 +9,21 @@ want to deploy the documentation site.
9
9
 
10
10
  ## GitHub Pages Workflow
11
11
 
12
- Each site repository owns `.github/workflows/deploy.yml`. The starter workflow:
12
+ `norna init` creates the GitHub Pages workflow at exactly:
13
+
14
+ ```text
15
+ .github/workflows/deploy.yml
16
+ ```
17
+
18
+ The file belongs to the site repository. GitHub Actions runs its contents, while
19
+ Norna's deploy helpers use the filename to find and monitor the workflow. Keep
20
+ the default filename when using `norna deploy`.
21
+
22
+ GitHub Actions itself permits other workflow filenames. If the file is renamed,
23
+ `norna deploy:watch` can monitor it with `--workflow <name-or-file>`, but the
24
+ normal `norna deploy` command still expects `deploy.yml`.
25
+
26
+ The starter workflow:
13
27
 
14
28
  1. runs for the repository's default branch,
15
29
  2. checks out the site repository,
@@ -20,8 +34,10 @@ Each site repository owns `.github/workflows/deploy.yml`. The starter workflow:
20
34
  7. deploys the artifact to GitHub Pages.
21
35
 
22
36
  In the GitHub repository settings, set Pages to build from GitHub Actions.
23
- Site-specific public files such as `site/public/CNAME`, `robots.txt` and
24
- `sitemap.xml` belong in the site repository.
37
+ Site-specific public files such as `site/public/CNAME`, `robots.txt`, and
38
+ `sitemap.xml` belong in the site repository. Norna copies them, while GitHub
39
+ Pages, crawlers, and other external consumers give those filenames their
40
+ meaning. See [Public Files](public-files.md).
25
41
 
26
42
  For a project site without a custom domain, include the repository path in
27
43
  `site/config.yaml`:
@@ -2,7 +2,7 @@
2
2
 
3
3
  Norna expects a defined set of files and directories. Their names and locations
4
4
  are part of the site model: following the structure lets Norna find content,
5
- presentation, configuration, routes, and assets without path configuration.
5
+ presentation, configuration, pages, and assets without path configuration.
6
6
 
7
7
  The selected site directory is `site/` by default:
8
8
 
@@ -13,13 +13,13 @@ site/
13
13
  |-- sitewide-content.yaml
14
14
  |-- content.md
15
15
  |-- images/
16
- | `-- <section-id>/
17
- |-- routes/
18
- | `-- <NNN-route-id>/
16
+ | `-- image.jpg
17
+ |-- pages/
18
+ | `-- <NNN-page-id>/
19
19
  | |-- content.md
20
20
  | |-- theme.yaml
21
21
  | `-- images/
22
- | `-- <section-id>/
22
+ | `-- image.jpg
23
23
  |-- public/
24
24
  `-- .norna/
25
25
  |-- generated-images.json
@@ -36,8 +36,8 @@ case-insensitive file systems.
36
36
  | --- | --- | --- |
37
37
  | `config.yaml` | Yes | Public URL, language, and browser scroll behavior. |
38
38
  | `theme.yaml` | Yes | Complete visual preset and optional focused overrides. |
39
- | `sitewide-content.yaml` | No | Shared navigation identity, banners, and footer. |
40
- | `content.md` | Yes | Homepage metadata, sections, prose, and Norna blocks. |
39
+ | `sitewide-content.yaml` | No | Shared logo display settings, banners, and footer. |
40
+ | `content.md` | Yes | Homepage title, optional metadata, sections, prose, and Norna blocks. |
41
41
 
42
42
  These responsibilities are deliberately separate:
43
43
 
@@ -47,43 +47,44 @@ These responsibilities are deliberately separate:
47
47
  only a preset selection.
48
48
  - [`sitewide-content.yaml`](sitewide-content.md) contains editorial material
49
49
  shared by every page.
50
- - [`content.md`](content.md) is the homepage page file and remains ordinary
51
- Markdown with YAML frontmatter.
50
+ - [`content.md`](content.md) is the homepage file and remains ordinary
51
+ Markdown. YAML frontmatter is optional.
52
52
 
53
- Routes cannot provide `config.yaml` or `sitewide-content.yaml`. Technical
54
- configuration and shared identity have one site-wide source.
53
+ Pages cannot provide `config.yaml` or `sitewide-content.yaml`. Technical
54
+ configuration and shared logo, banner, and footer settings have one site-wide
55
+ source.
55
56
 
56
57
  ## Images
57
58
 
58
59
  Managed homepage images belong in:
59
60
 
60
61
  ```text
61
- site/images/<section-id>/
62
+ site/images/
62
63
  ```
63
64
 
64
- The directory name must match an explicit level 2 Markdown section id in
65
- `content.md`. Markdown blocks refer to managed images by filename, not by path.
66
- See [Images and Metadata](images-and-metadata.md) for supported formats,
67
- generated variants, and syncing.
65
+ All managed images used by the homepage share this directory. Markdown blocks
66
+ refer to managed images by filename, not by path. See
67
+ [Images and Metadata](images-and-metadata.md) for supported formats, generated
68
+ variants, and syncing.
68
69
 
69
- ## Routes
70
+ ## Pages
70
71
 
71
- Each first-level route is one directory under `routes/`:
72
+ Each first-level page is one directory under `pages/`:
72
73
 
73
74
  ```text
74
- site/routes/010-guide/
75
+ site/pages/010-guide/
75
76
  |-- content.md
76
77
  |-- theme.yaml
77
78
  `-- images/
78
- `-- intro/
79
+ `-- image.jpg
79
80
  ```
80
81
 
81
- `content.md` is required for a route. The optional route `theme.yaml` replaces
82
- the root visual theme for that route. Route images follow the same
83
- `images/<section-id>/` convention as homepage images.
82
+ `content.md` is required for a page. The optional page `theme.yaml` replaces
83
+ the root visual theme for that page. Page images live directly in that page's
84
+ `images/` directory.
84
85
 
85
- The three-digit route prefix controls navigation order and is not part of the
86
- URL. See [Routes](routes.md) for exact directory-name and route-id rules.
86
+ The three-digit page prefix controls navigation order and is not part of the
87
+ URL. See [Pages](pages.md) for exact directory-name and page-id rules.
87
88
 
88
89
  ## Public Files
89
90
 
@@ -91,8 +92,9 @@ URL. See [Routes](routes.md) for exact directory-name and route-id rules.
91
92
  names are site-owned, but Norna recognizes a small set of exact conventional
92
93
  filenames for the navigation logo and browser icons.
93
94
 
94
- See [Public Files](public-files.md) for logo and favicon filenames, arbitrary
95
- static files, root-relative links, and publishing paths.
95
+ See [Public Files](public-files.md) for navigation-logo and browser-icon
96
+ filenames, GitHub Pages `CNAME`, arbitrary static files, root-relative links,
97
+ and publishing paths.
96
98
 
97
99
  ## Selecting The Site Directory
98
100
 
@@ -141,4 +143,3 @@ site:
141
143
  - `examples/`: complete sites and focused feature demonstrations;
142
144
  - `fixtures/`: engine regression input;
143
145
  - root `site/`: the Norna introduction and documentation site.
144
-