@janga/norna 0.7.6 → 0.7.7
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.
- package/README.md +5 -5
- package/astro.config.mjs +76 -0
- package/bin/norna-cli.mjs +2 -2
- package/docs/README.md +3 -3
- package/docs/commands.md +6 -6
- package/docs/configuration.md +3 -2
- package/docs/content.md +152 -91
- package/docs/design/site-examples-structure.md +1 -1
- package/docs/engine-development.md +3 -3
- package/docs/getting-started.md +4 -3
- package/docs/images-and-metadata.md +112 -20
- package/docs/routes.md +9 -12
- package/docs/site-structure.md +4 -3
- package/docs/theme.md +8 -7
- package/docs/typography.md +5 -5
- package/examples/dog-gallery/site/content.md +41 -45
- package/examples/dog-gallery/site/routes/010-dog-care/route-content.md +1 -3
- package/fixtures/basic/site/content.md +2 -4
- package/fixtures/content-model-v2/.astro/collections/site.schema.json +776 -0
- package/fixtures/content-model-v2/.astro/collections/theme.schema.json +668 -0
- package/fixtures/content-model-v2/.astro/content-assets.mjs +4 -0
- package/fixtures/content-model-v2/.astro/content-modules.mjs +1 -0
- package/fixtures/content-model-v2/.astro/content.d.ts +175 -0
- package/fixtures/content-model-v2/.astro/data-store.json +1 -0
- package/fixtures/content-model-v2/.astro/dev-local.json +8 -0
- package/fixtures/content-model-v2/.astro/dev.json +13 -0
- package/fixtures/content-model-v2/.astro/dev.log +231 -0
- package/fixtures/content-model-v2/.astro/settings.json +5 -0
- package/fixtures/content-model-v2/.astro/types.d.ts +2 -0
- package/fixtures/content-model-v2/dist/_astro/GalleryGrid.astro_astro_type_script_index_0_lang.B0kxDyGz.js +1 -0
- package/fixtures/content-model-v2/dist/_astro/SitePage.BbfZub4g.css +1 -0
- package/fixtures/content-model-v2/dist/guide/index.html +3 -0
- package/fixtures/content-model-v2/dist/images/generated/intro/detail-27930b14-480.webp +0 -0
- package/fixtures/content-model-v2/dist/images/generated/intro/detail-27930b14-768.webp +0 -0
- package/fixtures/content-model-v2/dist/images/generated/intro/detail-27930b14-971.webp +0 -0
- package/fixtures/content-model-v2/dist/images/generated/intro/duplicate-49c98f6c-480.webp +0 -0
- package/fixtures/content-model-v2/dist/images/generated/intro/duplicate-49c98f6c-768.webp +0 -0
- package/fixtures/content-model-v2/dist/images/generated/intro/duplicate-49c98f6c-971.webp +0 -0
- package/fixtures/content-model-v2/dist/images/generated/intro/hero-6d588a83-480.webp +0 -0
- package/fixtures/content-model-v2/dist/images/generated/intro/hero-6d588a83-768.webp +0 -0
- package/fixtures/content-model-v2/dist/images/generated/intro/hero-6d588a83-971.webp +0 -0
- package/fixtures/content-model-v2/dist/images/generated/plain/image-3770d763-1080.webp +0 -0
- package/fixtures/content-model-v2/dist/images/generated/plain/image-3770d763-1440.webp +0 -0
- package/fixtures/content-model-v2/dist/images/generated/plain/image-3770d763-1600.webp +0 -0
- package/fixtures/content-model-v2/dist/images/generated/plain/image-3770d763-480.webp +0 -0
- package/fixtures/content-model-v2/dist/images/generated/plain/image-3770d763-768.webp +0 -0
- package/fixtures/content-model-v2/dist/images/generated/routes/010-guide/images/intro/duplicate-5cf614d2-480.webp +0 -0
- package/fixtures/content-model-v2/dist/images/generated/routes/010-guide/images/intro/duplicate-5cf614d2-768.webp +0 -0
- package/fixtures/content-model-v2/dist/images/generated/routes/010-guide/images/intro/duplicate-5cf614d2-960.webp +0 -0
- package/fixtures/content-model-v2/dist/images/generated/timed/slide-one-3770d763-1080.webp +0 -0
- package/fixtures/content-model-v2/dist/images/generated/timed/slide-one-3770d763-1440.webp +0 -0
- package/fixtures/content-model-v2/dist/images/generated/timed/slide-one-3770d763-1600.webp +0 -0
- package/fixtures/content-model-v2/dist/images/generated/timed/slide-one-3770d763-480.webp +0 -0
- package/fixtures/content-model-v2/dist/images/generated/timed/slide-one-3770d763-768.webp +0 -0
- package/fixtures/content-model-v2/dist/images/generated/timed/slide-three-5bdec65e-1080.webp +0 -0
- package/fixtures/content-model-v2/dist/images/generated/timed/slide-three-5bdec65e-1440.webp +0 -0
- package/fixtures/content-model-v2/dist/images/generated/timed/slide-three-5bdec65e-1600.webp +0 -0
- package/fixtures/content-model-v2/dist/images/generated/timed/slide-three-5bdec65e-480.webp +0 -0
- package/fixtures/content-model-v2/dist/images/generated/timed/slide-three-5bdec65e-768.webp +0 -0
- package/fixtures/content-model-v2/dist/images/generated/timed/slide-two-26c08aee-1080.webp +0 -0
- package/fixtures/content-model-v2/dist/images/generated/timed/slide-two-26c08aee-1440.webp +0 -0
- package/fixtures/content-model-v2/dist/images/generated/timed/slide-two-26c08aee-1600.webp +0 -0
- package/fixtures/content-model-v2/dist/images/generated/timed/slide-two-26c08aee-480.webp +0 -0
- package/fixtures/content-model-v2/dist/images/generated/timed/slide-two-26c08aee-768.webp +0 -0
- package/fixtures/content-model-v2/dist/index.html +8 -0
- package/fixtures/content-model-v2/node_modules/.vite/deps/_metadata.json +80 -0
- package/fixtures/content-model-v2/node_modules/.vite/deps/astro-D_GIpJIE.js +434 -0
- package/fixtures/content-model-v2/node_modules/.vite/deps/astro-D_GIpJIE.js.map +1 -0
- package/fixtures/content-model-v2/node_modules/.vite/deps/astro_n_aria-query.js +6390 -0
- package/fixtures/content-model-v2/node_modules/.vite/deps/astro_n_aria-query.js.map +1 -0
- package/fixtures/content-model-v2/node_modules/.vite/deps/astro_n_axobject-query.js +2702 -0
- package/fixtures/content-model-v2/node_modules/.vite/deps/astro_n_axobject-query.js.map +1 -0
- package/fixtures/content-model-v2/node_modules/.vite/deps/astro_n_html-escaper.js +65 -0
- package/fixtures/content-model-v2/node_modules/.vite/deps/astro_n_html-escaper.js.map +1 -0
- package/fixtures/content-model-v2/node_modules/.vite/deps/astro_runtime_client_dev-toolbar_entrypoint__js.js +455 -0
- package/fixtures/content-model-v2/node_modules/.vite/deps/astro_runtime_client_dev-toolbar_entrypoint__js.js.map +1 -0
- package/fixtures/content-model-v2/node_modules/.vite/deps/audit-DM9Hkl5B.js +1534 -0
- package/fixtures/content-model-v2/node_modules/.vite/deps/audit-DM9Hkl5B.js.map +1 -0
- package/fixtures/content-model-v2/node_modules/.vite/deps/embla-carousel.js +1389 -0
- package/fixtures/content-model-v2/node_modules/.vite/deps/embla-carousel.js.map +1 -0
- package/fixtures/content-model-v2/node_modules/.vite/deps/highlight-DnZ1ULOL.js +48 -0
- package/fixtures/content-model-v2/node_modules/.vite/deps/highlight-DnZ1ULOL.js.map +1 -0
- package/fixtures/content-model-v2/node_modules/.vite/deps/icons-RyebKi45.js +42 -0
- package/fixtures/content-model-v2/node_modules/.vite/deps/icons-RyebKi45.js.map +1 -0
- package/fixtures/content-model-v2/node_modules/.vite/deps/package.json +3 -0
- package/fixtures/content-model-v2/node_modules/.vite/deps/rolldown-runtime-BvCyGRYZ.js +4 -0
- package/fixtures/content-model-v2/node_modules/.vite/deps/settings-DaU-gNnK.js +190 -0
- package/fixtures/content-model-v2/node_modules/.vite/deps/settings-DaU-gNnK.js.map +1 -0
- package/fixtures/content-model-v2/node_modules/.vite/deps/toolbar-63PA619H.js +458 -0
- package/fixtures/content-model-v2/node_modules/.vite/deps/toolbar-63PA619H.js.map +1 -0
- package/fixtures/content-model-v2/node_modules/.vite/deps/ui-library--bkcNSYz.js +1016 -0
- package/fixtures/content-model-v2/node_modules/.vite/deps/ui-library--bkcNSYz.js.map +1 -0
- package/fixtures/content-model-v2/node_modules/.vite/deps/window-jPkpKVcy.js +32 -0
- package/fixtures/content-model-v2/node_modules/.vite/deps/window-jPkpKVcy.js.map +1 -0
- package/fixtures/content-model-v2/node_modules/.vite/deps/xray-BXCHpEJP.js +111 -0
- package/fixtures/content-model-v2/node_modules/.vite/deps/xray-BXCHpEJP.js.map +1 -0
- package/fixtures/content-model-v2/site/.norna/generated-images.json +210 -0
- package/fixtures/content-model-v2/site/config.mjs +11 -0
- package/fixtures/content-model-v2/site/content.md +84 -0
- package/fixtures/content-model-v2/site/images/card-section/adopt.svg +9 -0
- package/fixtures/content-model-v2/site/images/card-section/foster.svg +12 -0
- package/fixtures/content-model-v2/site/images/intro/detail.jpg +0 -0
- package/fixtures/content-model-v2/site/images/intro/duplicate.jpg +0 -0
- package/fixtures/content-model-v2/site/images/intro/hero.jpg +0 -0
- package/fixtures/content-model-v2/site/images/plain/image.jpg +0 -0
- package/fixtures/content-model-v2/site/images/timed/slide-one.jpg +0 -0
- package/fixtures/content-model-v2/site/images/timed/slide-three.jpg +0 -0
- package/fixtures/content-model-v2/site/images/timed/slide-two.jpg +0 -0
- package/fixtures/content-model-v2/site/routes/010-guide/images/intro/duplicate.jpg +0 -0
- package/fixtures/content-model-v2/site/routes/010-guide/route-content.md +17 -0
- package/fixtures/content-model-v2/site/theme.md +9 -0
- package/package.json +3 -2
- package/scripts/deploy-site.mjs +11 -4
- package/scripts/dev-local.mjs +6 -0
- package/scripts/generate-images.mjs +132 -56
- package/scripts/lib/image-dimensions.mjs +26 -0
- package/scripts/lib/norna-markdown-blocks.mjs +643 -0
- package/scripts/lib/site-content.mjs +31 -29
- package/scripts/show-typography.mjs +17 -9
- package/scripts/sync-content-sections.mjs +280 -411
- package/scripts/test-content-check.mjs +59 -45
- package/scripts/test-content-model-v2.mjs +998 -0
- package/scripts/test-engine-commands.mjs +1 -1
- package/scripts/test-package-check.mjs +36 -8
- package/scripts/test-temporary-visibility.mjs +3 -6
- package/src/components/CardList.astro +77 -0
- package/src/components/GalleryGrid.astro +22 -12
- package/src/components/SiteNavigation.astro +5 -4
- package/src/components/SitePage.astro +9 -2
- package/src/components/SiteSection.astro +35 -13
- package/src/content.config.ts +4 -17
- package/src/lib/generatedImages.ts +50 -10
- package/src/lib/sectionContent.ts +130 -35
- package/src/styles/global.css +187 -0
- package/starters/basic/site/content.md +10 -6
- package/starters/project/site/content.md +0 -9
- package/starters/project/site/routes/010-guide/route-content.md +0 -5
|
@@ -1,26 +1,78 @@
|
|
|
1
1
|
# Images And Metadata
|
|
2
2
|
|
|
3
|
-
This document describes
|
|
3
|
+
This document describes Norna's image pipeline. Site repositories own their
|
|
4
4
|
source images and any copyright or licensing policy for those images.
|
|
5
5
|
|
|
6
|
-
## Source Images
|
|
6
|
+
## Managed Source Images
|
|
7
7
|
|
|
8
|
-
|
|
9
|
-
`
|
|
8
|
+
Norna-managed local images are referenced from Markdown with
|
|
9
|
+
`norna-image-stack` or `norna-image-carousel` blocks. See
|
|
10
|
+
[Content](content.md#image-blocks) for the block syntax.
|
|
11
|
+
|
|
12
|
+
Homepage source images live under:
|
|
13
|
+
|
|
14
|
+
```text
|
|
15
|
+
site/images/<section-id>/
|
|
16
|
+
```
|
|
17
|
+
|
|
18
|
+
Route source images live under:
|
|
19
|
+
|
|
20
|
+
```text
|
|
21
|
+
site/routes/<NNN-route-id>/images/<section-id>/
|
|
22
|
+
```
|
|
10
23
|
|
|
11
24
|
Supported source extensions:
|
|
12
25
|
|
|
13
26
|
- `.jpg`
|
|
14
27
|
- `.jpeg`
|
|
15
28
|
- `.png`
|
|
29
|
+
- `.svg`
|
|
30
|
+
|
|
31
|
+
Image block references use only the filename:
|
|
32
|
+
|
|
33
|
+
````md
|
|
34
|
+
```norna-image-stack
|
|
35
|
+
- image: portrait.jpg
|
|
36
|
+
alt: Optional alt text.
|
|
37
|
+
caption: Optional caption.
|
|
38
|
+
```
|
|
39
|
+
````
|
|
16
40
|
|
|
17
|
-
|
|
18
|
-
|
|
19
|
-
|
|
41
|
+
`alt` and `caption` are optional. If `alt` is omitted, Norna renders an empty
|
|
42
|
+
alt attribute.
|
|
43
|
+
|
|
44
|
+
For generated or edited images, keep provenance near the image in a source-only
|
|
45
|
+
comment. Norna removes these comments from rendered HTML:
|
|
46
|
+
|
|
47
|
+
```md
|
|
48
|
+
<!-- norna-image-provenance:
|
|
49
|
+
image: portrait.jpg
|
|
50
|
+
source: generated
|
|
51
|
+
prompt: Short prompt or editing note.
|
|
52
|
+
-->
|
|
53
|
+
```
|
|
20
54
|
|
|
21
|
-
|
|
55
|
+
Filenames do not have to be globally unique for the site to be valid.
|
|
56
|
+
Automatic sync only moves files when the filename identifies exactly one source
|
|
57
|
+
candidate within the current page or route.
|
|
22
58
|
|
|
23
|
-
|
|
59
|
+
## Markdown Images
|
|
60
|
+
|
|
61
|
+
Use ordinary Markdown images for external images or static public assets:
|
|
62
|
+
|
|
63
|
+
```md
|
|
64
|
+

|
|
65
|
+

|
|
66
|
+
```
|
|
67
|
+
|
|
68
|
+
Relative local Markdown images such as `` are not
|
|
69
|
+
managed by Norna. `content:check` warns about them because Norna cannot
|
|
70
|
+
validate, process, or sync those files through the image pipeline.
|
|
71
|
+
|
|
72
|
+
## Generated Variants And Static SVG
|
|
73
|
+
|
|
74
|
+
For raster images, `npm run norna:images` and `npm run norna:build` generate
|
|
75
|
+
WebP files in:
|
|
24
76
|
|
|
25
77
|
```text
|
|
26
78
|
site/.norna/public/images/generated/
|
|
@@ -46,6 +98,19 @@ example-work-1a2b3c4d-1440.webp
|
|
|
46
98
|
When a source image changes, the generated URL changes too. This avoids stale
|
|
47
99
|
browser, CDN, and GitHub Actions cache entries at the old URL.
|
|
48
100
|
|
|
101
|
+
SVG files are managed by the same Markdown image blocks, validation and sync
|
|
102
|
+
model, but they are not rasterized and do not get WebP variants. Norna copies
|
|
103
|
+
the SVG source to:
|
|
104
|
+
|
|
105
|
+
```text
|
|
106
|
+
site/.norna/public/images/original/
|
|
107
|
+
```
|
|
108
|
+
|
|
109
|
+
The copied SVG filename includes the source hash. If the SVG has a `viewBox` or
|
|
110
|
+
numeric `width` and `height`, Norna stores that ratio in the image manifest so
|
|
111
|
+
the existing image layout can size it like other images. If no intrinsic aspect
|
|
112
|
+
ratio can be read, the SVG is still rendered directly.
|
|
113
|
+
|
|
49
114
|
## Manifest
|
|
50
115
|
|
|
51
116
|
The generated image manifest is:
|
|
@@ -54,13 +119,15 @@ The generated image manifest is:
|
|
|
54
119
|
site/.norna/generated-images.json
|
|
55
120
|
```
|
|
56
121
|
|
|
57
|
-
It is versioned site state.
|
|
58
|
-
output version, and generated variant paths.
|
|
59
|
-
|
|
60
|
-
|
|
122
|
+
It is versioned site state. For raster images, it stores source hashes,
|
|
123
|
+
original dimensions, output version, and generated variant paths. For static
|
|
124
|
+
SVG images, it stores the source hash, copied public path, output version, and
|
|
125
|
+
intrinsic dimensions when they can be read. The image pipeline reuses generated
|
|
126
|
+
or copied files only when the manifest entry matches the current source hash
|
|
127
|
+
and output version, and all expected output files exist.
|
|
61
128
|
|
|
62
|
-
Generated files under `site/.norna/public/` are build-preparation output
|
|
63
|
-
|
|
129
|
+
Generated files under `site/.norna/public/` are build-preparation output and
|
|
130
|
+
should not be versioned.
|
|
64
131
|
|
|
65
132
|
## Metadata Behavior
|
|
66
133
|
|
|
@@ -70,10 +137,35 @@ copyright metadata.
|
|
|
70
137
|
Generated WebP files are created with ImageMagick using `-strip`, so embedded
|
|
71
138
|
metadata is not a publication mechanism for generated variants. Keep licensing,
|
|
72
139
|
credits, copyright notices, alt text, and captions in site-owned files such as
|
|
73
|
-
`site/content.md`, `COPYRIGHT.md`, or other site
|
|
140
|
+
`site/content.md`, route content files, `COPYRIGHT.md`, or other site
|
|
141
|
+
documentation.
|
|
74
142
|
|
|
75
143
|
If a site wants embedded metadata in original source files, that process is
|
|
76
|
-
outside the current
|
|
144
|
+
outside the current Norna command surface.
|
|
145
|
+
|
|
146
|
+
## AI-Generated Images
|
|
147
|
+
|
|
148
|
+
For AI-generated images, keep provenance and the generation prompt in a
|
|
149
|
+
Markdown comment near the image block. This makes the image maintainable as
|
|
150
|
+
content: future editors can understand where it came from and regenerate or
|
|
151
|
+
revise it without reverse-engineering the asset.
|
|
152
|
+
|
|
153
|
+
````md
|
|
154
|
+
<!--
|
|
155
|
+
AI image prompt for workflow.png:
|
|
156
|
+
A clean editorial illustration of ordinary project files becoming a small
|
|
157
|
+
static website, restrained colors, readable composition, no text in the image.
|
|
158
|
+
-->
|
|
159
|
+
|
|
160
|
+
```norna-image-stack
|
|
161
|
+
- image: workflow.png
|
|
162
|
+
alt: Abstract illustration of project files becoming a website.
|
|
163
|
+
caption: Generated illustration.
|
|
164
|
+
```
|
|
165
|
+
````
|
|
166
|
+
|
|
167
|
+
This is a maintenance rule for real editorial images. It is not necessary for
|
|
168
|
+
throwaway test fixtures or examples where the prompt has no practical value.
|
|
77
169
|
|
|
78
170
|
## GitHub Actions Cache
|
|
79
171
|
|
|
@@ -83,6 +175,6 @@ The starter workflow caches:
|
|
|
83
175
|
site/.norna/public/images/generated
|
|
84
176
|
```
|
|
85
177
|
|
|
86
|
-
The cache key should include `site/.norna/generated-images.json` so
|
|
87
|
-
|
|
88
|
-
|
|
178
|
+
The cache key should include `site/.norna/generated-images.json` so unchanged
|
|
179
|
+
generated variants can be restored during deploy. With a cache miss or a
|
|
180
|
+
changed source hash, variants are rebuilt from source images.
|
package/docs/routes.md
CHANGED
|
@@ -4,9 +4,9 @@
|
|
|
4
4
|
under `site/routes/<NNN-route-id>/route-content.md` and build to first-level
|
|
5
5
|
URLs.
|
|
6
6
|
|
|
7
|
-
Routes use the same page frontmatter, section
|
|
8
|
-
Markdown section model as the homepage. See [Content](content.md)
|
|
9
|
-
and section model.
|
|
7
|
+
Routes use the same page frontmatter, optional section metadata, Norna image
|
|
8
|
+
blocks, and Markdown section model as the homepage. See [Content](content.md)
|
|
9
|
+
for the page and section model.
|
|
10
10
|
|
|
11
11
|
## Route Directory Format
|
|
12
12
|
|
|
@@ -61,8 +61,6 @@ title: About
|
|
|
61
61
|
description: About this site.
|
|
62
62
|
navigation:
|
|
63
63
|
label: About
|
|
64
|
-
sections:
|
|
65
|
-
- id: intro
|
|
66
64
|
---
|
|
67
65
|
|
|
68
66
|
## Intro {#intro}
|
|
@@ -99,14 +97,13 @@ Route images live under the physical route directory:
|
|
|
99
97
|
site/routes/010-about/images/intro/image.jpg
|
|
100
98
|
```
|
|
101
99
|
|
|
102
|
-
Image references in route
|
|
100
|
+
Image references in route content still use only the filename:
|
|
103
101
|
|
|
104
|
-
|
|
105
|
-
|
|
106
|
-
|
|
107
|
-
|
|
108
|
-
- image: image.jpg
|
|
109
|
-
alt: "Intro image."
|
|
102
|
+
````md
|
|
103
|
+
```norna-image-stack
|
|
104
|
+
- image: image.jpg
|
|
105
|
+
alt: Intro image.
|
|
110
106
|
```
|
|
107
|
+
````
|
|
111
108
|
|
|
112
109
|
The image directory segment after `images/` should match the section id.
|
package/docs/site-structure.md
CHANGED
|
@@ -41,8 +41,9 @@ Version these files in a site repository:
|
|
|
41
41
|
image sizing, font, typography defaults, colors, inline styles, and frame
|
|
42
42
|
colors.
|
|
43
43
|
See [Theme](theme.md).
|
|
44
|
-
- `site/content.md`: homepage page file with editable content,
|
|
45
|
-
|
|
44
|
+
- `site/content.md`: homepage page file with editable content, Markdown
|
|
45
|
+
sections, optional section metadata, image blocks, alt text, and captions.
|
|
46
|
+
See [Content](content.md).
|
|
46
47
|
- `site/images/<section-id>/`: original source images.
|
|
47
48
|
- `site/routes/<NNN-route-id>/route-content.md`: optional route page files.
|
|
48
49
|
See [Routes](routes.md).
|
|
@@ -50,7 +51,7 @@ Version these files in a site repository:
|
|
|
50
51
|
for that route page.
|
|
51
52
|
- `site/public/`: site-specific static public files.
|
|
52
53
|
- `site/.norna/generated-images.json`: generated image manifest used to
|
|
53
|
-
decide whether WebP variants can be reused.
|
|
54
|
+
decide whether WebP variants and copied managed SVG files can be reused.
|
|
54
55
|
- `.github/workflows/deploy.yml`: site-owned GitHub Pages workflow.
|
|
55
56
|
- `package.json` and `package-lock.json`: scripts and pinned engine dependency.
|
|
56
57
|
|
package/docs/theme.md
CHANGED
|
@@ -73,9 +73,9 @@ navigation:
|
|
|
73
73
|
`desktop` / `mobile` values.
|
|
74
74
|
- `density`: default structural spacing profile. Allowed values are `compact`,
|
|
75
75
|
`normal`, and `airy`.
|
|
76
|
-
- `spacing`: optional structural spacing overrides for sections and
|
|
77
|
-
|
|
78
|
-
`desktop` / `mobile` values.
|
|
76
|
+
- `spacing`: optional structural spacing overrides for sections and Norna
|
|
77
|
+
image blocks. Every spacing value accepts either one CSS length for all
|
|
78
|
+
viewports or `desktop` / `mobile` values.
|
|
79
79
|
|
|
80
80
|
Example:
|
|
81
81
|
|
|
@@ -104,8 +104,8 @@ Spacing keys:
|
|
|
104
104
|
- `firstSectionTop`: space above the first section heading.
|
|
105
105
|
- `sectionGap`: space above each following section.
|
|
106
106
|
- `finalSectionBottom`: space below the final section.
|
|
107
|
-
- `bodyToImages`: space from section body text to image
|
|
108
|
-
- `imageGap`: space between
|
|
107
|
+
- `bodyToImages`: space from section body text to Norna image blocks.
|
|
108
|
+
- `imageGap`: space between stacked images or carousel blocks.
|
|
109
109
|
|
|
110
110
|
Text-near spacing, such as spacing after headings, spacing before Markdown
|
|
111
111
|
subheadings, paragraph spacing, and caption spacing, belongs to
|
|
@@ -206,11 +206,12 @@ presentation:
|
|
|
206
206
|
paragraphSpacing: 1em
|
|
207
207
|
```
|
|
208
208
|
|
|
209
|
-
Section-specific presentation belongs under
|
|
209
|
+
Section-specific presentation belongs under
|
|
210
|
+
`sections.<section-id>.presentation`:
|
|
210
211
|
|
|
211
212
|
```yaml
|
|
212
213
|
sections:
|
|
213
|
-
|
|
214
|
+
intro:
|
|
214
215
|
presentation:
|
|
215
216
|
backgroundColor: "#161616"
|
|
216
217
|
textColor: "#ffffff"
|
package/docs/typography.md
CHANGED
|
@@ -132,10 +132,10 @@ typography:
|
|
|
132
132
|
```
|
|
133
133
|
|
|
134
134
|
A page-level `presentation.typography.preset` changes the typographic character
|
|
135
|
-
for that page. A section-level
|
|
136
|
-
changes the typographic
|
|
137
|
-
|
|
138
|
-
set.
|
|
135
|
+
for that page. A section-level
|
|
136
|
+
`sections.<section-id>.presentation.typography.preset` changes the typographic
|
|
137
|
+
character for that section. `rhythm` is inherited separately, so changing
|
|
138
|
+
preset does not change spacing unless `rhythm` is also set.
|
|
139
139
|
|
|
140
140
|
If a section sets `typography.rhythm`, that section changes text-near spacing.
|
|
141
141
|
If a section only sets `typography.overrides`, it keeps the resolved page
|
|
@@ -145,7 +145,7 @@ Example section override:
|
|
|
145
145
|
|
|
146
146
|
```yaml
|
|
147
147
|
sections:
|
|
148
|
-
|
|
148
|
+
intro:
|
|
149
149
|
presentation:
|
|
150
150
|
typography:
|
|
151
151
|
preset: statement
|
|
@@ -4,7 +4,7 @@ description: A small norna example with free dog images.
|
|
|
4
4
|
navigation:
|
|
5
5
|
label: Dog site!
|
|
6
6
|
sections:
|
|
7
|
-
|
|
7
|
+
black-dogs:
|
|
8
8
|
presentation:
|
|
9
9
|
typography:
|
|
10
10
|
preset: statement
|
|
@@ -12,16 +12,7 @@ sections:
|
|
|
12
12
|
headings:
|
|
13
13
|
h2:
|
|
14
14
|
size: xlarge
|
|
15
|
-
|
|
16
|
-
- image: photo-of-a-black-dog.jpg
|
|
17
|
-
alt: "A black dog sitting outdoors and looking at the camera."
|
|
18
|
-
caption:
|
|
19
|
-
"Photo of a dog. ContaDeletada2906, CC0 1.0, via Wikimedia Commons."
|
|
20
|
-
- image: black-puppy-meadow.png
|
|
21
|
-
alt:
|
|
22
|
-
"A black puppy standing in a grassy meadow and looking at the camera."
|
|
23
|
-
caption: "AI-generated image."
|
|
24
|
-
- id: summer-dogs
|
|
15
|
+
summer-dogs:
|
|
25
16
|
visible:
|
|
26
17
|
from: "2026-08-01"
|
|
27
18
|
until: "2026-09-01"
|
|
@@ -29,21 +20,11 @@ sections:
|
|
|
29
20
|
backgroundColor: "#181818"
|
|
30
21
|
typography:
|
|
31
22
|
preset: compact-gallery
|
|
32
|
-
|
|
33
|
-
- id: brown-dogs
|
|
23
|
+
brown-dogs:
|
|
34
24
|
presentation:
|
|
35
25
|
typography:
|
|
36
26
|
preset: text-forward
|
|
37
|
-
|
|
38
|
-
- image: brown-dog.jpg
|
|
39
|
-
alt: "A brown dog looking directly at the camera."
|
|
40
|
-
caption: "DogBrown. Frank-3, CC0 1.0, via Wikimedia Commons."
|
|
41
|
-
- image: dog-accompanies-master.jpg
|
|
42
|
-
alt: "A man walks outdoors with a dog at his side."
|
|
43
|
-
caption:
|
|
44
|
-
"Dog accompanies his master. Steve Hillebrand, U.S. Fish and Wildlife
|
|
45
|
-
Service, public domain."
|
|
46
|
-
- id: golden-dogs
|
|
27
|
+
golden-dogs:
|
|
47
28
|
presentation:
|
|
48
29
|
typography:
|
|
49
30
|
overrides:
|
|
@@ -55,33 +36,12 @@ sections:
|
|
|
55
36
|
body:
|
|
56
37
|
lineHeight: 1.58
|
|
57
38
|
paragraphSpacing: 1em
|
|
58
|
-
|
|
59
|
-
- image: golden-retriever.jpg
|
|
60
|
-
alt: "A golden retriever standing outdoors."
|
|
61
|
-
caption: "Golden Retriever. Ribo, public domain, via Wikimedia Commons."
|
|
62
|
-
- image: toller-puppy.jpg
|
|
63
|
-
alt:
|
|
64
|
-
"A young Nova Scotia Duck Tolling Retriever puppy sitting on grass."
|
|
65
|
-
caption:
|
|
66
|
-
"Nova Scotia Duck Tolling Retriever puppy. RM, public domain, via
|
|
67
|
-
Wikimedia Commons."
|
|
68
|
-
- id: white-dogs
|
|
39
|
+
white-dogs:
|
|
69
40
|
presentation:
|
|
70
41
|
typography:
|
|
71
42
|
overrides:
|
|
72
43
|
caption:
|
|
73
44
|
spacingBefore: 0.35em
|
|
74
|
-
gallery:
|
|
75
|
-
- carousel:
|
|
76
|
-
- image: white-cute-dog.jpg
|
|
77
|
-
alt: "A white dog looking toward the camera."
|
|
78
|
-
caption:
|
|
79
|
-
"White cute dog. Neal Ziring, public domain, via Wikimedia
|
|
80
|
-
Commons."
|
|
81
|
-
- image: white-puppy-garden.png
|
|
82
|
-
alt: "A fluffy white puppy standing on grass in a garden."
|
|
83
|
-
caption: "AI-generated image."
|
|
84
|
-
- id: sources
|
|
85
45
|
---
|
|
86
46
|
|
|
87
47
|
## Black Dogs {#black-dogs}
|
|
@@ -104,6 +64,15 @@ This `####` heading should follow `typography.headings.h4`.
|
|
|
104
64
|
Curabitur blandit tempus porttitor. Donec id elit non mi porta gravida at eget
|
|
105
65
|
metus. Praesent commodo cursus magna, vel scelerisque nisl consectetur et.
|
|
106
66
|
|
|
67
|
+
```norna-image-stack
|
|
68
|
+
- image: photo-of-a-black-dog.jpg
|
|
69
|
+
alt: A black dog sitting outdoors and looking at the camera.
|
|
70
|
+
caption: Photo of a dog. ContaDeletada2906, CC0 1.0, via Wikimedia Commons.
|
|
71
|
+
- image: black-puppy-meadow.png
|
|
72
|
+
alt: A black puppy standing in a grassy meadow and looking at the camera.
|
|
73
|
+
caption: AI-generated image.
|
|
74
|
+
```
|
|
75
|
+
|
|
107
76
|
## Summer Dogs {#summer-dogs}
|
|
108
77
|
|
|
109
78
|
This temporary section is visible during August 2026. It is here to demonstrate
|
|
@@ -126,6 +95,15 @@ Maecenas sed diam eget risus varius blandit sit amet non magna. Morbi leo risus,
|
|
|
126
95
|
porta ac consectetur ac, vestibulum at eros. Sed posuere consectetur est at
|
|
127
96
|
lobortis.
|
|
128
97
|
|
|
98
|
+
```norna-image-stack
|
|
99
|
+
- image: brown-dog.jpg
|
|
100
|
+
alt: A brown dog looking directly at the camera.
|
|
101
|
+
caption: DogBrown. Frank-3, CC0 1.0, via Wikimedia Commons.
|
|
102
|
+
- image: dog-accompanies-master.jpg
|
|
103
|
+
alt: A man walks outdoors with a dog at his side.
|
|
104
|
+
caption: Dog accompanies his master. Steve Hillebrand, U.S. Fish and Wildlife Service, public domain.
|
|
105
|
+
```
|
|
106
|
+
|
|
129
107
|
## Golden Dogs {#golden-dogs}
|
|
130
108
|
|
|
131
109
|
Golden-coated retrievers add a third image section and more scrolling depth.
|
|
@@ -141,6 +119,15 @@ Nulla vitae elit libero, a pharetra augue. Integer posuere erat a ante venenatis
|
|
|
141
119
|
dapibus posuere velit aliquet. Aenean eu leo quam. Pellentesque ornare sem
|
|
142
120
|
lacinia quam venenatis vestibulum.
|
|
143
121
|
|
|
122
|
+
```norna-image-stack
|
|
123
|
+
- image: golden-retriever.jpg
|
|
124
|
+
alt: A golden retriever standing outdoors.
|
|
125
|
+
caption: Golden Retriever. Ribo, public domain, via Wikimedia Commons.
|
|
126
|
+
- image: toller-puppy.jpg
|
|
127
|
+
alt: A young Nova Scotia Duck Tolling Retriever puppy sitting on grass.
|
|
128
|
+
caption: Nova Scotia Duck Tolling Retriever puppy. RM, public domain, via Wikimedia Commons.
|
|
129
|
+
```
|
|
130
|
+
|
|
144
131
|
## White Dogs {#white-dogs}
|
|
145
132
|
|
|
146
133
|
A white dog completes the colour-based image sequence.
|
|
@@ -152,6 +139,15 @@ Praesent commodo cursus magna, vel scelerisque nisl consectetur et. Lorem ipsum
|
|
|
152
139
|
dolor sit amet, consectetur adipiscing elit. Donec sed odio dui. Vestibulum id
|
|
153
140
|
ligula porta felis euismod semper.
|
|
154
141
|
|
|
142
|
+
```norna-image-stack
|
|
143
|
+
- image: white-cute-dog.jpg
|
|
144
|
+
alt: A white dog looking toward the camera.
|
|
145
|
+
caption: White cute dog. Neal Ziring, public domain, via Wikimedia Commons.
|
|
146
|
+
- image: white-puppy-garden.png
|
|
147
|
+
alt: A fluffy white puppy standing on grass in a garden.
|
|
148
|
+
caption: AI-generated image.
|
|
149
|
+
```
|
|
150
|
+
|
|
155
151
|
## Sources {#sources}
|
|
156
152
|
|
|
157
153
|
Most images are sourced from Wikimedia Commons pages that list CC0 or
|
|
@@ -4,15 +4,13 @@ description: A small route for testing multi-page norna navigation.
|
|
|
4
4
|
navigation:
|
|
5
5
|
label: Dog care
|
|
6
6
|
sections:
|
|
7
|
-
|
|
7
|
+
daily-rhythm:
|
|
8
8
|
presentation:
|
|
9
9
|
typography:
|
|
10
10
|
overrides:
|
|
11
11
|
headings:
|
|
12
12
|
h2:
|
|
13
13
|
size: large
|
|
14
|
-
- id: calm-training
|
|
15
|
-
- id: media-notes
|
|
16
14
|
---
|
|
17
15
|
|
|
18
16
|
## Daily rhythm {#daily-rhythm}
|