@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
@@ -23,11 +23,21 @@ Available presets:
23
23
 
24
24
  If theme typography is omitted, `quiet-gallery` is used.
25
25
 
26
- Presets define alignment, size, and line height for `headings.h1` through
27
- `headings.h4`, `body`, and `caption`. Built-in presets use `medium` as the
28
- default size for every text role. Visual heading hierarchy comes from the
29
- Markdown heading level, so `h1` is larger than `h2`, `h2` is larger than `h3`,
30
- and so on.
26
+ Presets define alignment, size, weight, and line height for `headings.h1`
27
+ through `headings.h4`, `body`, and `caption`. They also choose a readable body
28
+ text width. Built-in presets use `medium` as the default size for every text
29
+ role. Visual heading hierarchy comes from the Markdown heading level, so `h1`
30
+ is larger than `h2`, `h2` is larger than `h3`, and so on.
31
+
32
+ The presets use these controls deliberately:
33
+
34
+ - `quiet-gallery` uses restrained heading weights and a normal reading width.
35
+ - `compact-gallery` uses stronger headings and a wider text column for short,
36
+ scannable content.
37
+ - `text-forward` uses a narrower reading width and more generous body line
38
+ height.
39
+ - `statement` uses the strongest heading weights and a narrow text column for
40
+ short, declarative content.
31
41
 
32
42
  `rhythm` defines text-near spacing for headings, paragraphs, and captions.
33
43
  Available rhythms are `compact`, `normal`, and `airy`. Built-in rhythm values
@@ -62,12 +72,14 @@ typography:
62
72
  headings:
63
73
  h2:
64
74
  size: medium
75
+ weight: 600
65
76
  spacingAfter: 0.55em
66
77
  h3:
67
78
  size: medium
68
79
  spacingBefore: 1.5em
69
80
  spacingAfter: 0.5em
70
81
  body:
82
+ width: narrow
71
83
  paragraphSpacing: 0.8em
72
84
  caption:
73
85
  spacingBefore: 0.5em
@@ -104,21 +116,31 @@ follows the Markdown level the user wrote: `##` uses `headings.h2`.
104
116
  `spacingAfter`, and `paragraphSpacing` are CSS lengths such as `0`, `0.8em`,
105
117
  `1rem`, or `12px`. Use `em` for spacing that should track the text size.
106
118
 
119
+ `weight` is a controlled heading weight. Allowed values are `400`, `500`,
120
+ `600`, and `700`. `body.width` is the readable text width and accepts
121
+ `narrow`, `normal`, or `wide`. It controls the prose column, not the page's
122
+ maximum width or the width of image blocks.
123
+
107
124
  Supported override fields:
108
125
 
109
- - `headings.h1.align`, `headings.h1.size`, `headings.h1.lineHeight`,
126
+ - `headings.h1.align`, `headings.h1.size`, `headings.h1.weight`,
127
+ `headings.h1.lineHeight`,
110
128
  `headings.h1.spacingBefore`, `headings.h1.spacingAfter`
111
- - `headings.h2.align`, `headings.h2.size`, `headings.h2.lineHeight`,
129
+ - `headings.h2.align`, `headings.h2.size`, `headings.h2.weight`,
130
+ `headings.h2.lineHeight`,
112
131
  `headings.h2.spacingBefore`, `headings.h2.spacingAfter`
113
- - `headings.h3.align`, `headings.h3.size`, `headings.h3.lineHeight`,
132
+ - `headings.h3.align`, `headings.h3.size`, `headings.h3.weight`,
133
+ `headings.h3.lineHeight`,
114
134
  `headings.h3.spacingBefore`, `headings.h3.spacingAfter`
115
- - `headings.h4.align`, `headings.h4.size`, `headings.h4.lineHeight`,
135
+ - `headings.h4.align`, `headings.h4.size`, `headings.h4.weight`,
136
+ `headings.h4.lineHeight`,
116
137
  `headings.h4.spacingBefore`, `headings.h4.spacingAfter`
117
- - `body.align`, `body.size`, `body.lineHeight`, `body.paragraphSpacing`
138
+ - `body.align`, `body.size`, `body.width`, `body.lineHeight`,
139
+ `body.paragraphSpacing`
118
140
  - `caption.align`, `caption.size`, `caption.lineHeight`,
119
141
  `caption.spacingBefore`
120
142
 
121
- ## Inheritance
143
+ ## Route Themes
122
144
 
123
145
  Theme typography is the site-wide base:
124
146
 
@@ -130,30 +152,20 @@ typography:
130
152
  rhythm: normal
131
153
  ```
132
154
 
133
- A page-level `presentation.typography.preset` changes the typographic character
134
- for that page. A section-level
135
- `sections.<section-id>.presentation.typography.preset` changes the typographic
136
- character for that section. `rhythm` is inherited separately, so changing
137
- preset does not change spacing unless `rhythm` is also set.
138
-
139
- If a section sets `typography.rhythm`, that section changes text-near spacing.
140
- If a section only sets `typography.overrides`, it keeps the resolved page
141
- preset and rhythm and changes only the specified values.
155
+ A route-local `theme.md` can give that route a different typographic character.
156
+ The route theme replaces the root visual theme rather than inheriting from it,
157
+ so repeat any non-default `fontFamily`, `rhythm`, or `overrides` that the route
158
+ still needs.
142
159
 
143
- Example section override:
160
+ Example route theme:
144
161
 
145
162
  ```yaml
146
- sections:
147
- intro:
148
- presentation:
149
- typography:
150
- preset: statement
151
- overrides:
152
- body:
153
- paragraphSpacing: 0.7em
163
+ # site/routes/010-introduction/theme.md
164
+ typography:
165
+ preset: statement
166
+ rhythm: normal
154
167
  ```
155
168
 
156
- Centered text uses narrower text widths. Left- or right-aligned heading and body
157
- text use the calculated image layout width so text edges line up with images
158
- after layout gutters and image limits are applied. Captions are normally
159
- centered.
169
+ The `body.width` value controls the prose column independently of the page and
170
+ image widths. Captions are normally centered, but `text-forward` uses
171
+ left-aligned captions to support longer explanatory text.
@@ -0,0 +1,9 @@
1
+ # Dog Shelter single-page example
2
+
3
+ A small Norna site with two homepage sections and no routes.
4
+
5
+ Run it from the Norna repository root:
6
+
7
+ ```sh
8
+ node bin/norna.mjs --site-dir examples/001-dog-shelter-single-page/site dev:local
9
+ ```
@@ -0,0 +1,27 @@
1
+ export default {
2
+ site: {
3
+ url: 'http://localhost:4321/',
4
+ basePath: '/',
5
+ },
6
+ navigation: {
7
+ smoothScroll: {
8
+ enabled: true,
9
+ minimumDurationMs: 600,
10
+ maximumDurationMs: 1_200,
11
+ durationPerPixelMs: 0.2,
12
+ },
13
+ },
14
+ locale: {
15
+ lang: 'en',
16
+ labels: {
17
+ skipToContent: 'Skip to content',
18
+ sectionNavigation: 'Sections',
19
+ gallery: 'Images',
20
+ },
21
+ },
22
+ github: {
23
+ repo: 'owner/dog-shelter',
24
+ branch: 'main',
25
+ pagesWorkflow: 'Deploy to GitHub Pages',
26
+ },
27
+ };
@@ -0,0 +1,38 @@
1
+ ---
2
+ title: Home
3
+ description: A single-page dog shelter website built with Norna.
4
+ ---
5
+
6
+ ## What we do {#what-we-do}
7
+
8
+ We rescue and rehome dogs.
9
+
10
+ <!-- norna-image-provenance:
11
+ image: dog-house.svg
12
+ source: AI-assisted, hand-authored SVG
13
+ prompt: Draw a simple flat vector dog house with a friendly dog at the entrance,
14
+ using a small paper, red and dark-brown palette. No text and no external assets.
15
+ -->
16
+
17
+ ```norna-image-stack
18
+ - image: dog-house.svg
19
+ alt: A brown dog standing at the entrance to a red dog house.
20
+ caption: Time to recover before adoption.
21
+ ```
22
+
23
+ ## You can help {#you-can-help}
24
+
25
+ Adopt. Foster. Donate.
26
+
27
+ <!-- norna-image-provenance:
28
+ image: heart.svg
29
+ source: AI-assisted, hand-authored SVG
30
+ prompt: Draw two simple hands holding a red heart as a flat vector illustration,
31
+ using a small paper, red and dark-brown palette. No text or external assets.
32
+ -->
33
+
34
+ ```norna-image-stack
35
+ - image: heart.svg
36
+ alt: Two open hands holding a red heart.
37
+ caption: Foster care helps another dog.
38
+ ```
@@ -0,0 +1,25 @@
1
+ <svg xmlns="http://www.w3.org/2000/svg" viewBox="0 0 800 520" role="img" aria-labelledby="title desc">
2
+ <title id="title">Dog at a shelter house</title>
3
+ <desc id="desc">A friendly brown dog stands at the entrance to a red wooden dog house.</desc>
4
+ <rect width="800" height="520" rx="32" fill="#eef3ef"/>
5
+ <path d="M0 405 Q180 365 380 405 T800 390 V520 H0Z" fill="#cad8bd"/>
6
+ <g stroke="#493c2b" stroke-width="8" stroke-linejoin="round">
7
+ <path d="M190 247 L400 82 L610 247" fill="#9f493a"/>
8
+ <path d="M236 222 H564 V432 H236Z" fill="#c8674f"/>
9
+ <path d="M327 432 V300 Q327 234 400 234 Q473 234 473 300 V432Z" fill="#332d29"/>
10
+ <path d="M213 244 L400 94 L587 244" fill="none" stroke="#7f3f32" stroke-width="24" stroke-linecap="round"/>
11
+ </g>
12
+ <g transform="translate(310 250)" stroke="#493c2b" stroke-width="6" stroke-linejoin="round">
13
+ <path d="M40 119 C47 80 93 64 142 76 C181 86 196 119 184 158 H58 C42 151 34 135 40 119Z" fill="#b8794d"/>
14
+ <path d="M62 94 C45 61 58 23 96 13 C133 3 169 27 168 64 C167 93 145 108 112 109 H76Z" fill="#b8794d"/>
15
+ <path d="M76 32 L53 3 L98 17" fill="#8c573a"/>
16
+ <path d="M143 25 L171 3 L164 46" fill="#8c573a"/>
17
+ <circle cx="92" cy="53" r="6" fill="#272522" stroke="none"/>
18
+ <circle cx="140" cy="53" r="6" fill="#272522" stroke="none"/>
19
+ <ellipse cx="116" cy="76" rx="25" ry="19" fill="#dca477"/>
20
+ <circle cx="116" cy="70" r="7" fill="#272522" stroke="none"/>
21
+ <path d="M105 84 Q116 96 129 84" fill="none" stroke-linecap="round"/>
22
+ <path d="M59 154 V188 M94 154 V188 M145 154 V188" fill="none" stroke-linecap="round"/>
23
+ <path d="M177 105 Q220 80 211 39" fill="none" stroke-linecap="round"/>
24
+ </g>
25
+ </svg>
@@ -0,0 +1,13 @@
1
+ <svg xmlns="http://www.w3.org/2000/svg" viewBox="0 0 800 520" role="img" aria-labelledby="title desc">
2
+ <title id="title">Hands holding a heart</title>
3
+ <desc id="desc">Two open hands support a large red heart.</desc>
4
+ <rect width="800" height="520" rx="32" fill="#f3eee5"/>
5
+ <circle cx="400" cy="250" r="176" fill="#e5dccd"/>
6
+ <path d="M400 354 C368 316 263 252 263 166 C263 108 309 79 354 92 C379 99 394 116 400 135 C406 116 421 99 446 92 C491 79 537 108 537 166 C537 252 432 316 400 354Z" fill="#b84f45" stroke="#493c2b" stroke-width="8" stroke-linejoin="round"/>
7
+ <g fill="#d5a071" stroke="#493c2b" stroke-width="7" stroke-linecap="round" stroke-linejoin="round">
8
+ <path d="M74 368 C144 330 211 328 291 365 L363 407 C382 420 373 451 350 450 L268 426 C228 414 191 421 154 451 L92 502 L30 429Z"/>
9
+ <path d="M726 368 C656 330 589 328 509 365 L437 407 C418 420 427 451 450 450 L532 426 C572 414 609 421 646 451 L708 502 L770 429Z"/>
10
+ <path d="M290 365 L350 349 C369 344 383 360 376 378 L363 407"/>
11
+ <path d="M510 365 L450 349 C431 344 417 360 424 378 L437 407"/>
12
+ </g>
13
+ </svg>
@@ -0,0 +1,10 @@
1
+ <svg xmlns="http://www.w3.org/2000/svg" viewBox="0 0 64 64" role="img" aria-label="Dog Shelter paw mark">
2
+ <rect width="64" height="64" rx="12" fill="#f8f5ee"/>
3
+ <g fill="#7f3f32">
4
+ <ellipse cx="32" cy="39" rx="16" ry="13"/>
5
+ <circle cx="16" cy="25" r="7"/>
6
+ <circle cx="29" cy="18" r="7"/>
7
+ <circle cx="43" cy="20" r="7"/>
8
+ <circle cx="50" cy="32" r="7"/>
9
+ </g>
10
+ </svg>
@@ -0,0 +1,2 @@
1
+ User-agent: *
2
+ Allow: /
@@ -0,0 +1,6 @@
1
+ ---
2
+ navigation:
3
+ brand: Dog Shelter
4
+ footer:
5
+ copyrightMessage: Dog Shelter example site.
6
+ ---
@@ -0,0 +1,25 @@
1
+ ---
2
+ layout:
3
+ density: normal
4
+ pageWidth: 1180px
5
+ gutter:
6
+ desktop: clamp(1.25rem, 4vw, 3rem)
7
+ mobile: 1rem
8
+ gallery:
9
+ width: 760px
10
+ maxAvailableWidthPercent:
11
+ desktop: 100
12
+ mobile: 100
13
+ maxAvailableHeightPercent:
14
+ desktop: 72
15
+ mobile: 68
16
+ typography:
17
+ fontFamily: "Arial, 'Helvetica Neue', Helvetica, sans-serif"
18
+ preset: text-forward
19
+ rhythm: normal
20
+ presentation:
21
+ palette: paper
22
+ sectionSurfaces:
23
+ mode: cycle
24
+ sequence: [base, soft]
25
+ ---
@@ -0,0 +1,9 @@
1
+ # Dog Shelter multi-page example
2
+
3
+ A small Norna site with a homepage and ordered routes for dogs and adoption.
4
+
5
+ Run it from the Norna repository root:
6
+
7
+ ```sh
8
+ node bin/norna.mjs --site-dir examples/002-dog-shelter-multi-page/site dev:local
9
+ ```
@@ -0,0 +1,27 @@
1
+ export default {
2
+ site: {
3
+ url: 'http://localhost:4321/',
4
+ basePath: '/',
5
+ },
6
+ navigation: {
7
+ smoothScroll: {
8
+ enabled: true,
9
+ minimumDurationMs: 600,
10
+ maximumDurationMs: 1_200,
11
+ durationPerPixelMs: 0.2,
12
+ },
13
+ },
14
+ locale: {
15
+ lang: 'en',
16
+ labels: {
17
+ skipToContent: 'Skip to content',
18
+ sectionNavigation: 'Sections',
19
+ gallery: 'Images',
20
+ },
21
+ },
22
+ github: {
23
+ repo: 'owner/dog-shelter',
24
+ branch: 'main',
25
+ pagesWorkflow: 'Deploy to GitHub Pages',
26
+ },
27
+ };
@@ -0,0 +1,12 @@
1
+ ---
2
+ title: Home
3
+ description: A multi-page dog shelter website built with Norna.
4
+ ---
5
+
6
+ ## Dog Shelter {#intro}
7
+
8
+ We rescue dogs, help them recover and introduce them to families ready to give
9
+ them a permanent home.
10
+
11
+ Visit **Dogs** to meet two current residents, or **Adopt** to learn how the
12
+ adoption process works.
@@ -0,0 +1,10 @@
1
+ <svg xmlns="http://www.w3.org/2000/svg" viewBox="0 0 64 64" role="img" aria-label="Dog Shelter paw mark">
2
+ <rect width="64" height="64" rx="12" fill="#f8f5ee"/>
3
+ <g fill="#7f3f32">
4
+ <ellipse cx="32" cy="39" rx="16" ry="13"/>
5
+ <circle cx="16" cy="25" r="7"/>
6
+ <circle cx="29" cy="18" r="7"/>
7
+ <circle cx="43" cy="20" r="7"/>
8
+ <circle cx="50" cy="32" r="7"/>
9
+ </g>
10
+ </svg>
@@ -0,0 +1,2 @@
1
+ User-agent: *
2
+ Allow: /
@@ -0,0 +1,19 @@
1
+ <svg xmlns="http://www.w3.org/2000/svg" viewBox="0 0 800 560" role="img" aria-labelledby="title desc">
2
+ <title id="title">Rex</title>
3
+ <desc id="desc">A gentle golden dog with one floppy ear and a curved tail.</desc>
4
+ <rect width="800" height="560" rx="32" fill="#f3eee3"/>
5
+ <ellipse cx="404" cy="462" rx="270" ry="36" fill="#ddd1b8"/>
6
+ <g stroke="#493c2b" stroke-width="9" stroke-linejoin="round">
7
+ <path d="M218 316 C265 240 386 219 527 258 C594 277 623 343 589 404 H278 C221 391 196 354 218 316Z" fill="#e3c681"/>
8
+ <path d="M274 275 C237 202 279 112 370 91 C458 71 538 132 528 218 C520 285 464 318 389 317 H307Z" fill="#e3c681"/>
9
+ <path d="M309 134 L264 52 L365 91" fill="#c49b51"/>
10
+ <path d="M465 111 Q560 96 551 181 Q529 214 488 197Z" fill="#c49b51"/>
11
+ <circle cx="346" cy="187" r="11" fill="#272522" stroke="none"/>
12
+ <circle cx="451" cy="187" r="11" fill="#272522" stroke="none"/>
13
+ <ellipse cx="399" cy="239" rx="61" ry="45" fill="#f1dca9"/>
14
+ <circle cx="399" cy="225" r="14" fill="#272522" stroke="none"/>
15
+ <path d="M377 254 Q399 280 427 254" fill="none" stroke-linecap="round"/>
16
+ <path d="M281 400 V479 M374 400 V479 M511 400 V479" fill="none" stroke-linecap="round"/>
17
+ <path d="M568 294 Q676 330 642 420" fill="none" stroke-linecap="round"/>
18
+ </g>
19
+ </svg>
@@ -0,0 +1,19 @@
1
+ <svg xmlns="http://www.w3.org/2000/svg" viewBox="0 0 800 560" role="img" aria-labelledby="title desc">
2
+ <title id="title">Rover</title>
3
+ <desc id="desc">A friendly brown dog with upright ears and a curled tail.</desc>
4
+ <rect width="800" height="560" rx="32" fill="#eaf2ec"/>
5
+ <ellipse cx="404" cy="462" rx="270" ry="36" fill="#c8d9c7"/>
6
+ <g stroke="#493c2b" stroke-width="9" stroke-linejoin="round">
7
+ <path d="M215 313 C251 231 372 209 518 246 C590 265 622 332 593 402 H278 C220 391 191 354 215 313Z" fill="#b8794d"/>
8
+ <path d="M259 271 C220 195 256 105 348 83 C438 61 526 118 523 208 C520 278 468 314 389 316 H294Z" fill="#b8794d"/>
9
+ <path d="M291 128 L236 50 L340 86" fill="#8c573a"/>
10
+ <path d="M454 109 L526 43 L505 159" fill="#8c573a"/>
11
+ <circle cx="333" cy="181" r="11" fill="#272522" stroke="none"/>
12
+ <circle cx="449" cy="181" r="11" fill="#272522" stroke="none"/>
13
+ <ellipse cx="391" cy="236" rx="60" ry="45" fill="#dca477"/>
14
+ <circle cx="391" cy="222" r="14" fill="#272522" stroke="none"/>
15
+ <path d="M369 251 Q391 277 419 251" fill="none" stroke-linecap="round"/>
16
+ <path d="M278 396 V479 M365 396 V479 M508 396 V479" fill="none" stroke-linecap="round"/>
17
+ <path d="M565 280 Q680 224 660 120 Q646 81 618 103" fill="none" stroke-linecap="round"/>
18
+ </g>
19
+ </svg>
@@ -0,0 +1,30 @@
1
+ ---
2
+ title: Dogs
3
+ description: Meet dogs currently waiting for adoption.
4
+ ---
5
+
6
+ ## Dogs {#dogs}
7
+
8
+ Meet Rover and Rex.
9
+
10
+ <!-- norna-image-provenance:
11
+ image: rover.svg
12
+ source: AI-assisted, hand-authored SVG
13
+ prompt: Draw a friendly brown cartoon dog standing in profile on a pale green
14
+ background. Flat vector style, dark outlines, no text or external assets.
15
+
16
+ image: rex.svg
17
+ source: AI-assisted, hand-authored SVG
18
+ prompt: Draw a friendly golden cartoon dog standing in profile on a pale cream
19
+ background. Make it visibly distinct from Rover. Flat vector style, dark
20
+ outlines, no text or external assets.
21
+ -->
22
+
23
+ ```norna-image-stack
24
+ - image: rover.svg
25
+ alt: Rover, a brown dog with upright ears and a curled tail.
26
+ caption: Rover needs daily walks.
27
+ - image: rex.svg
28
+ alt: Rex, a golden dog with one floppy ear and a gently curved tail.
29
+ caption: Rex needs a patient home.
30
+ ```
@@ -0,0 +1,12 @@
1
+ ---
2
+ title: Adopt
3
+ description: Learn how to adopt from Dog Shelter.
4
+ ---
5
+
6
+ ## Adopt {#adopt}
7
+
8
+ Adoption begins with a conversation about your home, routines and experience
9
+ with dogs. We then arrange a meeting with dogs whose needs appear to match.
10
+
11
+ The goal is not the quickest placement. It is a stable home where both the dog
12
+ and the family have the support they need.
@@ -0,0 +1,6 @@
1
+ ---
2
+ navigation:
3
+ brand: Dog Shelter
4
+ footer:
5
+ copyrightMessage: Dog Shelter example site.
6
+ ---
@@ -0,0 +1,25 @@
1
+ ---
2
+ layout:
3
+ density: normal
4
+ pageWidth: 1180px
5
+ gutter:
6
+ desktop: clamp(1.25rem, 4vw, 3rem)
7
+ mobile: 1rem
8
+ gallery:
9
+ width: 760px
10
+ maxAvailableWidthPercent:
11
+ desktop: 100
12
+ mobile: 100
13
+ maxAvailableHeightPercent:
14
+ desktop: 72
15
+ mobile: 68
16
+ typography:
17
+ fontFamily: "Arial, 'Helvetica Neue', Helvetica, sans-serif"
18
+ preset: text-forward
19
+ rhythm: normal
20
+ presentation:
21
+ palette: paper
22
+ sectionSurfaces:
23
+ mode: cycle
24
+ sequence: [base, soft]
25
+ ---