@janga/norna 0.7.1 → 0.7.3

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 (168) hide show
  1. package/README.md +32 -18
  2. package/astro.config.mjs +2 -0
  3. package/bin/norna-cli.mjs +175 -0
  4. package/bin/norna.mjs +149 -150
  5. package/docs/README.md +41 -22
  6. package/docs/commands.md +25 -12
  7. package/docs/configuration.md +38 -135
  8. package/docs/content.md +108 -265
  9. package/docs/{command-organization.md → design/command-organization.md} +64 -60
  10. package/docs/{site-examples-structure-note.md → design/site-examples-structure.md} +19 -24
  11. package/docs/engine-development.md +35 -7
  12. package/docs/getting-started.md +55 -26
  13. package/docs/images-and-metadata.md +1 -1
  14. package/docs/local-development.md +14 -1
  15. package/docs/publishing.md +24 -1
  16. package/docs/routes.md +90 -0
  17. package/docs/site-structure.md +18 -10
  18. package/docs/theme.md +292 -0
  19. package/docs/typography.md +144 -0
  20. package/examples/dog-gallery/.astro/collections/site.schema.json +802 -0
  21. package/examples/dog-gallery/.astro/collections/theme.schema.json +714 -0
  22. package/examples/dog-gallery/.astro/content-assets.mjs +4 -0
  23. package/examples/dog-gallery/.astro/content-modules.mjs +1 -0
  24. package/examples/dog-gallery/.astro/content.d.ts +175 -0
  25. package/examples/dog-gallery/.astro/data-store.json +1 -0
  26. package/examples/dog-gallery/.astro/dev-local.json +8 -0
  27. package/examples/dog-gallery/.astro/dev.json +13 -0
  28. package/examples/dog-gallery/.astro/dev.log +49 -0
  29. package/examples/dog-gallery/.astro/settings.json +5 -0
  30. package/examples/dog-gallery/.astro/types.d.ts +2 -0
  31. package/examples/dog-gallery/dist/_astro/GalleryGrid.astro_astro_type_script_index_0_lang.B0kxDyGz.js +1 -0
  32. package/examples/dog-gallery/dist/_astro/SitePage.BFHZm5UG.css +1 -0
  33. package/examples/dog-gallery/dist/dog-care/index.html +15 -0
  34. package/examples/dog-gallery/dist/favicon.svg +7 -0
  35. package/examples/dog-gallery/dist/images/generated/black-dogs/black-puppy-meadow-7255e3d9-1080.webp +0 -0
  36. package/examples/dog-gallery/dist/images/generated/black-dogs/black-puppy-meadow-7255e3d9-1440.webp +0 -0
  37. package/examples/dog-gallery/dist/images/generated/black-dogs/black-puppy-meadow-7255e3d9-1536.webp +0 -0
  38. package/examples/dog-gallery/dist/images/generated/black-dogs/black-puppy-meadow-7255e3d9-480.webp +0 -0
  39. package/examples/dog-gallery/dist/images/generated/black-dogs/black-puppy-meadow-7255e3d9-768.webp +0 -0
  40. package/examples/dog-gallery/dist/images/generated/black-dogs/photo-of-a-black-dog-5cf614d2-480.webp +0 -0
  41. package/examples/dog-gallery/dist/images/generated/black-dogs/photo-of-a-black-dog-5cf614d2-768.webp +0 -0
  42. package/examples/dog-gallery/dist/images/generated/black-dogs/photo-of-a-black-dog-5cf614d2-960.webp +0 -0
  43. package/examples/dog-gallery/dist/images/generated/brown-dogs/brown-dog-50ef114e-1080.webp +0 -0
  44. package/examples/dog-gallery/dist/images/generated/brown-dogs/brown-dog-50ef114e-1440.webp +0 -0
  45. package/examples/dog-gallery/dist/images/generated/brown-dogs/brown-dog-50ef114e-1920.webp +0 -0
  46. package/examples/dog-gallery/dist/images/generated/brown-dogs/brown-dog-50ef114e-3939.webp +0 -0
  47. package/examples/dog-gallery/dist/images/generated/brown-dogs/brown-dog-50ef114e-480.webp +0 -0
  48. package/examples/dog-gallery/dist/images/generated/brown-dogs/brown-dog-50ef114e-768.webp +0 -0
  49. package/examples/dog-gallery/dist/images/generated/brown-dogs/dog-accompanies-master-7ef804d5-1080.webp +0 -0
  50. package/examples/dog-gallery/dist/images/generated/brown-dogs/dog-accompanies-master-7ef804d5-1440.webp +0 -0
  51. package/examples/dog-gallery/dist/images/generated/brown-dogs/dog-accompanies-master-7ef804d5-1920.webp +0 -0
  52. package/examples/dog-gallery/dist/images/generated/brown-dogs/dog-accompanies-master-7ef804d5-2400.webp +0 -0
  53. package/examples/dog-gallery/dist/images/generated/brown-dogs/dog-accompanies-master-7ef804d5-480.webp +0 -0
  54. package/examples/dog-gallery/dist/images/generated/brown-dogs/dog-accompanies-master-7ef804d5-768.webp +0 -0
  55. package/examples/dog-gallery/dist/images/generated/golden-dogs/golden-retriever-f797fd88-1080.webp +0 -0
  56. package/examples/dog-gallery/dist/images/generated/golden-dogs/golden-retriever-f797fd88-1440.webp +0 -0
  57. package/examples/dog-gallery/dist/images/generated/golden-dogs/golden-retriever-f797fd88-1600.webp +0 -0
  58. package/examples/dog-gallery/dist/images/generated/golden-dogs/golden-retriever-f797fd88-480.webp +0 -0
  59. package/examples/dog-gallery/dist/images/generated/golden-dogs/golden-retriever-f797fd88-768.webp +0 -0
  60. package/examples/dog-gallery/dist/images/generated/golden-dogs/toller-puppy-a2a8fbc0-1080.webp +0 -0
  61. package/examples/dog-gallery/dist/images/generated/golden-dogs/toller-puppy-a2a8fbc0-1440.webp +0 -0
  62. package/examples/dog-gallery/dist/images/generated/golden-dogs/toller-puppy-a2a8fbc0-1920.webp +0 -0
  63. package/examples/dog-gallery/dist/images/generated/golden-dogs/toller-puppy-a2a8fbc0-2576.webp +0 -0
  64. package/examples/dog-gallery/dist/images/generated/golden-dogs/toller-puppy-a2a8fbc0-480.webp +0 -0
  65. package/examples/dog-gallery/dist/images/generated/golden-dogs/toller-puppy-a2a8fbc0-768.webp +0 -0
  66. package/examples/dog-gallery/dist/images/generated/white-dogs/white-cute-dog-077a0689-1080.webp +0 -0
  67. package/examples/dog-gallery/dist/images/generated/white-dogs/white-cute-dog-077a0689-1277.webp +0 -0
  68. package/examples/dog-gallery/dist/images/generated/white-dogs/white-cute-dog-077a0689-480.webp +0 -0
  69. package/examples/dog-gallery/dist/images/generated/white-dogs/white-cute-dog-077a0689-768.webp +0 -0
  70. package/examples/dog-gallery/dist/images/generated/white-dogs/white-puppy-garden-d3ab2ca0-1080.webp +0 -0
  71. package/examples/dog-gallery/dist/images/generated/white-dogs/white-puppy-garden-d3ab2ca0-1440.webp +0 -0
  72. package/examples/dog-gallery/dist/images/generated/white-dogs/white-puppy-garden-d3ab2ca0-1536.webp +0 -0
  73. package/examples/dog-gallery/dist/images/generated/white-dogs/white-puppy-garden-d3ab2ca0-480.webp +0 -0
  74. package/examples/dog-gallery/dist/images/generated/white-dogs/white-puppy-garden-d3ab2ca0-768.webp +0 -0
  75. package/examples/dog-gallery/dist/index.html +43 -0
  76. package/examples/dog-gallery/dist/robots.txt +2 -0
  77. package/examples/dog-gallery/node_modules/.vite/deps/_metadata.json +74 -0
  78. package/examples/dog-gallery/node_modules/.vite/deps/astro-D_GIpJIE.js +434 -0
  79. package/examples/dog-gallery/node_modules/.vite/deps/astro-D_GIpJIE.js.map +1 -0
  80. package/examples/dog-gallery/node_modules/.vite/deps/astro_n_aria-query.js +6390 -0
  81. package/examples/dog-gallery/node_modules/.vite/deps/astro_n_aria-query.js.map +1 -0
  82. package/examples/dog-gallery/node_modules/.vite/deps/astro_n_axobject-query.js +2702 -0
  83. package/examples/dog-gallery/node_modules/.vite/deps/astro_n_axobject-query.js.map +1 -0
  84. package/examples/dog-gallery/node_modules/.vite/deps/astro_n_html-escaper.js +65 -0
  85. package/examples/dog-gallery/node_modules/.vite/deps/astro_n_html-escaper.js.map +1 -0
  86. package/examples/dog-gallery/node_modules/.vite/deps/astro_runtime_client_dev-toolbar_entrypoint__js.js +455 -0
  87. package/examples/dog-gallery/node_modules/.vite/deps/astro_runtime_client_dev-toolbar_entrypoint__js.js.map +1 -0
  88. package/examples/dog-gallery/node_modules/.vite/deps/audit-DM9Hkl5B.js +1534 -0
  89. package/examples/dog-gallery/node_modules/.vite/deps/audit-DM9Hkl5B.js.map +1 -0
  90. package/examples/dog-gallery/node_modules/.vite/deps/highlight-DnZ1ULOL.js +48 -0
  91. package/examples/dog-gallery/node_modules/.vite/deps/highlight-DnZ1ULOL.js.map +1 -0
  92. package/examples/dog-gallery/node_modules/.vite/deps/icons-RyebKi45.js +42 -0
  93. package/examples/dog-gallery/node_modules/.vite/deps/icons-RyebKi45.js.map +1 -0
  94. package/examples/dog-gallery/node_modules/.vite/deps/package.json +3 -0
  95. package/examples/dog-gallery/node_modules/.vite/deps/rolldown-runtime-BvCyGRYZ.js +4 -0
  96. package/examples/dog-gallery/node_modules/.vite/deps/settings-DaU-gNnK.js +190 -0
  97. package/examples/dog-gallery/node_modules/.vite/deps/settings-DaU-gNnK.js.map +1 -0
  98. package/examples/dog-gallery/node_modules/.vite/deps/toolbar-63PA619H.js +458 -0
  99. package/examples/dog-gallery/node_modules/.vite/deps/toolbar-63PA619H.js.map +1 -0
  100. package/examples/dog-gallery/node_modules/.vite/deps/ui-library--bkcNSYz.js +1016 -0
  101. package/examples/dog-gallery/node_modules/.vite/deps/ui-library--bkcNSYz.js.map +1 -0
  102. package/examples/dog-gallery/node_modules/.vite/deps/window-jPkpKVcy.js +32 -0
  103. package/examples/dog-gallery/node_modules/.vite/deps/window-jPkpKVcy.js.map +1 -0
  104. package/examples/dog-gallery/node_modules/.vite/deps/xray-BXCHpEJP.js +111 -0
  105. package/examples/dog-gallery/node_modules/.vite/deps/xray-BXCHpEJP.js.map +1 -0
  106. package/examples/dog-gallery/site/.norna/generated-images.json +226 -0
  107. package/examples/dog-gallery/site/config.mjs +67 -0
  108. package/examples/dog-gallery/site/content.md +168 -0
  109. package/examples/dog-gallery/site/images/black-dogs/black-puppy-meadow.png +0 -0
  110. package/examples/dog-gallery/site/images/black-dogs/photo-of-a-black-dog.jpg +0 -0
  111. package/examples/dog-gallery/site/images/brown-dogs/brown-dog.jpg +0 -0
  112. package/examples/dog-gallery/site/images/brown-dogs/dog-accompanies-master.jpg +0 -0
  113. package/examples/dog-gallery/site/images/golden-dogs/golden-retriever.jpg +0 -0
  114. package/examples/dog-gallery/site/images/golden-dogs/toller-puppy.jpg +0 -0
  115. package/examples/dog-gallery/site/images/white-dogs/white-cute-dog.jpg +0 -0
  116. package/examples/dog-gallery/site/images/white-dogs/white-puppy-garden.png +0 -0
  117. package/examples/dog-gallery/site/public/favicon.svg +7 -0
  118. package/examples/dog-gallery/site/public/robots.txt +2 -0
  119. package/examples/dog-gallery/site/routes/dog-care/route-content.md +49 -0
  120. package/examples/dog-gallery/site/theme.md +114 -0
  121. package/fixtures/basic/site/config.mjs +3 -22
  122. package/fixtures/basic/site/content.md +1 -1
  123. package/fixtures/basic/site/theme.md +7 -3
  124. package/package.json +10 -9
  125. package/scripts/check-config.mjs +4 -3
  126. package/scripts/deploy-site.mjs +3 -3
  127. package/scripts/dev-local.mjs +64 -15
  128. package/scripts/init-site.mjs +11 -9
  129. package/scripts/lib/frontmatter-yaml.mjs +85 -0
  130. package/scripts/lib/presentation.mjs +10 -11
  131. package/scripts/lib/project-config.mjs +113 -45
  132. package/scripts/lib/site-content.mjs +21 -2
  133. package/scripts/lib/site-paths.mjs +18 -3
  134. package/scripts/lib/theme-config.mjs +34 -0
  135. package/scripts/lib/typography.mjs +103 -23
  136. package/scripts/show-typography.mjs +202 -75
  137. package/scripts/sync-content-sections.mjs +6 -6
  138. package/scripts/test-cli-discovery.mjs +124 -0
  139. package/scripts/test-content-check.mjs +3 -4
  140. package/scripts/test-engine-commands.mjs +20 -6
  141. package/scripts/test-navigation.mjs +10 -6
  142. package/scripts/test-package-check.mjs +40 -11
  143. package/scripts/test-temporary-visibility.mjs +2 -3
  144. package/src/components/SiteNavigation.astro +7 -5
  145. package/src/components/SitePage.astro +5 -3
  146. package/src/components/SiteSection.astro +63 -29
  147. package/src/content.config.ts +64 -2
  148. package/src/layouts/BaseLayout.astro +19 -1
  149. package/src/lib/basePath.ts +21 -0
  150. package/src/lib/generatedImages.ts +8 -4
  151. package/src/lib/sectionContent.ts +6 -1
  152. package/src/lib/sitePublicAssets.ts +8 -1
  153. package/src/styles/global.css +59 -55
  154. package/starters/basic/.github/workflows/deploy.yml +3 -3
  155. package/starters/basic/README.md +30 -14
  156. package/starters/basic/package.json +3 -3
  157. package/starters/basic/site/config.mjs +4 -24
  158. package/starters/basic/site/content.md +44 -9
  159. package/starters/basic/site/theme.md +113 -16
  160. package/starters/project/.github/workflows/deploy.yml +65 -0
  161. package/starters/project/README.md +72 -0
  162. package/starters/project/package-lock.json +4296 -0
  163. package/starters/project/package.json +35 -0
  164. package/starters/project/site/config.mjs +43 -0
  165. package/starters/project/site/content.md +88 -0
  166. package/starters/project/site/public/robots.txt +2 -0
  167. package/starters/project/site/routes/guide/route-content.md +58 -0
  168. package/starters/project/site/theme.md +15 -0
@@ -25,6 +25,29 @@ workflow:
25
25
  Site-specific static files such as `site/public/CNAME`, `robots.txt`, and
26
26
  `sitemap.xml` belong in the site repository.
27
27
 
28
+ In the GitHub repository settings, set Pages to build from GitHub Actions. For
29
+ a project site without a custom domain, configure the site URL and base path in
30
+ `site/config.mjs`:
31
+
32
+ ```js
33
+ site: {
34
+ url: 'https://owner.github.io/repository-name/',
35
+ basePath: '/repository-name/',
36
+ }
37
+ ```
38
+
39
+ For a custom domain, keep `basePath` as `/`:
40
+
41
+ ```js
42
+ site: {
43
+ url: 'https://example.com/',
44
+ basePath: '/',
45
+ }
46
+ ```
47
+
48
+ Norna uses `site.basePath` for generated internal page links, favicons,
49
+ generated images, and root-relative links or images written in Markdown.
50
+
28
51
  ## Deploy An Already Committed Branch
29
52
 
30
53
  Use:
@@ -56,7 +79,7 @@ npm run norna:deploy:commit -- "Commit message"
56
79
 
57
80
  It builds, stages only allowed site changes, commits, pushes, and checks Pages.
58
81
  The allowlist is implemented in `scripts/deploy-site.mjs` and includes the
59
- site content file, selected config/static files, expected gallery images,
82
+ site content file, selected config/static files, expected generated images,
60
83
  generated image manifest, package files, `tsconfig.json`, `astro.config.mjs`,
61
84
  and `src/` changes.
62
85
 
package/docs/routes.md ADDED
@@ -0,0 +1,90 @@
1
+ # Routes
2
+
3
+ `site/content.md` is the homepage and builds to `/`. Optional route pages live
4
+ under `site/routes/<route-folder>/route-content.md` and build to first-level
5
+ URLs.
6
+
7
+ Routes use the same page frontmatter, section frontmatter, image rows, and
8
+ Markdown section model as the homepage. See [Content](content.md) for the page
9
+ and section model.
10
+
11
+ ## Route File
12
+
13
+ Add a first-level route by creating:
14
+
15
+ ```text
16
+ site/routes/about/route-content.md
17
+ ```
18
+
19
+ Minimal route page:
20
+
21
+ ```md
22
+ ---
23
+ title: About
24
+ description: About this site.
25
+ navigation:
26
+ label: About
27
+ order: 20
28
+ sections:
29
+ - id: intro
30
+ ---
31
+
32
+ ## Intro {#intro}
33
+
34
+ Text...
35
+ ```
36
+
37
+ The example above builds to `/about/`.
38
+
39
+ ## Slug
40
+
41
+ If `slug` is omitted, the route folder name is used. If `slug` is set, it must
42
+ use lowercase letters, numbers, and hyphens.
43
+
44
+ ```yaml
45
+ slug: about-the-work
46
+ ```
47
+
48
+ Keep the route folder and `slug` aligned unless you intentionally need a
49
+ different URL.
50
+
51
+ The homepage ignores `slug`.
52
+
53
+ ## Navigation
54
+
55
+ `navigation` may contain:
56
+
57
+ - `include`: optional boolean. Defaults to `true`.
58
+ - `label`: optional string. Defaults to `title`.
59
+ - `order`: optional integer. Defaults to `0` for the homepage and `100` for
60
+ route pages.
61
+
62
+ Current route navigation is intended for small sites. This guidance may change
63
+ as route support matures, but the present model is:
64
+
65
+ - A single-page site should normally use only page navigation between sections.
66
+ - A small multi-page site may use site navigation between routes plus page
67
+ navigation between sections on the current page.
68
+ - If a site needs many routes, deeply nested routes, or several navigation
69
+ levels, it has probably outgrown the current sticky-navigation model and may
70
+ need a different site structure or navigation system.
71
+
72
+ ## Route Images
73
+
74
+ Route images live under the route:
75
+
76
+ ```text
77
+ site/routes/about/images/intro/image.jpg
78
+ ```
79
+
80
+ Image references in route frontmatter still use only the filename:
81
+
82
+ ```yaml
83
+ sections:
84
+ - id: intro
85
+ gallery:
86
+ - image: image.jpg
87
+ alt: "Intro image."
88
+ ```
89
+
90
+ The image directory segment after `images/` should match the section id.
@@ -26,22 +26,26 @@ site/
26
26
  ```
27
27
 
28
28
  Use `NORNA_SITE_DIR` or `norna --site-dir <path>` to select another
29
- site directory. Commands started from a subdirectory walk upward until they find
30
- the selected site directory containing both `config.mjs` and `content.md`.
31
- `theme.md` is optional; omit it to use the engine's built-in presentation
32
- defaults.
29
+ site directory. Without an explicit site directory, commands first accept the
30
+ current directory when it contains both `config.mjs` and `content.md`.
31
+ Otherwise, commands started from a subdirectory walk upward until they find the
32
+ default `site/` directory containing those files.
33
+ `theme.md` is optional; omit it to use the engine's built-in visual defaults.
33
34
 
34
35
  ## Versioned Source Files
35
36
 
36
37
  Version these files in a site repository:
37
38
 
38
39
  - `site/config.mjs`: technical site configuration.
39
- - `site/theme.md`: optional site-wide visual theme, inline styles, and frame
40
- defaults.
40
+ - `site/theme.md`: optional site-wide visual theme, including layout, spacing,
41
+ image sizing, font, typography defaults, colors, inline styles, and frame
42
+ colors.
43
+ See [Theme](theme.md).
41
44
  - `site/content.md`: homepage page file with editable content, section
42
- definitions, gallery rows, alt text, and captions.
45
+ definitions, image rows, alt text, and captions. See [Content](content.md).
43
46
  - `site/images/<section-id>/`: original source images.
44
47
  - `site/routes/<route-folder>/route-content.md`: optional route page files.
48
+ See [Routes](routes.md).
45
49
  - `site/routes/<route-folder>/images/<section-id>/`: original source images
46
50
  for that route page.
47
51
  - `site/public/`: site-specific static public files.
@@ -66,16 +70,20 @@ Do not edit these by hand:
66
70
 
67
71
  Favicons are convention-based. Put files such as `favicon.svg`, `favicon.ico`,
68
72
  `favicon.png`, or `apple-touch-icon.png` in `site/public/`. The renderer emits
69
- icon links only for files that exist.
73
+ icon links only for files that exist and prefixes them with `site.basePath`
74
+ when the site is published below a path such as `/repository-name/`.
70
75
 
71
76
  ## Engine Repository Layout
72
77
 
73
78
  In this repository:
74
79
 
75
- - `bin/norna.mjs` dispatches public CLI commands.
80
+ - `bin/norna.mjs` launches the appropriate installed Norna version.
81
+ - `bin/norna-cli.mjs` dispatches public CLI commands.
76
82
  - `scripts/` contains validation, image, local preview, deploy, and test tools.
77
83
  - `src/` contains the Astro renderer, components, styles, and content schema.
78
84
  - `starters/basic/` is copied by `norna init <target-dir>` to create a
79
85
  site repository.
80
86
  - `fixtures/basic/site/` is used by engine regression tests.
81
- - `site/` is the local dog-gallery demo used by default in this repository.
87
+ - `examples/dog-gallery/site/` is the local visual dog example used by demo
88
+ builds and navigation diagnostics.
89
+ - `site/` is reserved for the local documentation site.
package/docs/theme.md ADDED
@@ -0,0 +1,292 @@
1
+ # Theme
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.
6
+
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.
10
+
11
+ ## Minimal Theme
12
+
13
+ ```yaml
14
+ ---
15
+ navigation:
16
+ brand: Example Site
17
+ layout:
18
+ pageWidth: 1180px
19
+ gutter:
20
+ desktop: clamp(1.25rem, 4vw, 3rem)
21
+ mobile: 1rem
22
+ spacing:
23
+ firstSectionTop:
24
+ desktop: clamp(1.875rem, 3vw, 2.75rem)
25
+ mobile: 1.375rem
26
+ sectionGap:
27
+ desktop: clamp(2.55rem, 4.2vw, 3.9rem)
28
+ mobile: 2.25rem
29
+ finalSectionBottom:
30
+ desktop: clamp(2.55rem, 4.2vw, 3.9rem)
31
+ mobile: 2.25rem
32
+ sectionHeadingToBody:
33
+ desktop: clamp(0.5625rem, 1.25vw, 0.75rem)
34
+ mobile: 0.4375rem
35
+ bodyToImages:
36
+ desktop: clamp(1.25rem, 2.5vw, 2rem)
37
+ mobile: 1.25rem
38
+ imageGap:
39
+ desktop: clamp(1.5rem, 3.5vw, 2.75rem)
40
+ mobile: 2.75rem
41
+ subheadingTop:
42
+ desktop: 2rem
43
+ mobile: 1.6rem
44
+ subheadingRuleTop:
45
+ desktop: 1rem
46
+ mobile: 0.8rem
47
+ gallery:
48
+ width: 900px
49
+ maxAvailableWidthPercent:
50
+ desktop: 100
51
+ mobile: 100
52
+ maxAvailableHeightPercent:
53
+ desktop: 74
54
+ mobile: 68
55
+ typography:
56
+ fontFamily: "Arial, 'Helvetica Neue', Helvetica, sans-serif"
57
+ preset: quiet-gallery
58
+ presentation:
59
+ backgroundColor: "#000000"
60
+ textColor: "#f7f4ee"
61
+ frame:
62
+ colors: presentation
63
+ ---
64
+ ```
65
+
66
+ Starter sites include a marked comment block such as
67
+ `norna:start theme-help` / `norna:end theme-help`. The block is only
68
+ explorable help text; YAML comments do not affect rendering. The active
69
+ configuration is the uncommented YAML below it.
70
+
71
+ ## Navigation
72
+
73
+ `navigation` is optional. It currently supports:
74
+
75
+ - `brand`: optional site-wide brand or home-link text shown in the site
76
+ navigation.
77
+
78
+ If `navigation.brand` is omitted, Norna uses the homepage `title` from
79
+ `site/content.md`. Use `navigation.brand` when the homepage title is editorial
80
+ or route-specific, but the navigation should keep a stable site name.
81
+
82
+ Example:
83
+
84
+ ```yaml
85
+ navigation:
86
+ brand: Norna
87
+ ```
88
+
89
+ ## Layout
90
+
91
+ `layout` is optional. It controls the outer page geometry:
92
+
93
+ - `pageWidth`: maximum width of the main page content area.
94
+ - `gutter`: side margin removed from the viewport before available content
95
+ width is calculated. Use either one CSS length for all viewports or
96
+ `desktop` / `mobile` values.
97
+ - `spacing`: vertical rhythm for sections, text, image rows, and Markdown
98
+ subheadings. Every spacing value accepts either one CSS length for all
99
+ viewports or `desktop` / `mobile` values.
100
+
101
+ Example:
102
+
103
+ ```yaml
104
+ layout:
105
+ pageWidth: 1180px
106
+ gutter:
107
+ desktop: clamp(1.25rem, 4vw, 3rem)
108
+ mobile: 1rem
109
+ spacing:
110
+ firstSectionTop:
111
+ desktop: clamp(1.875rem, 3vw, 2.75rem)
112
+ mobile: 1.375rem
113
+ sectionGap:
114
+ desktop: clamp(2.55rem, 4.2vw, 3.9rem)
115
+ mobile: 2.25rem
116
+ subheadingTop:
117
+ desktop: 2rem
118
+ mobile: 1.6rem
119
+ ```
120
+
121
+ If omitted, Norna uses `1180px` for `pageWidth`, desktop
122
+ `clamp(1.25rem, 4vw, 3rem)` for `gutter`, mobile `1rem`, and the spacing
123
+ defaults shown in the minimal theme example.
124
+
125
+ Spacing keys:
126
+
127
+ - `firstSectionTop`: space above the first section heading.
128
+ - `sectionGap`: space above each following section.
129
+ - `finalSectionBottom`: space below the final section.
130
+ - `sectionHeadingToBody`: space from a section heading to its body text.
131
+ - `bodyToImages`: space from section body text to image rows.
132
+ - `imageGap`: space between image rows.
133
+ - `subheadingTop`: space above Markdown `###` subheadings inside body text.
134
+ - `subheadingRuleTop`: space between the rule above a Markdown `###`
135
+ subheading and the subheading text.
136
+
137
+ ## Image Sizing
138
+
139
+ `gallery` is optional. It controls image sizing:
140
+
141
+ - `width`: hard maximum rendered image area width for images, captions, and
142
+ aligned text.
143
+ - `maxAvailableWidthPercent`: maximum share of available width after gutters.
144
+ - `maxAvailableHeightPercent`: maximum share of viewport height used by
145
+ images.
146
+
147
+ Example:
148
+
149
+ ```yaml
150
+ gallery:
151
+ width: 900px
152
+ maxAvailableWidthPercent:
153
+ desktop: 100
154
+ mobile: 100
155
+ maxAvailableHeightPercent:
156
+ desktop: 74
157
+ mobile: 68
158
+ ```
159
+
160
+ If omitted, Norna uses `900px`, full available width, and image height limits of
161
+ desktop `74` / mobile `68`.
162
+
163
+ ## Typography
164
+
165
+ Top-level `typography` is the site-wide typographic base. It supports:
166
+
167
+ - `fontFamily`: global CSS font-family stack.
168
+ - `preset`: built-in typography preset.
169
+ - `overrides`: focused changes to preset values.
170
+
171
+ Example:
172
+
173
+ ```yaml
174
+ typography:
175
+ fontFamily: "Arial, 'Helvetica Neue', Helvetica, sans-serif"
176
+ preset: quiet-gallery
177
+ overrides:
178
+ headings:
179
+ h2:
180
+ size: medium
181
+ h3:
182
+ size: small
183
+ body:
184
+ lineHeight: 1.55
185
+ ```
186
+
187
+ Use `norna typography presets` to inspect built-in preset values and
188
+ `norna typography show` to inspect the resolved typography for the selected
189
+ site. See [Typography](typography.md).
190
+
191
+ ## Presentation
192
+
193
+ `presentation` is optional. It can contain:
194
+
195
+ - `backgroundColor`: optional quoted hex color in `#rgb`, `#rrggbb`, or
196
+ `#rrggbbaa` form.
197
+ - `textColor`: optional quoted hex color in `#rgb`, `#rrggbb`, or
198
+ `#rrggbbaa` form.
199
+ - `inlineStyles`: optional named inline text styles.
200
+
201
+ Example:
202
+
203
+ ```yaml
204
+ presentation:
205
+ backgroundColor: "#101418"
206
+ textColor: "#f4f1ea"
207
+ ```
208
+
209
+ ## Page And Section Overrides
210
+
211
+ Site-wide presentation belongs in `site/theme.md`. Page-level presentation in a
212
+ page file is always an override on top of the theme:
213
+
214
+ ```yaml
215
+ presentation:
216
+ typography:
217
+ overrides:
218
+ headings:
219
+ h2:
220
+ size: large
221
+ body:
222
+ paragraphSpacing: 1em
223
+ ```
224
+
225
+ Section-specific presentation belongs under `sections[].presentation`:
226
+
227
+ ```yaml
228
+ sections:
229
+ - id: intro
230
+ presentation:
231
+ backgroundColor: "#161616"
232
+ textColor: "#ffffff"
233
+ typography:
234
+ preset: statement
235
+ ```
236
+
237
+ If a page omits `presentation`, it uses the theme presentation unchanged. If a
238
+ section omits `presentation`, it uses the resolved page presentation.
239
+
240
+ Configured section backgrounds render as full-width horizontal bands while the
241
+ section content keeps the normal page and image widths. The top spacing
242
+ before the first heading, the spacing between sections, and the spacing after
243
+ the final section are part of the section background.
244
+
245
+ Configured section text colors apply to section headings, Markdown text,
246
+ Markdown subheadings, and image captions. Links keep the global accent color.
247
+
248
+ ## Frame Colors
249
+
250
+ `frame.colors` controls the sticky navigation and footer colors.
251
+
252
+ Allowed values:
253
+
254
+ - `presentation`: use the resolved presentation colors for this level.
255
+ - `theme`: use the site theme frame colors. This is useful in page-level
256
+ frontmatter.
257
+ - explicit colors:
258
+
259
+ ```yaml
260
+ frame:
261
+ colors:
262
+ backgroundColor: "#111111"
263
+ textColor: "#eeeeee"
264
+ ```
265
+
266
+ The sticky section navigation row and footer use the resolved frame colors, not
267
+ section-specific presentation.
268
+
269
+ ## Inline Styles
270
+
271
+ `presentation.inlineStyles` defines named inline text styles that can be used
272
+ from Markdown:
273
+
274
+ ```yaml
275
+ presentation:
276
+ inlineStyles:
277
+ highlight:
278
+ color: "#ffd84d"
279
+ ```
280
+
281
+ Inline style names must match `^[a-z][a-z0-9-]*$`. Each style currently
282
+ supports a required `color` field using the same quoted hex color format as
283
+ `textColor`.
284
+
285
+ Apply an inline style in Markdown with `[text]{.style-name}`:
286
+
287
+ ```md
288
+ This sentence contains [highlighted text]{.highlight}.
289
+ ```
290
+
291
+ `content:check` fails if Markdown uses an inline style that is not defined in
292
+ `site/theme.md` `presentation.inlineStyles`.
@@ -0,0 +1,144 @@
1
+ # Typography
2
+
3
+ `norna` typography is configured in `site/theme.md` through a site-wide font,
4
+ presets, and optional overrides.
5
+
6
+ The normal place to choose a site-wide typography preset is the top-level
7
+ `typography` block in `site/theme.md`.
8
+ Page and section files may override the theme when a page or section needs a
9
+ different presentation.
10
+
11
+ ## Presets
12
+
13
+ Available presets:
14
+
15
+ - `quiet-gallery`: the default for image-led sites. Text is restrained and
16
+ supports the images without dominating the page.
17
+ - `compact-gallery`: tighter typography for many sections, many images, or
18
+ short information blocks.
19
+ - `text-forward`: more generous body text for pages where longer text carries
20
+ more of the experience.
21
+ - `statement`: stronger type for introductions, first sections, and short
22
+ programmatic statements. Use it sparingly, usually as a section override.
23
+
24
+ If theme typography is omitted, `quiet-gallery` is used.
25
+
26
+ Presets define `headings.h1` through `headings.h4`, `body`, and `caption`.
27
+ They differ primarily through heading scale, alignment, line height, paragraph
28
+ spacing, caption treatment, and intended use. Choose larger or smaller type
29
+ with focused overrides when a specific page or section needs it.
30
+
31
+ Use this command to inspect the exact preset values shipped with the installed
32
+ engine:
33
+
34
+ ```sh
35
+ norna typography presets
36
+ ```
37
+
38
+ Use this command to inspect the effective values for the selected site after
39
+ presets and overrides have been applied:
40
+
41
+ ```sh
42
+ norna typography show
43
+ ```
44
+
45
+ The output includes the site theme, every page route, and every section. Each
46
+ resolved value shows its `source`; values inherited by a page or section are
47
+ also marked with `inherited: true`.
48
+
49
+ ## Configuration Shape
50
+
51
+ ```yaml
52
+ typography:
53
+ fontFamily: "Arial, 'Helvetica Neue', Helvetica, sans-serif"
54
+ preset: quiet-gallery
55
+ overrides:
56
+ headings:
57
+ h2:
58
+ size: medium
59
+ h3:
60
+ size: small
61
+ body:
62
+ paragraphSpacing: 0.8em
63
+ ```
64
+
65
+ The typographic roles are:
66
+
67
+ - `headings.h1`: reserved for page-level Markdown `#` headings if the content
68
+ model starts supporting them.
69
+ - `headings.h2`: Markdown `##` section headings.
70
+ - `headings.h3`: Markdown `###` subheadings inside section body text.
71
+ - `headings.h4`: Markdown `####` subheadings inside section body text.
72
+ - `body`: Markdown body text inside sections.
73
+ - `caption`: image captions.
74
+
75
+ Allowed alignment values are `left`, `center`, and `right`. Alignment can be
76
+ responsive:
77
+
78
+ ```yaml
79
+ align:
80
+ desktop: left
81
+ mobile: center
82
+ ```
83
+
84
+ Allowed size values are `small`, `medium`, `large`, and `xlarge`. `medium` is
85
+ the normal reading size. Use `small` for quieter supporting text, and use
86
+ `large` or `xlarge` only when a page or section needs stronger emphasis.
87
+ Headings use their own scale, but follow the same principle: `medium` is the
88
+ normal section heading size, not a hero size. Norna may render the first
89
+ section heading as an HTML `h1` for document structure, but its visual
90
+ typography still follows the Markdown level the user wrote: `##` uses
91
+ `headings.h2`.
92
+
93
+ `lineHeight` is a unitless number from `1` through `3`. `spacing` and
94
+ `paragraphSpacing` are CSS lengths such as `0`, `0.8em`, `1rem`, or `12px`.
95
+
96
+ Supported override fields:
97
+
98
+ - `headings.h1.align`, `headings.h1.size`, `headings.h1.lineHeight`,
99
+ `headings.h1.spacing`
100
+ - `headings.h2.align`, `headings.h2.size`, `headings.h2.lineHeight`,
101
+ `headings.h2.spacing`
102
+ - `headings.h3.align`, `headings.h3.size`, `headings.h3.lineHeight`,
103
+ `headings.h3.spacing`
104
+ - `headings.h4.align`, `headings.h4.size`, `headings.h4.lineHeight`,
105
+ `headings.h4.spacing`
106
+ - `body.align`, `body.size`, `body.lineHeight`, `body.paragraphSpacing`
107
+ - `caption.align`, `caption.size`, `caption.lineHeight`, `caption.spacing`
108
+
109
+ ## Inheritance
110
+
111
+ Theme typography is the site-wide base:
112
+
113
+ ```yaml
114
+ # site/theme.md
115
+ typography:
116
+ fontFamily: "Arial, 'Helvetica Neue', Helvetica, sans-serif"
117
+ preset: quiet-gallery
118
+ ```
119
+
120
+ A page-level `presentation.typography.preset` changes the typographic base for
121
+ that page. A section-level `sections[].presentation.typography.preset` changes
122
+ the typographic base for that section.
123
+
124
+ If a section sets `typography.preset`, that section starts from that preset. If
125
+ a section only sets `typography.overrides`, it keeps the resolved page preset
126
+ and changes only the specified values.
127
+
128
+ Example section override:
129
+
130
+ ```yaml
131
+ sections:
132
+ - id: intro
133
+ presentation:
134
+ typography:
135
+ preset: statement
136
+ overrides:
137
+ body:
138
+ paragraphSpacing: 0.7em
139
+ ```
140
+
141
+ Centered text uses narrower text widths. Left- or right-aligned heading and body
142
+ text use the calculated image layout width so text edges line up with images
143
+ after layout gutters and image limits are applied. Captions are normally
144
+ centered.