@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
@@ -44,6 +44,9 @@
44
44
  --space-section-to-section-desktop: clamp(2.55rem, 4.2vw, 3.9rem);
45
45
  --space-section-to-section-mobile: 2.25rem;
46
46
  --space-section-to-section: var(--space-section-to-section-desktop);
47
+ --space-page-title-to-first-section-desktop: clamp(0.9rem, 1.6vw, 1.4rem);
48
+ --space-page-title-to-first-section-mobile: 0.9rem;
49
+ --space-page-title-to-first-section: var(--space-page-title-to-first-section-desktop);
47
50
  --space-final-section-bottom-desktop: var(--space-section-to-section-desktop);
48
51
  --space-final-section-bottom-mobile: var(--space-section-to-section-mobile);
49
52
  --space-final-section-bottom: var(--space-final-section-bottom-desktop);
@@ -193,13 +196,18 @@ a {
193
196
  }
194
197
 
195
198
  .site-nav a:hover,
199
+ .site-nav a:focus-visible,
196
200
  .site-nav a[aria-current='page'],
197
201
  .mobile-nav-panel a:hover,
202
+ .mobile-nav-panel a:focus-visible,
198
203
  .mobile-nav-panel a[aria-current='page'] {
199
204
  opacity: 1;
200
205
  }
201
206
 
202
- .site-nav a[aria-current='page'] {
207
+ .site-nav > ul > .site-nav-item > a:hover,
208
+ .site-nav > ul > .site-nav-item > a:focus-visible,
209
+ .site-nav > ul > .site-nav-item > a[aria-current='page'],
210
+ .site-nav > ul > .site-nav-item-current-branch > a {
203
211
  text-decoration: underline;
204
212
  text-decoration-thickness: 1px;
205
213
  text-underline-offset: 0.35em;
@@ -232,6 +240,20 @@ a {
232
240
  gap: 0.65rem;
233
241
  }
234
242
 
243
+ .site-nav-submenu .navigation-page-tree-submenu {
244
+ gap: 0.75rem;
245
+ }
246
+
247
+ .site-nav-submenu .navigation-page-tree-submenu .navigation-page-tree-submenu {
248
+ margin: 0.15rem 0 0 0.35rem;
249
+ border-left: 1px solid color-mix(in srgb, currentColor 24%, transparent);
250
+ padding-left: 0.75rem;
251
+ }
252
+
253
+ .site-nav-submenu .navigation-page-link {
254
+ font-weight: 650;
255
+ }
256
+
235
257
  .site-nav-submenu a {
236
258
  font-size: 0.76rem;
237
259
  letter-spacing: 0.03em;
@@ -242,7 +264,8 @@ a {
242
264
  }
243
265
 
244
266
  .site-nav-submenu a:hover,
245
- .site-nav-submenu a:focus-visible {
267
+ .site-nav-submenu a:focus-visible,
268
+ .site-nav-submenu a[aria-current='location'] {
246
269
  opacity: 1;
247
270
  text-decoration: underline;
248
271
  text-underline-offset: 0.25em;
@@ -256,6 +279,13 @@ a {
256
279
  transform: translate(-50%, 0);
257
280
  }
258
281
 
282
+ .site-nav-item[data-submenu-dismissed='true'] .site-nav-submenu {
283
+ opacity: 0;
284
+ visibility: hidden;
285
+ pointer-events: none;
286
+ transform: translate(-50%, -0.35rem);
287
+ }
288
+
259
289
  .mobile-nav-menu {
260
290
  display: none;
261
291
  }
@@ -264,10 +294,29 @@ a {
264
294
  border-top: 1px solid color-mix(in srgb, currentColor 14%, transparent);
265
295
  }
266
296
 
297
+ .page-nav-inner {
298
+ display: flex;
299
+ align-items: center;
300
+ justify-content: center;
301
+ gap: clamp(1.1rem, 2.5vw, 2rem);
302
+ width: min(calc(100% - (var(--content-gutter) * 2)), var(--page-width));
303
+ margin: 0 auto;
304
+ }
305
+
306
+ .page-nav-label {
307
+ flex: 0 0 auto;
308
+ font-size: 0.7rem;
309
+ font-weight: 650;
310
+ letter-spacing: 0.08em;
311
+ opacity: 0.55;
312
+ text-transform: uppercase;
313
+ white-space: nowrap;
314
+ }
315
+
267
316
  .page-nav ul {
268
317
  display: flex;
269
318
  flex-wrap: wrap;
270
- justify-content: center;
319
+ justify-content: flex-start;
271
320
  gap: 0 clamp(1.4rem, 4vw, 3.25rem);
272
321
  margin: 0;
273
322
  padding: 0;
@@ -302,14 +351,15 @@ a {
302
351
  }
303
352
 
304
353
  .page-nav a:hover,
305
- .page-nav a:focus-visible {
354
+ .page-nav a:focus-visible,
355
+ .page-nav a[aria-current='location'] {
306
356
  opacity: 1;
307
357
  text-decoration: underline;
308
358
  text-decoration-thickness: 1px;
309
359
  text-underline-offset: 0.35em;
310
360
  }
311
361
 
312
- .mobile-page-nav a[aria-current='true'] {
362
+ .mobile-nav-sections a[aria-current='location'] {
313
363
  opacity: 1;
314
364
  text-decoration: underline;
315
365
  text-decoration-thickness: 1px;
@@ -330,6 +380,56 @@ a {
330
380
  padding: 0;
331
381
  }
332
382
 
383
+ .site-breadcrumbs {
384
+ width: min(100%, 60ch, var(--text-width));
385
+ margin: 0 auto;
386
+ padding-top: clamp(1rem, 2.5vw, 1.5rem);
387
+ font-size: 1rem;
388
+ line-height: 1.4;
389
+ }
390
+
391
+ .site-breadcrumbs ol {
392
+ display: flex;
393
+ flex-wrap: wrap;
394
+ gap: 0;
395
+ margin: 0;
396
+ padding: 0;
397
+ font-size: 0.78rem;
398
+ list-style: none;
399
+ }
400
+
401
+ .site-breadcrumbs li {
402
+ display: flex;
403
+ align-items: center;
404
+ }
405
+
406
+ .site-breadcrumbs li + li::before {
407
+ margin: 0 0.55rem;
408
+ content: "/";
409
+ opacity: 0.38;
410
+ }
411
+
412
+ .site-breadcrumbs a {
413
+ color: inherit;
414
+ opacity: 0.72;
415
+ text-decoration: none;
416
+ }
417
+
418
+ .site-breadcrumbs a:hover,
419
+ .site-breadcrumbs a:focus-visible {
420
+ opacity: 1;
421
+ text-decoration: underline;
422
+ text-underline-offset: 0.25em;
423
+ }
424
+
425
+ .site-breadcrumbs [aria-current='page'] {
426
+ font-weight: 650;
427
+ }
428
+
429
+ .site-content-has-breadcrumbs > .site-section:first-of-type {
430
+ padding-top: clamp(1.15rem, 2.5vw, 1.75rem);
431
+ }
432
+
333
433
  .site-banners {
334
434
  position: relative;
335
435
  z-index: 2;
@@ -455,6 +555,18 @@ a {
455
555
  padding-top: var(--space-section-to-section);
456
556
  }
457
557
 
558
+ .site-section-page-title-empty .section-header {
559
+ padding-bottom: 0;
560
+ }
561
+
562
+ .site-section-page-title-empty .section-header h1 {
563
+ padding-bottom: 0;
564
+ }
565
+
566
+ .site-section-page-title-empty + .site-section {
567
+ padding-top: var(--space-page-title-to-first-section);
568
+ }
569
+
458
570
  .site-section:last-child {
459
571
  padding-bottom: var(--space-final-section-bottom);
460
572
  }
@@ -467,11 +579,12 @@ a {
467
579
  .section-header {
468
580
  width: min(100%, var(--section-heading-width-desktop, 760px));
469
581
  margin: 0 auto;
470
- padding: 0 0 var(--section-heading-spacing-after, 0.55em);
582
+ padding: 0;
471
583
  text-align: var(--section-heading-align-desktop, center);
472
584
  }
473
585
 
474
- .site-section-first-block-is-visual .section-header {
586
+ .site-section-first-block-is-visual .section-header h1,
587
+ .site-section-first-block-is-visual .section-header h2 {
475
588
  padding-bottom: var(--space-heading-to-block);
476
589
  }
477
590
 
@@ -485,6 +598,7 @@ ul {
485
598
  .section-header h1,
486
599
  .section-header h2 {
487
600
  margin-bottom: 0;
601
+ padding-bottom: var(--section-heading-spacing-after, 0.55em);
488
602
  color: inherit;
489
603
  font-size: var(--section-heading-font-size-desktop, clamp(1.35rem, 1.1rem + 0.9vw, 2rem));
490
604
  font-weight: var(--section-heading-font-weight, 400);
@@ -1115,6 +1229,7 @@ ul {
1115
1229
  --space-heading-to-block: var(--space-heading-to-block-mobile);
1116
1230
  --space-image-item: var(--space-image-item-mobile);
1117
1231
  --space-section-to-section: var(--space-section-to-section-mobile);
1232
+ --space-page-title-to-first-section: var(--space-page-title-to-first-section-mobile);
1118
1233
  --space-final-section-bottom: var(--space-final-section-bottom-mobile);
1119
1234
  --content-gutter: var(--content-gutter-mobile);
1120
1235
  --image-max-available-width: var(--image-max-available-width-mobile);
@@ -1122,6 +1237,10 @@ ul {
1122
1237
  --site-top-anchor-offset: 6.25rem;
1123
1238
  }
1124
1239
 
1240
+ .site-top {
1241
+ backdrop-filter: none;
1242
+ }
1243
+
1125
1244
  .site-nav-row {
1126
1245
  width: min(calc(100% - (var(--content-gutter) * 2)), var(--page-width));
1127
1246
  padding: 0.75rem 0;
@@ -1146,30 +1265,20 @@ ul {
1146
1265
  display: block;
1147
1266
  position: relative;
1148
1267
  flex: 0 0 auto;
1268
+ margin-left: auto;
1149
1269
  }
1150
1270
 
1151
- .page-nav ul {
1152
- gap: 0 1.55rem;
1153
- padding: 0 1rem;
1154
- text-align: center;
1155
- }
1156
-
1157
- .page-nav li + li::before {
1158
- left: -0.95rem;
1159
- }
1160
-
1161
- .page-nav a {
1162
- padding: 0.95rem 0 0.85rem;
1163
- font-size: 0.72rem;
1164
- white-space: nowrap;
1271
+ .page-nav {
1272
+ display: none;
1165
1273
  }
1166
1274
 
1167
- .mobile-nav-menu summary {
1275
+ .mobile-nav-menu > summary {
1168
1276
  display: flex;
1169
1277
  align-items: center;
1170
- gap: 0.42rem;
1278
+ gap: 0.5rem;
1279
+ min-height: 2.75rem;
1171
1280
  border: 1px solid currentColor;
1172
- padding: 0.5rem 0.7rem 0.44rem;
1281
+ padding: 0.55rem 0.75rem;
1173
1282
  font-size: 0.72rem;
1174
1283
  font-weight: 700;
1175
1284
  letter-spacing: 0.1em;
@@ -1179,63 +1288,272 @@ ul {
1179
1288
  text-transform: uppercase;
1180
1289
  }
1181
1290
 
1182
- .mobile-nav-menu summary::after {
1183
- content: "▾";
1184
- font-size: 0.82em;
1291
+ .mobile-nav-menu > summary::after {
1292
+ content: "☰";
1293
+ font-size: 1rem;
1185
1294
  line-height: 1;
1186
- opacity: 0.78;
1295
+ opacity: 0.86;
1187
1296
  }
1188
1297
 
1189
- .mobile-nav-menu[open] summary::after {
1190
- transform: rotate(180deg);
1298
+ .mobile-nav-menu[open] > summary::after {
1299
+ content: "×";
1300
+ font-size: 1.25rem;
1191
1301
  }
1192
1302
 
1193
- .mobile-nav-menu summary::-webkit-details-marker {
1303
+ .mobile-nav-menu > summary::-webkit-details-marker {
1194
1304
  display: none;
1195
1305
  }
1196
1306
 
1197
1307
  .mobile-nav-panel {
1198
- position: absolute;
1199
- top: calc(100% + 0.75rem);
1308
+ position: fixed;
1309
+ top: var(--site-top-anchor-offset);
1200
1310
  right: 0;
1201
- display: grid;
1202
- gap: 1.75rem;
1203
- width: min(82vw, 22rem);
1204
- border: 1px solid color-mix(in srgb, currentColor 30%, transparent);
1205
- padding: 1rem;
1311
+ bottom: 0;
1312
+ left: 0;
1313
+ width: 100%;
1314
+ max-height: none;
1315
+ border-top: 1px solid color-mix(in srgb, currentColor 24%, transparent);
1316
+ padding: clamp(1.25rem, 5vw, 2rem) var(--content-gutter) max(1.5rem, env(safe-area-inset-bottom));
1206
1317
  background: var(--site-top-background-color, var(--color-nav-background));
1207
- box-shadow: 0 1rem 2.5rem rgb(0 0 0 / 0.28);
1318
+ box-shadow: 0 1.5rem 3.5rem rgb(0 0 0 / 0.32);
1208
1319
  color: var(--site-top-text-color, var(--color-text));
1320
+ overflow-y: auto;
1321
+ overscroll-behavior: contain;
1209
1322
  }
1210
1323
 
1211
- .mobile-nav-panel h2 {
1212
- margin: 0 0 0.75rem;
1213
- font-size: 0.68rem;
1214
- font-weight: 700;
1215
- letter-spacing: 0.14em;
1216
- line-height: 1;
1217
- text-transform: uppercase;
1324
+ .mobile-site-nav {
1325
+ width: min(100%, 32rem);
1326
+ margin: 0 auto;
1218
1327
  }
1219
1328
 
1220
- .mobile-page-nav {
1221
- border-top: 1px solid color-mix(in srgb, currentColor 18%, transparent);
1222
- padding-top: 1.05rem;
1329
+ .mobile-nav-panel h2 {
1330
+ margin: 0 0 1.25rem;
1331
+ font-size: clamp(1.25rem, 5vw, 1.55rem);
1332
+ font-weight: 650;
1333
+ letter-spacing: 0;
1334
+ line-height: 1.2;
1335
+ text-transform: none;
1223
1336
  }
1224
1337
 
1225
1338
  .mobile-nav-panel ul {
1226
1339
  display: grid;
1227
- gap: 0.65rem;
1340
+ gap: 0;
1341
+ }
1342
+
1343
+ .navigation-page-tree-mobile > .navigation-page-node {
1344
+ border-top: 1px solid color-mix(in srgb, currentColor 14%, transparent);
1345
+ }
1346
+
1347
+ .navigation-page-tree-mobile > .navigation-page-node:first-child {
1348
+ border-top: 0;
1349
+ }
1350
+
1351
+ .navigation-page-tree-mobile .navigation-page-link,
1352
+ .mobile-navigation-branch > summary,
1353
+ .mobile-navigation-page-links a {
1354
+ display: flex;
1355
+ align-items: center;
1356
+ width: 100%;
1357
+ min-height: 3.25rem;
1358
+ padding: 0.75rem 0;
1359
+ }
1360
+
1361
+ .mobile-navigation-branch > summary {
1362
+ justify-content: space-between;
1363
+ border: 0;
1364
+ font-size: 0.94rem;
1365
+ font-weight: 650;
1366
+ letter-spacing: 0;
1367
+ line-height: 1.35;
1368
+ list-style: none;
1369
+ text-transform: none;
1370
+ cursor: pointer;
1371
+ }
1372
+
1373
+ .mobile-nav-menu .mobile-navigation-branch > summary::after {
1374
+ content: "+";
1375
+ font-size: 1.1rem;
1376
+ font-weight: 400;
1377
+ opacity: 0.7;
1378
+ }
1379
+
1380
+ .mobile-nav-menu .mobile-navigation-branch[open] > summary::after {
1381
+ content: "−";
1382
+ }
1383
+
1384
+ .mobile-navigation-branch > summary::-webkit-details-marker {
1385
+ display: none;
1386
+ }
1387
+
1388
+ .mobile-navigation-branch-content {
1389
+ margin-left: 0.35rem;
1390
+ border-left: 1px solid color-mix(in srgb, currentColor 20%, transparent);
1391
+ padding-left: 1rem;
1392
+ }
1393
+
1394
+ .mobile-navigation-page-links li,
1395
+ .mobile-navigation-branch-content > .navigation-page-tree-mobile > .navigation-page-node {
1396
+ border-top: 1px solid color-mix(in srgb, currentColor 10%, transparent);
1397
+ }
1398
+
1399
+ .mobile-navigation-page-links li:first-child {
1400
+ border-top: 0;
1401
+ }
1402
+
1403
+ .mobile-navigation-page-links a,
1404
+ .navigation-page-tree-mobile .navigation-page-link {
1405
+ font-size: 0.9rem;
1406
+ letter-spacing: 0;
1407
+ line-height: 1.35;
1408
+ text-transform: none;
1409
+ }
1410
+
1411
+ .navigation-page-node-current > .navigation-page-link,
1412
+ .navigation-page-node-current > .mobile-navigation-branch > summary > span,
1413
+ .navigation-page-node-current-branch > .mobile-navigation-branch > summary > span {
1414
+ text-decoration: underline;
1415
+ text-decoration-thickness: 1px;
1416
+ text-underline-offset: 0.3em;
1417
+ }
1418
+
1419
+ .mobile-nav-panel a,
1420
+ .mobile-nav-page-open,
1421
+ .mobile-nav-back {
1422
+ font-family: inherit;
1423
+ font-size: 0.94rem;
1424
+ letter-spacing: 0;
1425
+ line-height: 1.35;
1426
+ text-transform: none;
1427
+ }
1428
+
1429
+ .mobile-nav-page {
1430
+ border-top: 1px solid color-mix(in srgb, currentColor 14%, transparent);
1431
+ padding: 0;
1228
1432
  }
1229
1433
 
1230
- .mobile-nav-panel a {
1231
- font-size: 0.82rem;
1232
- letter-spacing: 0.06em;
1434
+ .mobile-nav-page:first-child {
1435
+ border-top: 0;
1436
+ }
1437
+
1438
+ .mobile-nav-page > a,
1439
+ .mobile-nav-page-open {
1440
+ display: flex;
1441
+ align-items: center;
1442
+ justify-content: space-between;
1443
+ width: 100%;
1444
+ min-height: 3.4rem;
1445
+ padding: 0.8rem 0;
1446
+ font-weight: 600;
1447
+ }
1448
+
1449
+ .mobile-nav-page-open {
1450
+ display: none;
1451
+ border: 0;
1452
+ background: transparent;
1453
+ color: currentColor;
1454
+ cursor: pointer;
1455
+ font-weight: 600;
1456
+ text-align: left;
1457
+ }
1458
+
1459
+ .mobile-nav-page-open::after {
1460
+ content: "›";
1461
+ font-size: 1.35rem;
1462
+ line-height: 1;
1463
+ opacity: 0.68;
1233
1464
  }
1234
1465
 
1235
- .mobile-page-nav a[aria-current='true'] {
1466
+ .mobile-nav-page-open:hover > span,
1467
+ .mobile-nav-page-open:focus-visible > span,
1468
+ .mobile-nav-page-open[aria-current='page'] > span {
1236
1469
  text-decoration: underline;
1237
1470
  text-decoration-thickness: 1px;
1238
- text-underline-offset: 0.35em;
1471
+ text-underline-offset: 0.3em;
1472
+ }
1473
+
1474
+ .mobile-nav-menu[data-mobile-navigation-ready='true'] .mobile-nav-page-open,
1475
+ .mobile-nav-menu[data-mobile-navigation-ready='true'] .mobile-nav-back {
1476
+ display: flex;
1477
+ }
1478
+
1479
+ .mobile-nav-menu[data-mobile-navigation-ready='true'] .mobile-nav-page-fallback {
1480
+ display: none;
1481
+ }
1482
+
1483
+ .mobile-nav-view[hidden] {
1484
+ display: none;
1485
+ }
1486
+
1487
+ .mobile-nav-menu:not([data-mobile-navigation-ready='true']) .mobile-nav-page-view:not([data-current-page='true']) {
1488
+ display: none;
1489
+ }
1490
+
1491
+ .mobile-nav-page-view + .mobile-nav-page-view,
1492
+ .mobile-nav-view + .mobile-nav-view {
1493
+ margin-top: 2rem;
1494
+ }
1495
+
1496
+ .mobile-nav-menu[data-mobile-navigation-ready='true'] .mobile-nav-view {
1497
+ margin-top: 0;
1498
+ }
1499
+
1500
+ .mobile-nav-back {
1501
+ display: none;
1502
+ align-items: center;
1503
+ gap: 0.55rem;
1504
+ min-height: 2.75rem;
1505
+ margin: -0.4rem 0 0.65rem;
1506
+ border: 0;
1507
+ padding: 0;
1508
+ background: transparent;
1509
+ color: currentColor;
1510
+ cursor: pointer;
1511
+ opacity: 0.78;
1512
+ }
1513
+
1514
+ .mobile-nav-back::before {
1515
+ content: "‹";
1516
+ font-size: 1.35rem;
1517
+ line-height: 1;
1518
+ }
1519
+
1520
+ .mobile-nav-back:hover,
1521
+ .mobile-nav-back:focus-visible {
1522
+ opacity: 1;
1523
+ text-decoration: underline;
1524
+ text-underline-offset: 0.25em;
1525
+ }
1526
+
1527
+ .mobile-nav-sections {
1528
+ border-top: 1px solid color-mix(in srgb, currentColor 16%, transparent);
1529
+ }
1530
+
1531
+ .mobile-nav-sections li {
1532
+ border-bottom: 1px solid color-mix(in srgb, currentColor 12%, transparent);
1533
+ }
1534
+
1535
+ .mobile-nav-sections a {
1536
+ min-height: 3.2rem;
1537
+ padding: 0.85rem 0;
1538
+ font-size: 0.92rem;
1539
+ opacity: 0.78;
1540
+ }
1541
+
1542
+ .mobile-nav-sections .mobile-nav-overview {
1543
+ font-weight: 650;
1544
+ }
1545
+
1546
+ .mobile-nav-sections a:hover,
1547
+ .mobile-nav-sections a:focus-visible,
1548
+ .mobile-nav-sections a[aria-current='location'] {
1549
+ opacity: 1;
1550
+ text-decoration: underline;
1551
+ text-decoration-thickness: 1px;
1552
+ text-underline-offset: 0.25em;
1553
+ }
1554
+
1555
+ .mobile-navigation-open {
1556
+ overflow: hidden;
1239
1557
  }
1240
1558
 
1241
1559
  .site-content {
@@ -15,14 +15,12 @@ If the standard local port is blocked, start with:
15
15
  npm run norna:dev -- --kill
16
16
  ```
17
17
 
18
- Edit the shared navigation label, logo settings, banners, and footer in
18
+ Edit shared logo settings, banners, and footer in
19
19
  `site/sitewide-content.yaml`,
20
20
  site-wide visual defaults in `site/theme.yaml`, homepage content and section
21
21
  metadata in `site/content.md`, and technical settings such as URL and locale
22
- in `site/config.yaml`. Keep source images under `site/images/<section-id>/`
23
- and static public files under `site/public/`. The image folder name should
24
- match the section id in Markdown, for example `## Work {#work}` uses
25
- `site/images/work/`.
22
+ in `site/config.yaml`. Keep managed homepage source images directly under
23
+ `site/images/` and static public files under `site/public/`.
26
24
 
27
25
  For a GitHub Pages project site without a custom domain, include the repository
28
26
  path in the public URL:
@@ -38,7 +36,7 @@ In GitHub repository settings, configure Pages to build from GitHub Actions.
38
36
 
39
37
  Page width, side gutters, layout density, typography rhythm, image width, image
40
38
  height limits, font, palettes, section surfaces, and site-wide typography are
41
- configured in `site/theme.yaml`. A route may replace that visual theme with its
39
+ configured in `site/theme.yaml`. A page may replace that visual theme with its
42
40
  own `theme.yaml`.
43
41
 
44
42
  Commit `package-lock.json` after the first install so GitHub Actions can use
@@ -73,7 +71,7 @@ Generic documentation lives in the `norna` repository:
73
71
  - `docs/content.md`
74
72
  - `docs/theme.md`
75
73
  - `docs/typography.md`
76
- - `docs/routes.md`
74
+ - `docs/pages.md`
77
75
  - `docs/configuration.md`
78
76
  - `docs/commands.md`
79
77
  - `docs/images-and-metadata.md`
@@ -1,16 +1,19 @@
1
1
  ---
2
- title: Example Site
3
- description: Minimal norna starter site.
2
+ page:
3
+ description: Minimal norna starter site.
4
4
  ---
5
5
 
6
+ # Example Site
7
+
8
+
6
9
  ## Intro {#intro}
7
10
  This is a minimal starter site for norna. Since this site doesn't have any
8
- routes defined, the navigation menu will be a sticky bar with anchor links for
11
+ pages defined, the navigation menu will be a sticky bar with anchor links for
9
12
  ease of use on phones etc. **Highlighted inline text** when a short
10
13
  phrase needs emphasis
11
14
  ## Work {#work}
12
15
  Add Norna image blocks in Markdown where the images should appear. Put
13
- matching source images under `images/work/`.
16
+ matching source images directly under `images/`.
14
17
 
15
18
  ````
16
19
  ```norna-image-stack
@@ -1,12 +1,3 @@
1
- navigation:
2
- label: Example Site
3
1
  footer:
4
2
  copyrightMessage: (c) Example Owner.
5
- buildInfo:
6
- enabled: true
7
- text: Built
8
- dateTimeFormat:
9
- locale: en-GB
10
- timeZone: UTC
11
- dateStyle: short
12
- timeStyle: short
3
+ buildInfo: true
@@ -19,13 +19,13 @@ npm run norna:dev -- --kill
19
19
  ## Files
20
20
 
21
21
  - `site/config.yaml`: public URL and optional language and smooth scrolling.
22
- - `site/sitewide-content.yaml`: shared navigation identity, banners, and footer.
22
+ - `site/sitewide-content.yaml`: shared logo display settings, banners, and footer.
23
23
  - `site/theme.yaml`: site-wide visual settings such as layout density, typography
24
24
  rhythm, palettes, section surfaces, and typography.
25
25
  - `site/content.md`: homepage title, sections, placeholders, project summary,
26
26
  links, install command, example usage, benefits, next steps, Norna blocks,
27
27
  and license.
28
- - `site/routes/010-guide/content.md`: short secondary page with realistic
28
+ - `site/pages/010-guide/content.md`: short secondary page with realistic
29
29
  project guide content.
30
30
  - `site/public/robots.txt`: static public file copied into the built site.
31
31
 
@@ -37,14 +37,14 @@ GitHub Pages workflow uses `npm ci`.
37
37
 
38
38
  1. Replace the project name, tagline, links, install command, example usage,
39
39
  benefits, use cases, and license in `site/content.md`.
40
- 2. Replace the guide examples in `site/routes/010-guide/content.md`, or
41
- delete the route if the homepage is enough.
42
- 3. Edit `site/sitewide-content.yaml` for the navigation label, logo display,
40
+ 2. Replace the guide examples in `site/pages/010-guide/content.md`, or
41
+ delete the page if the homepage is enough.
42
+ 3. Edit `site/sitewide-content.yaml` for logo display settings,
43
43
  banners, and footer.
44
44
  4. Edit `site/theme.yaml` for layout density, typography rhythm, palette, section
45
45
  surfaces, and typography.
46
- 5. Put any local source images in the image folder for the Markdown section
47
- that references them, for example `site/images/intro/`.
46
+ 5. Put managed homepage source images directly in `site/images/`. Images for
47
+ an additional page belong directly in that page's `images/` directory.
48
48
  6. Edit `site/config.yaml` for the public URL and, when needed, language or smooth
49
49
  scrolling. Deploy commands discover the GitHub repository and default branch.
50
50
  7. Update `package.json` with the site's package name and keep
@@ -79,6 +79,6 @@ Generic Norna documentation lives in the Norna repository:
79
79
  - `docs/content.md`
80
80
  - `docs/theme.md`
81
81
  - `docs/typography.md`
82
- - `docs/routes.md`
82
+ - `docs/pages.md`
83
83
  - `docs/configuration.md`
84
84
  - `docs/commands.md`