@janga/norna 0.7.9 → 0.7.10

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 (198) hide show
  1. package/README.md +1 -1
  2. package/docs/README.md +14 -11
  3. package/docs/configuration.md +9 -54
  4. package/docs/content.md +6 -7
  5. package/docs/design/norna-diagram-design.md +2 -0
  6. package/docs/getting-started.md +18 -16
  7. package/docs/routes.md +7 -6
  8. package/docs/site-structure.md +4 -2
  9. package/docs/sitewide-content.md +74 -0
  10. package/docs/theme.md +61 -128
  11. package/docs/typography.md +45 -33
  12. package/examples/001-dog-shelter-single-page/README.md +9 -0
  13. package/examples/001-dog-shelter-single-page/site/config.mjs +27 -0
  14. package/examples/001-dog-shelter-single-page/site/content.md +38 -0
  15. package/examples/001-dog-shelter-single-page/site/images/what-we-do/dog-house.svg +25 -0
  16. package/examples/001-dog-shelter-single-page/site/images/you-can-help/heart.svg +13 -0
  17. package/examples/001-dog-shelter-single-page/site/public/favicon.svg +10 -0
  18. package/examples/001-dog-shelter-single-page/site/public/robots.txt +2 -0
  19. package/examples/001-dog-shelter-single-page/site/sitewide-content.md +6 -0
  20. package/examples/001-dog-shelter-single-page/site/theme.md +25 -0
  21. package/examples/002-dog-shelter-multi-page/README.md +9 -0
  22. package/examples/002-dog-shelter-multi-page/site/config.mjs +27 -0
  23. package/examples/002-dog-shelter-multi-page/site/content.md +12 -0
  24. package/examples/002-dog-shelter-multi-page/site/public/favicon.svg +10 -0
  25. package/examples/002-dog-shelter-multi-page/site/public/robots.txt +2 -0
  26. package/examples/002-dog-shelter-multi-page/site/routes/010-dogs/images/dogs/rex.svg +19 -0
  27. package/examples/002-dog-shelter-multi-page/site/routes/010-dogs/images/dogs/rover.svg +19 -0
  28. package/examples/002-dog-shelter-multi-page/site/routes/010-dogs/route-content.md +30 -0
  29. package/examples/002-dog-shelter-multi-page/site/routes/020-adopt/route-content.md +12 -0
  30. package/examples/002-dog-shelter-multi-page/site/sitewide-content.md +6 -0
  31. package/examples/002-dog-shelter-multi-page/site/theme.md +25 -0
  32. package/examples/dog-gallery/.astro/collections/site.schema.json +776 -0
  33. package/examples/dog-gallery/.astro/collections/theme.schema.json +672 -0
  34. package/examples/dog-gallery/.astro/content-assets.mjs +4 -0
  35. package/examples/dog-gallery/.astro/content-modules.mjs +1 -0
  36. package/examples/dog-gallery/.astro/content.d.ts +175 -0
  37. package/examples/dog-gallery/.astro/data-store.json +1 -0
  38. package/examples/dog-gallery/.astro/dev-local.json +8 -0
  39. package/examples/dog-gallery/.astro/dev.json +13 -0
  40. package/examples/dog-gallery/.astro/dev.log +95 -0
  41. package/examples/dog-gallery/.astro/settings.json +5 -0
  42. package/examples/dog-gallery/.astro/types.d.ts +2 -0
  43. package/examples/dog-gallery/dist/_astro/GalleryGrid.astro_astro_type_script_index_0_lang.B0kxDyGz.js +1 -0
  44. package/examples/dog-gallery/dist/_astro/SitePage.DicGh_5N.css +1 -0
  45. package/examples/dog-gallery/dist/dog-care/index.html +15 -0
  46. package/examples/dog-gallery/dist/dog-shelter-logo.svg +14 -0
  47. package/examples/dog-gallery/dist/favicon.svg +7 -0
  48. package/examples/dog-gallery/dist/images/generated/black-dogs/black-puppy-meadow-7255e3d9-1080.webp +0 -0
  49. package/examples/dog-gallery/dist/images/generated/black-dogs/black-puppy-meadow-7255e3d9-1440.webp +0 -0
  50. package/examples/dog-gallery/dist/images/generated/black-dogs/black-puppy-meadow-7255e3d9-1536.webp +0 -0
  51. package/examples/dog-gallery/dist/images/generated/black-dogs/black-puppy-meadow-7255e3d9-480.webp +0 -0
  52. package/examples/dog-gallery/dist/images/generated/black-dogs/black-puppy-meadow-7255e3d9-768.webp +0 -0
  53. package/examples/dog-gallery/dist/images/generated/black-dogs/photo-of-a-black-dog-5cf614d2-480.webp +0 -0
  54. package/examples/dog-gallery/dist/images/generated/black-dogs/photo-of-a-black-dog-5cf614d2-768.webp +0 -0
  55. package/examples/dog-gallery/dist/images/generated/black-dogs/photo-of-a-black-dog-5cf614d2-960.webp +0 -0
  56. package/examples/dog-gallery/dist/images/generated/brown-dogs/brown-dog-50ef114e-1080.webp +0 -0
  57. package/examples/dog-gallery/dist/images/generated/brown-dogs/brown-dog-50ef114e-1440.webp +0 -0
  58. package/examples/dog-gallery/dist/images/generated/brown-dogs/brown-dog-50ef114e-1920.webp +0 -0
  59. package/examples/dog-gallery/dist/images/generated/brown-dogs/brown-dog-50ef114e-3939.webp +0 -0
  60. package/examples/dog-gallery/dist/images/generated/brown-dogs/brown-dog-50ef114e-480.webp +0 -0
  61. package/examples/dog-gallery/dist/images/generated/brown-dogs/brown-dog-50ef114e-768.webp +0 -0
  62. package/examples/dog-gallery/dist/images/generated/brown-dogs/dog-accompanies-master-7ef804d5-1080.webp +0 -0
  63. package/examples/dog-gallery/dist/images/generated/brown-dogs/dog-accompanies-master-7ef804d5-1440.webp +0 -0
  64. package/examples/dog-gallery/dist/images/generated/brown-dogs/dog-accompanies-master-7ef804d5-1920.webp +0 -0
  65. package/examples/dog-gallery/dist/images/generated/brown-dogs/dog-accompanies-master-7ef804d5-2400.webp +0 -0
  66. package/examples/dog-gallery/dist/images/generated/brown-dogs/dog-accompanies-master-7ef804d5-480.webp +0 -0
  67. package/examples/dog-gallery/dist/images/generated/brown-dogs/dog-accompanies-master-7ef804d5-768.webp +0 -0
  68. package/examples/dog-gallery/dist/images/generated/golden-dogs/golden-retriever-f797fd88-1080.webp +0 -0
  69. package/examples/dog-gallery/dist/images/generated/golden-dogs/golden-retriever-f797fd88-1440.webp +0 -0
  70. package/examples/dog-gallery/dist/images/generated/golden-dogs/golden-retriever-f797fd88-1600.webp +0 -0
  71. package/examples/dog-gallery/dist/images/generated/golden-dogs/golden-retriever-f797fd88-480.webp +0 -0
  72. package/examples/dog-gallery/dist/images/generated/golden-dogs/golden-retriever-f797fd88-768.webp +0 -0
  73. package/examples/dog-gallery/dist/images/generated/golden-dogs/toller-puppy-a2a8fbc0-1080.webp +0 -0
  74. package/examples/dog-gallery/dist/images/generated/golden-dogs/toller-puppy-a2a8fbc0-1440.webp +0 -0
  75. package/examples/dog-gallery/dist/images/generated/golden-dogs/toller-puppy-a2a8fbc0-1920.webp +0 -0
  76. package/examples/dog-gallery/dist/images/generated/golden-dogs/toller-puppy-a2a8fbc0-2576.webp +0 -0
  77. package/examples/dog-gallery/dist/images/generated/golden-dogs/toller-puppy-a2a8fbc0-480.webp +0 -0
  78. package/examples/dog-gallery/dist/images/generated/golden-dogs/toller-puppy-a2a8fbc0-768.webp +0 -0
  79. package/examples/dog-gallery/dist/images/generated/white-dogs/white-cute-dog-077a0689-1080.webp +0 -0
  80. package/examples/dog-gallery/dist/images/generated/white-dogs/white-cute-dog-077a0689-1277.webp +0 -0
  81. package/examples/dog-gallery/dist/images/generated/white-dogs/white-cute-dog-077a0689-480.webp +0 -0
  82. package/examples/dog-gallery/dist/images/generated/white-dogs/white-cute-dog-077a0689-768.webp +0 -0
  83. package/examples/dog-gallery/dist/images/generated/white-dogs/white-puppy-garden-d3ab2ca0-1080.webp +0 -0
  84. package/examples/dog-gallery/dist/images/generated/white-dogs/white-puppy-garden-d3ab2ca0-1440.webp +0 -0
  85. package/examples/dog-gallery/dist/images/generated/white-dogs/white-puppy-garden-d3ab2ca0-1536.webp +0 -0
  86. package/examples/dog-gallery/dist/images/generated/white-dogs/white-puppy-garden-d3ab2ca0-480.webp +0 -0
  87. package/examples/dog-gallery/dist/images/generated/white-dogs/white-puppy-garden-d3ab2ca0-768.webp +0 -0
  88. package/examples/dog-gallery/dist/index.html +45 -0
  89. package/examples/dog-gallery/dist/robots.txt +2 -0
  90. package/examples/dog-gallery/node_modules/.vite/deps/_metadata.json +7 -7
  91. package/examples/dog-gallery/site/.norna/generated-images.json +8 -8
  92. package/examples/dog-gallery/site/config.mjs +0 -20
  93. package/examples/dog-gallery/site/content.md +4 -5
  94. package/examples/dog-gallery/site/public/logo.svg +14 -0
  95. package/examples/dog-gallery/site/sitewide-content.md +16 -0
  96. package/examples/dog-gallery/site/theme.md +13 -24
  97. package/examples/presentation/README.md +15 -0
  98. package/examples/presentation/site/.norna/generated-images.json +66 -0
  99. package/examples/presentation/site/config.mjs +29 -0
  100. package/examples/presentation/site/content.md +67 -0
  101. package/examples/presentation/site/public/robots.txt +2 -0
  102. package/examples/presentation/site/routes/010-presets/route-content.md +63 -0
  103. package/examples/presentation/site/routes/010-presets/theme.md +4 -0
  104. package/examples/presentation/site/routes/020-media/images/cards/card-carousel.svg +11 -0
  105. package/examples/presentation/site/routes/020-media/images/cards/card-stack.svg +9 -0
  106. package/examples/presentation/site/routes/020-media/images/cards/card-surfaces.svg +8 -0
  107. package/examples/presentation/site/routes/020-media/images/carousel/carousel-one.svg +8 -0
  108. package/examples/presentation/site/routes/020-media/images/carousel/carousel-three.svg +13 -0
  109. package/examples/presentation/site/routes/020-media/images/carousel/carousel-two.svg +8 -0
  110. package/examples/presentation/site/routes/020-media/images/stack/stack-one.svg +8 -0
  111. package/examples/presentation/site/routes/020-media/images/stack/stack-two.svg +9 -0
  112. package/examples/presentation/site/routes/020-media/route-content.md +77 -0
  113. package/examples/presentation/site/routes/020-media/theme.md +4 -0
  114. package/examples/presentation/site/routes/030-surfaces/route-content.md +44 -0
  115. package/examples/presentation/site/routes/030-surfaces/theme.md +7 -0
  116. package/examples/presentation/site/sitewide-content.md +6 -0
  117. package/examples/presentation/site/theme.md +43 -0
  118. package/examples/typography-presets/.astro/collections/routeTheme.schema.json +746 -0
  119. package/examples/typography-presets/.astro/collections/site.schema.json +0 -717
  120. package/examples/typography-presets/.astro/collections/sitewide.schema.json +114 -0
  121. package/examples/typography-presets/.astro/collections/theme.schema.json +161 -59
  122. package/examples/typography-presets/.astro/content.d.ts +8 -0
  123. package/examples/typography-presets/.astro/data-store.json +1 -1
  124. package/examples/typography-presets/.astro/dev-local.json +2 -2
  125. package/examples/typography-presets/.astro/dev.json +2 -2
  126. package/examples/typography-presets/.astro/dev.log +37 -16
  127. package/examples/typography-presets/site/.norna/generated-images.json +76 -76
  128. package/examples/typography-presets/site/config.mjs +0 -13
  129. package/examples/typography-presets/site/content.md +8 -126
  130. package/examples/typography-presets/site/routes/010-quiet-gallery/route-content.md +34 -0
  131. package/examples/typography-presets/site/routes/010-quiet-gallery/theme.md +4 -0
  132. package/examples/typography-presets/site/routes/020-compact-gallery/route-content.md +33 -0
  133. package/examples/typography-presets/site/routes/020-compact-gallery/theme.md +4 -0
  134. package/examples/typography-presets/site/routes/030-text-forward/route-content.md +34 -0
  135. package/examples/typography-presets/site/routes/030-text-forward/theme.md +4 -0
  136. package/examples/typography-presets/site/routes/040-statement/route-content.md +34 -0
  137. package/examples/typography-presets/site/routes/040-statement/theme.md +4 -0
  138. package/examples/typography-presets/site/sitewide-content.md +14 -0
  139. package/examples/typography-presets/site/theme.md +9 -9
  140. package/fixtures/basic/site/config.mjs +0 -13
  141. package/fixtures/basic/site/sitewide-content.md +12 -0
  142. package/fixtures/basic/site/theme.md +2 -2
  143. package/fixtures/content-model-v2/site/content.md +2 -5
  144. package/fixtures/content-model-v2/site/theme.md +1 -3
  145. package/package.json +3 -2
  146. package/scripts/check-config.mjs +22 -1
  147. package/scripts/lib/frontmatter-yaml.mjs +28 -0
  148. package/scripts/lib/logo-assets.mjs +35 -0
  149. package/scripts/lib/norna-markdown-blocks.mjs +166 -0
  150. package/scripts/lib/presentation.mjs +104 -46
  151. package/scripts/lib/project-config.mjs +67 -105
  152. package/scripts/lib/site-content.mjs +26 -118
  153. package/scripts/lib/site-paths.mjs +2 -0
  154. package/scripts/lib/sitewide-config.mjs +34 -0
  155. package/scripts/lib/theme-config.mjs +72 -8
  156. package/scripts/lib/typography.mjs +20 -26
  157. package/scripts/show-typography.mjs +40 -147
  158. package/scripts/sync-content-sections.mjs +19 -17
  159. package/scripts/test-content-check.mjs +59 -27
  160. package/scripts/test-content-model-v2.mjs +154 -0
  161. package/scripts/test-engine-commands.mjs +3 -1
  162. package/scripts/test-package-check.mjs +66 -24
  163. package/scripts/test-temporary-visibility.mjs +19 -2
  164. package/src/components/CardList.astro +5 -2
  165. package/src/components/GalleryGrid.astro +37 -16
  166. package/src/components/SiteBanners.astro +100 -0
  167. package/src/components/SiteNavigation.astro +48 -31
  168. package/src/components/SitePage.astro +55 -13
  169. package/src/components/SiteSection.astro +193 -35
  170. package/src/content.config.ts +78 -48
  171. package/src/layouts/BaseLayout.astro +64 -14
  172. package/src/lib/routeThemes.ts +61 -0
  173. package/src/lib/sectionContent.ts +235 -51
  174. package/src/lib/sitePublicAssets.ts +1 -0
  175. package/src/styles/global.css +282 -93
  176. package/starters/basic/.github/workflows/deploy.yml +1 -1
  177. package/starters/basic/README.md +7 -6
  178. package/starters/basic/site/config.mjs +0 -13
  179. package/starters/basic/site/content.md +1 -1
  180. package/starters/basic/site/sitewide-content.md +14 -0
  181. package/starters/basic/site/theme.md +13 -24
  182. package/starters/project/.github/workflows/deploy.yml +1 -1
  183. package/starters/project/README.md +10 -8
  184. package/starters/project/site/config.mjs +0 -13
  185. package/starters/project/site/sitewide-content.md +14 -0
  186. package/starters/project/site/theme.md +3 -11
  187. /package/examples/typography-presets/site/{images → routes/010-quiet-gallery/images}/quiet-gallery/puppy-portrait.jpg +0 -0
  188. /package/examples/typography-presets/site/{images → routes/010-quiet-gallery/images}/quiet-gallery/shepherd-portrait.jpg +0 -0
  189. /package/examples/typography-presets/site/{images → routes/010-quiet-gallery/images}/quiet-gallery/white-puppy.jpg +0 -0
  190. /package/examples/typography-presets/site/{images → routes/020-compact-gallery/images}/compact-gallery/black-schnauzer.jpg +0 -0
  191. /package/examples/typography-presets/site/{images → routes/020-compact-gallery/images}/compact-gallery/retriever-portrait.jpg +0 -0
  192. /package/examples/typography-presets/site/{images → routes/020-compact-gallery/images}/compact-gallery/schnauzer-portrait.jpg +0 -0
  193. /package/examples/typography-presets/site/{images → routes/030-text-forward/images}/text-forward/boxer-portrait.jpg +0 -0
  194. /package/examples/typography-presets/site/{images → routes/030-text-forward/images}/text-forward/grass-puppy.jpg +0 -0
  195. /package/examples/typography-presets/site/{images → routes/030-text-forward/images}/text-forward/grey-street-dog.jpg +0 -0
  196. /package/examples/typography-presets/site/{images → routes/040-statement/images}/statement/black-pedigree.jpg +0 -0
  197. /package/examples/typography-presets/site/{images → routes/040-statement/images}/statement/sheepdog-grass.jpg +0 -0
  198. /package/examples/typography-presets/site/{images → routes/040-statement/images}/statement/sheepdog-wide.jpg +0 -0
package/README.md CHANGED
@@ -24,7 +24,7 @@ A `norna` site is file-driven:
24
24
  2. The site keeps technical settings, including public URL and optional URL
25
25
  base path, in `site/config.mjs`.
26
26
  3. The site keeps site-wide visual theme defaults, including layout, image
27
- sizing, font, typography, colors, and frame colors, in `site/theme.md`.
27
+ sizing, font, typography, palettes, and section surfaces, in `site/theme.md`.
28
28
  4. The site keeps homepage content, Markdown section order, managed media
29
29
  blocks, alt text, captions, and optional section metadata in
30
30
  `site/content.md`.
package/docs/README.md CHANGED
@@ -10,13 +10,14 @@ For a site maintainer:
10
10
  1. [Getting Started](getting-started.md)
11
11
  2. [Site Structure](site-structure.md)
12
12
  3. [Theme](theme.md)
13
- 4. [Configuration](configuration.md)
14
- 5. [Content](content.md)
15
- 6. [Typography](typography.md)
16
- 7. [Routes](routes.md)
17
- 8. [Images And Metadata](images-and-metadata.md)
18
- 9. [Local Development](local-development.md)
19
- 10. [Publishing](publishing.md)
13
+ 4. [Sitewide Content](sitewide-content.md)
14
+ 5. [Configuration](configuration.md)
15
+ 6. [Content](content.md)
16
+ 7. [Typography](typography.md)
17
+ 8. [Routes](routes.md)
18
+ 9. [Images And Metadata](images-and-metadata.md)
19
+ 10. [Local Development](local-development.md)
20
+ 11. [Publishing](publishing.md)
20
21
 
21
22
  For a developer integrating or updating the engine:
22
23
 
@@ -37,13 +38,15 @@ For design and naming principles:
37
38
  For a quick reference:
38
39
 
39
40
  - [Configuration](configuration.md) describes technical `site/config.mjs`
40
- fields such as URL, base path, locale labels, footer, GitHub, and deploy
41
+ fields such as URL, base path, locale labels, GitHub, and deploy
41
42
  settings.
43
+ - [Sitewide Content](sitewide-content.md) describes shared site identity, banners
44
+ and footer content in `site/sitewide-content.md`.
42
45
  - [Content](content.md) describes page frontmatter, Markdown-authored
43
- sections, optional section metadata, managed media blocks, temporary
44
- sections, and content validation.
46
+ sections, optional section metadata, managed media blocks, temporary sections,
47
+ and content validation.
45
48
  - [Theme](theme.md) describes site-wide layout, layout density, image sizing,
46
- font, typography rhythm, presentation colors, frame colors, and inline styles.
49
+ font, typography rhythm, presentation palettes, and section surfaces.
47
50
  - [Typography](typography.md) describes presets, rhythms, roles, overrides,
48
51
  inheritance, and inspection commands.
49
52
  - [Routes](routes.md) describes route files, slugs, route navigation, and
@@ -72,7 +72,7 @@ Use [Theme](theme.md) for:
72
72
  - `gallery.maxAvailableHeightPercent`
73
73
  - `typography.fontFamily`
74
74
  - typography presets, rhythm, and overrides
75
- - presentation colors, inline styles, and frame colors
75
+ - presentation palettes and section surfaces
76
76
 
77
77
  ## Navigation
78
78
 
@@ -141,6 +141,10 @@ Fields:
141
141
  `Sections`.
142
142
  - `locale.labels.menu`: mobile menu summary text, default `Menu`.
143
143
  - `locale.labels.closeMenu`: reserved close-menu label, default `Close menu`.
144
+ - `locale.labels.dismissBanner`: banner dismissal button label, default
145
+ `Dismiss notice`.
146
+ - `locale.labels.siteBanners`: ARIA label for the banner stack, default
147
+ `Site notices`.
144
148
  - `locale.labels.gallery`: Norna managed media ARIA label prefix, default
145
149
  `Images`.
146
150
 
@@ -160,60 +164,11 @@ locale: {
160
164
  }
161
165
  ```
162
166
 
163
- ## Footer
167
+ ## Sitewide Content
164
168
 
165
- ### `footer.copyrightMessage`
166
-
167
- - Purpose: optional footer sentence.
168
- - Type: string.
169
- - Required: no.
170
- - Default: hidden.
171
- - Validation: if set, it must be a non-empty string. `undefined`, `null`, and
172
- `''` are treated as absent.
173
- - Consequence: footer rendering is enabled when this or enabled build info is
174
- present.
175
-
176
- ### `footer.buildInfo`
177
-
178
- - Purpose: optional footer build timestamp.
179
- - Type: object, `false`, `null`, or omitted.
180
- - Required: no.
181
- - Default: hidden.
182
- - Validation: object fields are validated when the object is present. `false`,
183
- `null`, or omission hides build info.
184
-
185
- Fields:
186
-
187
- - `footer.buildInfo.enabled`: boolean, default `true`.
188
- - `footer.buildInfo.text`: required non-empty string.
189
- - `footer.buildInfo.dateTimeFormat`: required object.
190
- - `footer.buildInfo.dateTimeFormat.locale`: required string.
191
- - `footer.buildInfo.dateTimeFormat.timeZone`: required string.
192
- - `footer.buildInfo.dateTimeFormat.dateStyle`: required string.
193
- - `footer.buildInfo.dateTimeFormat.timeStyle`: required string.
194
-
195
- The date/time object must be accepted by `Intl.DateTimeFormat`.
196
-
197
- Example:
198
-
199
- ```js
200
- footer: {
201
- copyrightMessage: '(c) Example Artist.',
202
- buildInfo: {
203
- enabled: true,
204
- text: 'Built',
205
- dateTimeFormat: {
206
- locale: 'en-GB',
207
- timeZone: 'UTC',
208
- dateStyle: 'short',
209
- timeStyle: 'short',
210
- },
211
- },
212
- }
213
- ```
214
-
215
- If both `footer.copyrightMessage` and enabled `footer.buildInfo` are absent, the
216
- footer is not rendered.
169
+ Shared site identity, banners and footer content are defined in
170
+ `site/sitewide-content.md`. See [Sitewide Content](sitewide-content.md) for the
171
+ schema and examples.
217
172
 
218
173
  ## GitHub
219
174
 
package/docs/content.md CHANGED
@@ -18,9 +18,6 @@ The Astro content schema validates these top-level fields in page files:
18
18
  - `title`: required string. Rendered as the document title.
19
19
  - `description`: required string. Rendered as the meta description.
20
20
  - `navigation`: optional page navigation metadata. See [Routes](routes.md).
21
- - `presentation`: optional page-level presentation overrides. See
22
- [Theme](theme.md) and [Typography](typography.md).
23
- - `frame`: optional page-level frame color source. See [Theme](theme.md).
24
21
  - `sections`: optional section metadata keyed by section id.
25
22
 
26
23
  Minimal homepage:
@@ -71,16 +68,18 @@ current section, not new sections.
71
68
  ## Section Metadata
72
69
 
73
70
  Use `sections` only when a section needs structured metadata that is not
74
- naturally expressed by Markdown, such as visibility or presentation overrides.
71
+ naturally expressed by Markdown. Currently this is date-based visibility.
75
72
 
76
73
  ```yaml
77
74
  sections:
78
75
  work:
79
- presentation:
80
- typography:
81
- preset: statement
76
+ visible:
77
+ from: "2026-08-01"
78
+ until: "2026-09-16"
82
79
  ```
83
80
 
81
+ See [Temporary Sections](#temporary-sections) for visibility semantics.
82
+
84
83
  Each `sections.<section-id>` key must match a Markdown heading id in the same
85
84
  page file:
86
85
 
@@ -67,6 +67,8 @@ Diagrams must match the current Norna model:
67
67
 
68
68
  - A Norna site is described with site files, not arbitrary project structure.
69
69
  - `content.md` is the homepage content file.
70
+ - `sitewide-content.md` contains shared site identity, banners, and footer
71
+ content.
70
72
  - Additional pages are route directories with `route-content.md`.
71
73
  - Route folder prefixes control route presentation order.
72
74
  - Route ids become default URL slugs.
@@ -57,6 +57,7 @@ The starter contains:
57
57
  - `.github/workflows/deploy.yml` for GitHub Pages
58
58
  - `site/config.mjs`
59
59
  - `site/theme.md`
60
+ - `site/sitewide-content.md`
60
61
  - `site/content.md`
61
62
  - `site/public/robots.txt`
62
63
 
@@ -88,21 +89,22 @@ Relevant documentation: [Commands](commands.md), [Site Structure](site-structure
88
89
  ## First Edits
89
90
 
90
91
  1. Edit `site/config.mjs` for the site's URL, language labels, GitHub
91
- repository, footer, and deploy settings.
92
- 2. Edit `site/theme.md` for site-wide layout, layout density, typography
93
- rhythm, image sizing, font, typography preset, colors, inline styles, and
94
- frame colors, or omit it to use engine defaults.
95
- 3. Edit `site/content.md` for homepage title, description, Markdown sections,
96
- text, Norna managed media blocks, page/section presentation overrides, alt
97
- text, and captions.
98
- 4. Put source images under `site/images/<section-id>/`, where `<section-id>`
92
+ repository, and deploy settings.
93
+ 2. Edit `site/sitewide-content.md` for the shared brand or logo, banners and
94
+ footer content.
95
+ 3. Edit `site/theme.md` for site-wide layout, layout density, typography
96
+ rhythm, image sizing, font, typography preset, palettes, and section
97
+ surfaces, or omit it to use engine defaults.
98
+ 4. Edit `site/content.md` for homepage title, description, Markdown sections,
99
+ text, Norna managed media blocks, alt text, and captions.
100
+ 5. Put source images under `site/images/<section-id>/`, where `<section-id>`
99
101
  matches a `## Section {#section-id}` heading in `site/content.md`.
100
- 5. Add optional route pages under
102
+ 6. Add optional route pages under
101
103
  `site/routes/<NNN-route-id>/route-content.md`, for example
102
104
  `site/routes/010-about/route-content.md`.
103
- 6. Put static files such as `robots.txt`, `CNAME`, and favicons under
105
+ 7. Put static files such as `robots.txt`, `CNAME`, and favicons under
104
106
  `site/public/`.
105
- 7. Run:
107
+ 8. Run:
106
108
 
107
109
  ```sh
108
110
  npm run norna:config:check
@@ -158,12 +160,12 @@ Read [Site Structure](site-structure.md), [Content](content.md),
158
160
  [Configuration](configuration.md) before publishing a real site.
159
161
 
160
162
  To change the site's maximum page width, side gutters, layout density,
161
- typography rhythm, image width, image height limits, font, colors, or
163
+ typography rhythm, image width, image height limits, font, palettes, or
162
164
  site-wide typography preset, edit `site/theme.md`. See [Theme](theme.md) for
163
165
  the accepted shape.
164
166
 
165
- To change one page or section, add a focused `presentation.typography`
166
- override in `site/content.md`. See [Typography](typography.md). Use
167
- `norna typography presets` to inspect the installed preset and rhythm values and
168
- `norna typography show` to inspect the resolved typography for the selected
167
+ To give a route a different visual expression, add a complete route-local
168
+ `theme.md`. See [Theme](theme.md#route-themes) and [Typography](typography.md).
169
+ Use `norna typography presets` to inspect the installed preset and rhythm values
170
+ and `norna typography show` to inspect the resolved typography for the selected
169
171
  site.
package/docs/routes.md CHANGED
@@ -4,14 +4,15 @@
4
4
  under `site/routes/<NNN-route-id>/route-content.md` and build to first-level
5
5
  URLs.
6
6
 
7
- Routes use the same page frontmatter, optional section metadata, Norna managed
8
- media blocks, and Markdown section model as the homepage. See
9
- [Content](content.md) for the page and section model.
7
+ Routes use the same page frontmatter, optional section metadata, Norna-managed
8
+ media blocks, and Markdown section model as the homepage. See [Content](content.md)
9
+ for the page and section model.
10
10
 
11
11
  Route directories can contain route content, route-local images, and
12
- route-local presentation overrides in `route-content.md`. They cannot contain
13
- technical site configuration; technical configuration stays at the selected
14
- site directory's top-level `config.mjs`.
12
+ an optional route-local `theme.md`. The route theme replaces the root visual
13
+ theme for that route. Route directories cannot contain technical site
14
+ configuration; technical configuration stays in the selected site directory's
15
+ top-level `config.mjs`.
15
16
 
16
17
  ## Route Directory Format
17
18
 
@@ -11,6 +11,7 @@ The selected site directory defaults to `site/`:
11
11
  site/
12
12
  |-- config.mjs
13
13
  |-- theme.md
14
+ |-- sitewide-content.md
14
15
  |-- content.md
15
16
  |-- images/
16
17
  | `-- <section-id>/
@@ -38,9 +39,10 @@ Version these files in a site repository:
38
39
 
39
40
  - `site/config.mjs`: technical site configuration.
40
41
  - `site/theme.md`: optional site-wide visual theme, including layout, spacing,
41
- image sizing, font, typography defaults, colors, inline styles, and frame
42
- colors.
42
+ image sizing, font, typography defaults, palettes, and section surfaces.
43
43
  See [Theme](theme.md).
44
+ - `site/sitewide-content.md`: shared site identity, banners and footer content.
45
+ See [Sitewide Content](sitewide-content.md).
44
46
  - `site/content.md`: homepage page file with editable content, Markdown
45
47
  sections, optional section metadata, managed media blocks, alt text, and
46
48
  captions.
@@ -0,0 +1,74 @@
1
+ # Sitewide Content
2
+
3
+ `site/sitewide-content.md` contains content and settings shared by the whole site. It
4
+ is separate from `content.md`, which defines the homepage, and from
5
+ `config.mjs`, which defines technical behaviour.
6
+
7
+ ## Site identity
8
+
9
+ Use the optional `navigation` object for identity shared by all pages. `brand`
10
+ is the text shown in the home link when no logo is present. A logo is discovered
11
+ from one convention-based file in `site/public`: `logo.svg`, `logo.png`,
12
+ `logo.jpg`, or `logo.jpeg`.
13
+
14
+ ```yaml
15
+ navigation:
16
+ brand: Example Site
17
+ logo:
18
+ alt: Example Site
19
+ height: 2.6rem
20
+ ```
21
+
22
+ If `navigation.brand` is omitted, Norna uses the homepage `title` from
23
+ `site/content.md`. The logo's width is derived from its intrinsic aspect ratio.
24
+ If both a logo and a brand are present, the logo is displayed and the brand is
25
+ used as its text fallback and accessible default.
26
+
27
+ ## Banners
28
+
29
+ Use `banners` for short notices shown above the page content on every route.
30
+ The list order controls the presentation order. Each banner needs a unique
31
+ `id`, a title and text:
32
+
33
+ ```yaml
34
+ ---
35
+ banners:
36
+ - id: project-status
37
+ tone: warning
38
+ visible:
39
+ from: "2026-08-01"
40
+ until: "2026-09-01"
41
+ title: Experimental code
42
+ text: Not for production use.
43
+ ---
44
+ ```
45
+
46
+ `visible` uses the same date-window rules as temporary sections. Visitors can
47
+ dismiss individual active banners. The dismissal is stored locally in the
48
+ browser and is tied to the banner content, so an edited banner can appear
49
+ again.
50
+
51
+ The first version supports the `warning` tone. Keep banner text short; banners
52
+ are presented as compact single-line notices and may use an ellipsis when the
53
+ text does not fit.
54
+
55
+ ## Footer
56
+
57
+ The footer is also sitewide content. `copyrightMessage` adds a copyright or
58
+ license sentence. `buildInfo` optionally adds a generated build timestamp:
59
+
60
+ ```yaml
61
+ footer:
62
+ copyrightMessage: (c) Example Artist.
63
+ buildInfo:
64
+ enabled: true
65
+ text: Built
66
+ dateTimeFormat:
67
+ locale: en-GB
68
+ timeZone: UTC
69
+ dateStyle: short
70
+ timeStyle: short
71
+ ```
72
+
73
+ If both the copyright message and enabled build information are absent, the
74
+ footer is not rendered.
package/docs/theme.md CHANGED
@@ -1,20 +1,19 @@
1
1
  # Theme
2
2
 
3
- `site/theme.md` defines optional site-wide visual defaults for a `norna` site.
4
- It uses YAML frontmatter and does not need a Markdown body. If the file is
5
- missing, built-in engine defaults are used.
3
+ `site/theme.md` defines the site-wide visual theme for a `norna` site. It uses
4
+ YAML frontmatter and does not need a Markdown body. The root theme file is
5
+ required, but every setting inside it is optional and falls back to an engine
6
+ default.
6
7
 
7
- Page-level presentation in `site/content.md` and route page files is always an
8
- override on top of `site/theme.md`. Section-level presentation is an override
9
- on top of the resolved page presentation. Use those overrides for focused
10
- exceptions; the normal place for shared visual choices is `site/theme.md`.
8
+ An optional `theme.md` inside a route directory replaces the root visual theme
9
+ for that route. Route themes do not merge with the root theme: omitted values
10
+ use engine defaults. Shared identity such as brand and logo remains site-wide
11
+ and belongs in `sitewide-content.md`.
11
12
 
12
13
  ## Minimal Theme
13
14
 
14
15
  ```yaml
15
16
  ---
16
- navigation:
17
- brand: Example Site
18
17
  layout:
19
18
  density: normal
20
19
  pageWidth: 1180px
@@ -34,10 +33,10 @@ typography:
34
33
  preset: quiet-gallery
35
34
  rhythm: normal
36
35
  presentation:
37
- backgroundColor: "#000000"
38
- textColor: "#f7f4ee"
39
- frame:
40
- colors: presentation
36
+ palette: dark # Alternatives: light, paper
37
+ sectionSurfaces:
38
+ mode: cycle
39
+ sequence: [base, soft, emphasis]
41
40
  ---
42
41
  ```
43
42
 
@@ -46,23 +45,8 @@ Starter sites include a marked comment block such as
46
45
  explorable help text; YAML comments do not affect rendering. The active
47
46
  configuration is the uncommented YAML below it.
48
47
 
49
- ## Navigation
50
-
51
- `navigation` is optional. It currently supports:
52
-
53
- - `brand`: optional site-wide brand or home-link text shown in the site
54
- navigation.
55
-
56
- If `navigation.brand` is omitted, Norna uses the homepage `title` from
57
- `site/content.md`. Use `navigation.brand` when the homepage title is editorial
58
- or route-specific, but the navigation should keep a stable site name.
59
-
60
- Example:
61
-
62
- ```yaml
63
- navigation:
64
- brand: Norna
65
- ```
48
+ Site identity is not part of the visual theme. Define the optional navigation
49
+ brand and logo settings in `site/sitewide-content.md`; see [Sitewide Content](sitewide-content.md).
66
50
 
67
51
  ## Layout
68
52
 
@@ -74,9 +58,9 @@ navigation:
74
58
  `desktop` / `mobile` values.
75
59
  - `density`: default structural spacing profile. Allowed values are `compact`,
76
60
  `normal`, and `airy`.
77
- - `spacing`: optional structural spacing overrides for sections and Norna
78
- managed media blocks. Every spacing value accepts either one CSS length for all
79
- viewports or `desktop` / `mobile` values.
61
+ - `spacing`: optional spacing overrides for sections and content blocks. Every
62
+ spacing value accepts either one CSS length for all viewports or `desktop` /
63
+ `mobile` values.
80
64
 
81
65
  Example:
82
66
 
@@ -94,6 +78,12 @@ layout:
94
78
  sectionGap:
95
79
  desktop: clamp(1.4rem, 3vw, 2.75rem)
96
80
  mobile: 1.5rem
81
+ headingToBlock:
82
+ desktop: 0.75em
83
+ mobile: 0.7em
84
+ blockGap:
85
+ desktop: 1.5em
86
+ mobile: 1.25em
97
87
  ```
98
88
 
99
89
  If omitted, Norna uses `1180px` for `pageWidth`, desktop
@@ -105,11 +95,20 @@ Spacing keys:
105
95
  - `firstSectionTop`: space above the first section heading.
106
96
  - `sectionGap`: space above each following section.
107
97
  - `finalSectionBottom`: space below the final section.
108
- - `bodyToImages`: space from section body text to Norna managed media blocks.
98
+ - `headingToBlock`: space between a section heading and its first visual content
99
+ block, such as an image stack, carousel, or card list.
100
+ - `blockGap`: space between content blocks in a section. It applies between
101
+ Markdown, image, carousel, and card-list blocks, but not after the final block.
109
102
  - `imageGap`: space between stacked images or carousel blocks.
110
103
 
111
- Text-near spacing, such as spacing after headings, spacing before Markdown
112
- subheadings, paragraph spacing, and caption spacing, belongs to
104
+ The default `compact`, `normal`, and `airy` density profiles provide values for
105
+ these spacing keys. The `em` values for `headingToBlock` and `blockGap` are
106
+ relative to the relevant text size, so the rhythm follows typography changes.
107
+ Use `sectionGap` and the other structural keys when the distance should describe
108
+ the page layout rather than the size of nearby text.
109
+
110
+ Text-near spacing inside Markdown, such as spacing after headings, spacing
111
+ before Markdown subheadings, paragraph spacing, and caption spacing, belongs to
113
112
  `typography.rhythm` and typography overrides.
114
113
 
115
114
  ## Image Sizing
@@ -153,18 +152,20 @@ Example:
153
152
  ```yaml
154
153
  typography:
155
154
  fontFamily: "Arial, 'Helvetica Neue', Helvetica, sans-serif"
156
- preset: quiet-gallery
155
+ preset: text-forward
157
156
  rhythm: normal
158
157
  overrides:
159
158
  headings:
160
159
  h2:
161
160
  size: medium
161
+ weight: 600
162
162
  spacingAfter: 0.55em
163
163
  h3:
164
164
  size: medium
165
165
  spacingBefore: 1.5em
166
166
  spacingAfter: 0.5em
167
167
  body:
168
+ width: narrow
168
169
  lineHeight: 1.55
169
170
  ```
170
171
 
@@ -174,107 +175,39 @@ selected site. See [Typography](typography.md).
174
175
 
175
176
  ## Presentation
176
177
 
177
- `presentation` is optional. It can contain:
178
+ `presentation` is optional. It selects a small built-in visual palette for the
179
+ page frame and defines how section surfaces are assigned:
178
180
 
179
- - `backgroundColor`: optional quoted hex color in `#rgb`, `#rrggbb`, or
180
- `#rrggbbaa` form.
181
- - `textColor`: optional quoted hex color in `#rgb`, `#rrggbb`, or
182
- `#rrggbbaa` form.
183
- - `inlineStyles`: optional named inline text styles.
181
+ - `palette`: `dark`, `light`, or `paper`. The palette controls the page,
182
+ navigation, footer, and section colors.
183
+ - `sectionSurfaces.mode`: `none` or `cycle`.
184
+ - `sectionSurfaces.sequence`: optional sequence of `base`, `soft`, and
185
+ `emphasis`. Each surface may occur at most once.
184
186
 
185
187
  Example:
186
188
 
187
189
  ```yaml
188
190
  presentation:
189
- backgroundColor: "#101418"
190
- textColor: "#f4f1ea"
191
- ```
192
-
193
- ## Page And Section Overrides
194
-
195
- Site-wide presentation belongs in `site/theme.md`. Page-level presentation in a
196
- page file is always an override on top of the theme:
197
-
198
- ```yaml
199
- presentation:
200
- typography:
201
- overrides:
202
- headings:
203
- h2:
204
- size: large
205
- spacingAfter: 0.6em
206
- body:
207
- paragraphSpacing: 1em
208
- ```
209
-
210
- Section-specific presentation belongs under
211
- `sections.<section-id>.presentation`. Use it when one section genuinely needs
212
- different presentation; do not use `sections` to define section order or normal
213
- Markdown structure.
214
-
215
- ```yaml
216
- sections:
217
- intro:
218
- presentation:
219
- backgroundColor: "#161616"
220
- textColor: "#ffffff"
221
- typography:
222
- preset: statement
223
- ```
224
-
225
- If a page omits `presentation`, it uses the theme presentation unchanged. If a
226
- section omits `presentation`, it uses the resolved page presentation.
227
-
228
- Configured section backgrounds render as full-width horizontal bands while the
229
- section content keeps the normal page and image widths. The top spacing
230
- before the first heading, the spacing between sections, and the spacing after
231
- the final section are part of the section background.
232
-
233
- Configured section text colors apply to section headings, Markdown text,
234
- Markdown subheadings, and image captions. Links keep the global accent color.
235
-
236
- ## Frame Colors
237
-
238
- `frame.colors` controls the sticky navigation and footer colors.
239
-
240
- Allowed values:
241
-
242
- - `presentation`: use the resolved presentation colors for this level.
243
- - `theme`: use the site theme frame colors. This is useful in page-level
244
- frontmatter.
245
- - explicit colors:
246
-
247
- ```yaml
248
- frame:
249
- colors:
250
- backgroundColor: "#111111"
251
- textColor: "#eeeeee"
191
+ palette: paper # Alternatives: dark, light
192
+ sectionSurfaces:
193
+ mode: cycle
194
+ sequence: [base, soft, emphasis]
252
195
  ```
253
196
 
254
- The sticky section navigation row and footer use the resolved frame colors, not
255
- section-specific presentation.
197
+ ## Route Themes
256
198
 
257
- ## Inline Styles
199
+ Add `theme.md` to a route directory when that route should have a different
200
+ visual expression:
258
201
 
259
- `presentation.inlineStyles` defines named inline text styles that can be used
260
- from Markdown:
261
-
262
- ```yaml
263
- presentation:
264
- inlineStyles:
265
- highlight:
266
- color: "#ffd84d"
202
+ ```text
203
+ site/routes/010-guide/theme.md
267
204
  ```
268
205
 
269
- Inline style names must match `^[a-z][a-z0-9-]*$`. Each style currently
270
- supports a required `color` field using the same quoted hex color format as
271
- `textColor`.
272
-
273
- Apply an inline style in Markdown with `[text]{.style-name}`:
274
-
275
- ```md
276
- This sentence contains [highlighted text]{.highlight}.
277
- ```
206
+ The route theme uses the same visual schema as the root theme. It completely
207
+ replaces the root visual theme for that route, so include every non-default
208
+ visual choice the route needs. It cannot define navigation, brand, logo, or
209
+ technical configuration.
278
210
 
279
- `content:check` fails if Markdown uses an inline style that is not defined in
280
- `site/theme.md` `presentation.inlineStyles`.
211
+ Section surfaces render as full-width horizontal bands while the section
212
+ content keeps the normal page and image widths. Links keep the palette's global
213
+ accent color.